Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adding gnmi metrics #153

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
13 changes: 13 additions & 0 deletions config/telegraf.conf
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
113 changes: 113 additions & 0 deletions config/testdata/gnmi-app/main.go
Original file line number Diff line number Diff line change
@@ -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)
}
}
18 changes: 18 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -49,6 +65,8 @@ services:
depends_on:
- spdk
- influxdb
- go-app
command: sh -c "sleep 20 && telegraf"
networks:
- opi
cap_add:
Expand Down