go.ligato.io/vpp-agent/v3@v3.5.0/examples/grpc_vpp/stats_poller/main.go (about) 1 // Copyright (c) 2019 Cisco and/or its affiliates. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at: 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package main 16 17 import ( 18 "context" 19 "errors" 20 "fmt" 21 "io" 22 "log" 23 "net" 24 "os" 25 "time" 26 27 "github.com/namsral/flag" 28 "go.ligato.io/cn-infra/v2/agent" 29 "go.ligato.io/cn-infra/v2/infra" 30 "google.golang.org/grpc" 31 32 "go.ligato.io/vpp-agent/v3/proto/ligato/configurator" 33 ) 34 35 var ( 36 address = flag.String("address", "localhost:9111", "address of GRPC server") 37 socketType = flag.String("socket-type", "tcp", "[tcp, tcp4, tcp6, unix, unixpacket]") 38 39 period = flag.Uint("period", 3, "Polling period (in seconds)") 40 polls = flag.Uint("polls", 0, "Number of pollings") 41 ) 42 43 func main() { 44 ep := &ExamplePlugin{} 45 ep.SetName("stats-poller-example") 46 ep.Setup() 47 48 a := agent.NewAgent( 49 agent.AllPlugins(ep), 50 ) 51 if err := a.Run(); err != nil { 52 log.Fatal() 53 } 54 } 55 56 // ExamplePlugin demonstrates the use of grpc to watch on VPP notifications using vpp-agent. 57 type ExamplePlugin struct { 58 infra.PluginDeps 59 60 conn *grpc.ClientConn 61 } 62 63 // Init initializes example plugin. 64 func (p *ExamplePlugin) Init() (err error) { 65 // Set up connection to the server. 66 p.conn, err = grpc.Dial("unix", 67 grpc.WithInsecure(), 68 grpc.WithContextDialer(func(ctx context.Context, addr string) (net.Conn, error) { 69 return net.DialTimeout(*socketType, *address, time.Second*3) 70 }), 71 //grpc.WithContextDialer(dialer(*socketType, *address, time.Second*3)), 72 ) 73 74 if err != nil { 75 return err 76 } 77 78 client := configurator.NewStatsPollerServiceClient(p.conn) 79 80 // Start stats poller. 81 go p.pollStats(client) 82 83 return err 84 } 85 86 // Get is an implementation of client-side statistics streaming. 87 func (p *ExamplePlugin) pollStats(client configurator.StatsPollerServiceClient) { 88 ctx := context.Background() 89 90 req := &configurator.PollStatsRequest{ 91 PeriodSec: uint32(*period), 92 NumPolls: uint32(*polls), 93 } 94 fmt.Printf("Polling stats: %v\n", req) 95 96 stream, err := client.PollStats(ctx, req) 97 if err != nil { 98 p.Log.Fatalln("PollStats failed:", err) 99 } 100 101 var lastSeq uint32 102 for { 103 resp, err := stream.Recv() 104 if errors.Is(err, io.EOF) { 105 p.Log.Infof("Polling has completed.") 106 os.Exit(0) 107 } else if err != nil { 108 p.Log.Fatalln("Recv failed:", err) 109 } 110 111 if resp.PollSeq != lastSeq { 112 fmt.Printf(" --- Poll sequence: %-3v\n", resp.PollSeq) 113 } 114 lastSeq = resp.PollSeq 115 116 vppStats := resp.GetStats().GetVppStats() 117 fmt.Printf("VPP stats: %v\n", vppStats) 118 } 119 } 120 121 // Dialer for unix domain socket 122 func dialer(socket, address string, timeoutVal time.Duration) func(context.Context, string) (net.Conn, error) { 123 return func(ctx context.Context, addr string) (net.Conn, error) { 124 return net.DialTimeout(socket, address, timeoutVal) 125 } 126 }