From decc1c1e38d76867f94da69d9b61448dc4120e4f Mon Sep 17 00:00:00 2001 From: Weiming Xu Date: Thu, 21 May 2026 11:20:42 -0700 Subject: [PATCH] Add GNMI audit logging for Get() and Set() --- gnmi_server/server.go | 48 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/gnmi_server/server.go b/gnmi_server/server.go index 2dd282591..e043cc374 100644 --- a/gnmi_server/server.go +++ b/gnmi_server/server.go @@ -931,7 +931,28 @@ func IsNativeOrigin(origin string) bool { } // Get implements the Get RPC in gNMI spec. -func (s *Server) Get(ctx context.Context, req *gnmipb.GetRequest) (*gnmipb.GetResponse, error) { +func (s *Server) Get(ctx context.Context, req *gnmipb.GetRequest) (resp *gnmipb.GetResponse, err error) { + // GNMI-AUDIT logging + start := time.Now() + user := extractUser(ctx) + peer := extractPeer(ctx) + + log.Infof("[GNMI-AUDIT] GetRequest user=%s peer=%s prefix=%v paths=%v type=%v", + user, peer, req.GetPrefix(), req.GetPath(), req.GetType()) + + // defer logs automatically when function returns + defer func() { + duration := time.Since(start) + + if err != nil { + log.Errorf("[GNMI-AUDIT] GetResponse user=%s peer=%s status=FAIL err=%v duration=%v", + user, peer, err, duration) + } else { + log.Infof("[GNMI-AUDIT] GetResponse user=%s peer=%s status=OK duration=%v", + user, peer, duration) + } + }() + common_utils.IncCounter(common_utils.GNMI_GET) if req.GetType() != gnmipb.GetRequest_ALL { @@ -1072,8 +1093,19 @@ func SaveOnSetEnabled() error { func saveOnSetDisabled() error { return nil } func (s *Server) Set(ctx context.Context, req *gnmipb.SetRequest) (*gnmipb.SetResponse, error) { + // GNMI-AUDIT logging + start := time.Now() + user := extractUser(ctx) // from auth metadata + peer := extractPeer(ctx) // client address + + log.Infof("[GNMI-AUDIT] SetRequest user=%s peer=%s prefix=%v updates=%d replaces=%d deletes=%d", + user, peer, req.GetPrefix(), len(req.GetUpdate()), len(req.GetReplace()), len(req.GetDelete())) + e := s.ReqFromMaster(req, &s.masterEID) if e != nil { + duration := time.Since(start) + log.Errorf("[GNMI-AUDIT] SetResponse user=%s peer=%s status=FAIL err=%v duration=%v", + user, peer, e, duration) return nil, e } @@ -1213,11 +1245,21 @@ func (s *Server) Set(ctx context.Context, req *gnmipb.SetRequest) (*gnmipb.SetRe s.SaveStartupConfig() } - return &gnmipb.SetResponse{ + resp := &gnmipb.SetResponse{ Prefix: req.GetPrefix(), Response: results, - }, err + } + + duration := time.Since(start) + if err != nil { + log.Errorf("[GNMI-AUDIT] SetResponse user=%s peer=%s status=FAIL err=%v duration=%v", + user, peer, err, duration) + } else { + log.Infof("[GNMI-AUDIT] SetResponse user=%s peer=%s status=OK duration=%v", + user, peer, duration) + } + return resp, err } func (s *Server) Capabilities(ctx context.Context, req *gnmipb.CapabilityRequest) (*gnmipb.CapabilityResponse, error) {