[VOL-5506] Enable grpc stats
Change-Id: I78fe2235a2df26855053aa91da6f0b2c4fccd5f0
Signed-off-by: Abhay Kumar <abhay.kumar@radisys.com>
diff --git a/VERSION b/VERSION
index 8ac28bf..c78c496 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-4.6.1
+4.6.2
diff --git a/cmd/openolt-adapter/main.go b/cmd/openolt-adapter/main.go
index af8b52b..4b56d02 100644
--- a/cmd/openolt-adapter/main.go
+++ b/cmd/openolt-adapter/main.go
@@ -21,12 +21,14 @@
"context"
"errors"
"fmt"
+ "net/http"
"os"
"os/signal"
"syscall"
"time"
grpc_retry "github.com/grpc-ecosystem/go-grpc-middleware/retry"
+ "github.com/prometheus/client_golang/prometheus/promhttp"
codes "google.golang.org/grpc/codes"
conf "github.com/opencord/voltha-lib-go/v7/pkg/config"
@@ -538,6 +540,24 @@
defer cancel()
ad := newAdapter(cf)
+ http.Handle("/metrics", promhttp.Handler())
+ go func() {
+ logger.Infof(ctx, "Metrics available at %s/metrics", ad.config.PrometheusAddress)
+ // Create HTTP server with explicit timeouts to prevent slowloris attacks and resource exhaustion.
+ // Using http.ListenAndServe() directly doesn't allow setting timeouts, which is a security risk.
+ // The server uses http.DefaultServeMux (nil handler) which includes the /metrics endpoint registered above.
+ metricsServer := &http.Server{
+ Addr: ad.config.PrometheusAddress,
+ Handler: nil,
+ ReadHeaderTimeout: 10 * time.Second,
+ ReadTimeout: 30 * time.Second,
+ WriteTimeout: 30 * time.Second,
+ IdleTimeout: 120 * time.Second,
+ }
+ if err := metricsServer.ListenAndServe(); err != nil {
+ logger.Errorw(ctx, "failed to start metrics HTTP server: ", log.Fields{"error": err})
+ }
+ }()
p := &probe.Probe{}
go p.ListenAndServe(ctx, ad.config.ProbeAddress)
diff --git a/go.mod b/go.mod
index 334c2ad..aae02e1 100644
--- a/go.mod
+++ b/go.mod
@@ -7,8 +7,10 @@
github.com/gogo/protobuf v1.3.2
github.com/golang/protobuf v1.5.4
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
+ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/opencord/voltha-lib-go/v7 v7.7.1
github.com/opencord/voltha-protos/v5 v5.6.6
+ github.com/prometheus/client_golang v1.23.2
github.com/stretchr/testify v1.11.1
go.etcd.io/etcd/tests/v3 v3.6.5
google.golang.org/grpc v1.76.0
@@ -46,7 +48,6 @@
github.com/gorilla/websocket v1.4.2 // indirect
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect
- github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect
github.com/hashicorp/go-uuid v1.0.3 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
@@ -68,7 +69,6 @@
github.com/pierrec/lz4/v4 v4.1.22 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
- github.com/prometheus/client_golang v1.23.2 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.66.1 // indirect
github.com/prometheus/procfs v0.16.1 // indirect
diff --git a/internal/pkg/config/config.go b/internal/pkg/config/config.go
index ba0e564..d06607e 100644
--- a/internal/pkg/config/config.go
+++ b/internal/pkg/config/config.go
@@ -39,6 +39,7 @@
defaultEventtopic = "voltha.events"
defaultOnunumber = 1
defaultProbeAddress = ":8080"
+ defaultPrometheusPort = ":8081"
defaultLiveProbeInterval = 60 * time.Second
defaultNotLiveProbeInterval = 5 * time.Second // Probe more frequently when not alive
// defaultHeartbeatCheckInterval is the time in seconds the adapter will keep checking the hardware for heartbeat.
@@ -78,6 +79,7 @@
EventTopic string
LogLevel string
ProbeAddress string
+ PrometheusAddress string
GrpcAddress string
CoreEndpoint string
TraceAgentAddress string
@@ -123,6 +125,7 @@
Banner: defaultBanner,
DisplayVersionOnly: defaultDisplayVersionOnly,
ProbeAddress: defaultProbeAddress,
+ PrometheusAddress: defaultPrometheusPort,
LiveProbeInterval: defaultLiveProbeInterval,
NotLiveProbeInterval: defaultNotLiveProbeInterval,
HeartbeatCheckInterval: defaultHeartbeatCheckInterval,
@@ -201,6 +204,11 @@
defaultProbeAddress,
"The address on which to listen to answer liveness and readiness probe queries over HTTP.")
+ flag.StringVar(&(so.PrometheusAddress),
+ "prometheus_address",
+ defaultPrometheusPort,
+ "Used for exposing the metrics to prometheus.")
+
flag.DurationVar(&(so.LiveProbeInterval),
"live_probe_interval",
defaultLiveProbeInterval,
diff --git a/internal/pkg/core/device_handler.go b/internal/pkg/core/device_handler.go
index a72c011..c85be74 100755
--- a/internal/pkg/core/device_handler.go
+++ b/internal/pkg/core/device_handler.go
@@ -39,6 +39,7 @@
"github.com/gogo/protobuf/proto"
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
grpc_opentracing "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
+ grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
"github.com/opencord/voltha-lib-go/v7/pkg/config"
"github.com/opencord/voltha-lib-go/v7/pkg/events/eventif"
flow_utils "github.com/opencord/voltha-lib-go/v7/pkg/flows"
@@ -1209,15 +1210,18 @@
}
logger.Debugw(ctx, "Dailing grpc", log.Fields{"device-id": dh.device.Id})
+ grpc_prometheus.EnableClientHandlingTimeHistogram()
// Use Interceptors to automatically inject and publish Open Tracing Spans by this GRPC client
dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
grpc.WithInsecure(),
grpc.WithBlock(),
grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
+ grpc_prometheus.StreamClientInterceptor,
)),
grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
+ grpc_prometheus.UnaryClientInterceptor,
)))
if err != nil {