diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 48f3b27..abbf562 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -53,6 +53,12 @@ jobs: curl --fail http://127.0.0.1:9091/api/v1/query?query=dns_query_result_code | grep dns_query_result_code curl --fail http://127.0.0.1:9091/api/v1/query?query=ethtool_duplex | grep ethtool_duplex curl --fail http://127.0.0.1:9091/api/v1/query?query=kernel_boot_time_total | grep kernel_boot_time_total + if docker-compose logs | grep -q "source=go-app cpu_load"; then + echo "Success: 'gnmi' found in docker-compose logs." + else + echo "Failure: 'gnmi' not found in docker-compose logs." + exit 1 + fi - name: Logs if: always() diff --git a/config/telegraf.conf b/config/telegraf.conf index d0d5b77..129d8a0 100644 --- a/config/telegraf.conf +++ b/config/telegraf.conf @@ -49,6 +49,19 @@ servers = ["8.8.8.8"] include_fields = ["all_ips"] + +[[inputs.gnmi]] + addresses = ["go-app:57400"] + encoding = "json" + redial = "10s" + target = "localhost" + + [[inputs.gnmi.subscription]] + name = "cpu" + path = "/system/cpu-load" + subscription_mode = "sample" + sample_interval = "1s" + [[outputs.file]] files = ["stdout"] data_format = "influx" diff --git a/config/testdata/gnmi-app/main.go b/config/testdata/gnmi-app/main.go new file mode 100644 index 0000000..7a9b28f --- /dev/null +++ b/config/testdata/gnmi-app/main.go @@ -0,0 +1,113 @@ +package main + +import ( + "io" + "log" + "net" + "os/exec" + "strconv" + "strings" + "time" + + "github.com/openconfig/gnmi/proto/gnmi" + "google.golang.org/grpc" +) + +type server struct { + gnmi.UnimplementedGNMIServer +} + +// Helper function to get CPU load +func getCPULoad() (string, error) { + out, err := exec.Command("uptime").Output() + if err != nil { + return "", err + } + parts := strings.Fields(string(out)) + return parts[len(parts)-3], nil // Return the 1-minute load average +} + +// Helper function to get Memory usage +func getMemUsage() (int64, error) { + out, err := exec.Command("grep", "MemAvailable", "/proc/meminfo").Output() + if err != nil { + return 0, err + } + parts := strings.Fields(string(out)) + return strconv.ParseInt(parts[1], 10, 64) +} + +// Implement the Subscribe method for Telegraf +func (s *server) Subscribe(stream gnmi.GNMI_SubscribeServer) error { + log.Println("Received Subscribe request") + + for { + // Receive request + req, err := stream.Recv() + if err == io.EOF { + return nil + } + if err != nil { + return err + } + + log.Println("Subscription request:", req) + + // Fetch dynamic data + cpuLoad, err := getCPULoad() + if err != nil { + return err + } + memAvailable, err := getMemUsage() + if err != nil { + return err + } + + // Send a mock telemetry update response + update := &gnmi.SubscribeResponse{ + Response: &gnmi.SubscribeResponse_Update{ + Update: &gnmi.Notification{ + Prefix: &gnmi.Path{ + Elem: []*gnmi.PathElem{ + {Name: "system"}, + }, + }, + Update: []*gnmi.Update{ + { + Path: &gnmi.Path{Elem: []*gnmi.PathElem{{Name: "cpu-load"}}}, + Val: &gnmi.TypedValue{Value: &gnmi.TypedValue_StringVal{StringVal: cpuLoad}}, + }, + { + Path: &gnmi.Path{Elem: []*gnmi.PathElem{{Name: "mem-available"}}}, + Val: &gnmi.TypedValue{Value: &gnmi.TypedValue_IntVal{IntVal: memAvailable}}, + }, + }, + Timestamp: time.Now().UnixNano(), + }, + }, + } + + if err := stream.Send(update); err != nil { + log.Printf("Error sending update: %v", err) + return err + } + + // Add a delay of 5 seconds between updates + time.Sleep(5 * time.Second) + } +} + +func main() { + lis, err := net.Listen("tcp", ":57400") + if err != nil { + log.Fatalf("Failed to listen on port 57400: %v", err) + } + + grpcServer := grpc.NewServer() + gnmi.RegisterGNMIServer(grpcServer, &server{}) + + log.Println("gNMI server listening on port 57400") + if err := grpcServer.Serve(lis); err != nil { + log.Fatalf("Failed to serve gNMI: %v", err) + } +} diff --git a/docker-compose.yml b/docker-compose.yml index 87140f9..294aede 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -38,6 +38,22 @@ services: start_period: 20s timeout: 10s + go-app: + image: golang:1.20-alpine + working_dir: /app + volumes: + - ./config/testdata/gnmi-app:/app + ports: + - "57400:57400" + command: sh -c "go run main.go" + networks: + - opi + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:57400"] + interval: 6s + timeout: 10s + retries: 5 + telegraf: image: docker.io/library/telegraf:1.29 volumes: @@ -49,6 +65,8 @@ services: depends_on: - spdk - influxdb + - go-app + command: sh -c "sleep 20 && telegraf" networks: - opi cap_add: