From 880942352bed7576db35818f2a3426bb6c300620 Mon Sep 17 00:00:00 2001 From: ionutboangiu Date: Tue, 7 Oct 2025 20:06:24 +0300 Subject: [PATCH] use string status values in diameter conn events --- agents/diamagent.go | 22 ++++++---------------- engine/statmetrics.go | 37 ++++++++++++++++++++++++++++++------- utils/consts.go | 9 ++++++--- 3 files changed, 42 insertions(+), 26 deletions(-) diff --git a/agents/diamagent.go b/agents/diamagent.go index fafdcae92..5476f8899 100644 --- a/agents/diamagent.go +++ b/agents/diamagent.go @@ -452,18 +452,8 @@ func (da *DiameterAgent) handleRAA(c diam.Conn, m *diam.Message) { ch <- m } -const ( - // Connection status values for ConnectionStatus event field: - // -1 : connection closed/down - // 0 : duplicate connection (no metric change) - // 1 : new connection established/up - diamConnStatusDown = -1 - diamConnStatusDuplicate = 0 - diamConnStatusUp = 1 -) - // sendConnStatusReport reports connection status changes to StatS and ThresholdS. -func (da *DiameterAgent) sendConnStatusReport(metadata *smpeer.Metadata, status int, localAddr, remoteAddr net.Addr) { +func (da *DiameterAgent) sendConnStatusReport(metadata *smpeer.Metadata, status string, localAddr, remoteAddr net.Addr) { sqIDs := da.cgrCfg.DiameterAgentCfg().ConnStatusStatQueueIDs thIDs := da.cgrCfg.DiameterAgentCfg().ConnStatusThresholdIDs if len(sqIDs) == 0 && len(thIDs) == 0 { @@ -522,11 +512,11 @@ func (da *DiameterAgent) handleConns(peers <-chan diam.Conn) { } key := string(meta.OriginHost + utils.ConcatenatedKeySep + meta.OriginRealm) da.peersLck.Lock() - diamConnStatus := diamConnStatusUp + connStatus := utils.ConnStatusUp if _, exists := da.peers[key]; exists { - // Connection already exists for this peer. Set status to 0 (duplicate) + // Connection already exists for this peer. Set status to DUPLICATE // to prevent incrementing StatS metrics. - diamConnStatus = diamConnStatusDuplicate + connStatus = utils.ConnStatusDuplicate utils.Logger.Warning(fmt.Sprintf( "<%s> a connection from a peer with the same ID (%q) is already registered, overwriting...", @@ -535,7 +525,7 @@ func (da *DiameterAgent) handleConns(peers <-chan diam.Conn) { da.peers[key] = c da.peersLck.Unlock() localAddr, remoteAddr := c.LocalAddr(), c.RemoteAddr() - da.sendConnStatusReport(meta, diamConnStatus, localAddr, remoteAddr) + da.sendConnStatusReport(meta, connStatus, localAddr, remoteAddr) go func() { // Use hybrid approach to detect connection closure. CloseNotify() may not // fire if the serve() goroutine is blocked in Read(), so we also perform @@ -545,7 +535,7 @@ func (da *DiameterAgent) handleConns(peers <-chan diam.Conn) { da.peersLck.Lock() delete(da.peers, key) da.peersLck.Unlock() - da.sendConnStatusReport(meta, diamConnStatusDown, localAddr, remoteAddr) + da.sendConnStatusReport(meta, utils.ConnStatusDown, localAddr, remoteAddr) }() closeChan := c.(diam.CloseNotifier).CloseNotify() diff --git a/engine/statmetrics.go b/engine/statmetrics.go index 9bfdf002e..905edd1c6 100644 --- a/engine/statmetrics.go +++ b/engine/statmetrics.go @@ -1500,17 +1500,40 @@ func (sum *StatSum) GetFloat64Value(roundingDecimal int) (v float64) { return sum.getValue(roundingDecimal) } -func (sum *StatSum) getFieldVal(ev utils.DataProvider) (val float64, err error) { - var ival any - if ival, err = utils.DPDynamicInterface(sum.FieldName, ev); err != nil { +// connStatusToFloat converts connection status strings to numeric values for *sum metrics. +// This allows sending status as strings in events while computing numeric sums: +// - "UP" returns 1 (connection established) +// - "DOWN" returns -1 (connection closed) +// - "DUPLICATE" returns 0 (connection already exists, no change) +func connStatusToFloat(v string) (float64, bool) { + switch v { + case utils.ConnStatusUp: + return 1, true + case utils.ConnStatusDown: + return -1, true + case utils.ConnStatusDuplicate: + return 0, true + } + return 0, false +} + +func (sum *StatSum) getFieldVal(ev utils.DataProvider) (float64, error) { + ival, err := utils.DPDynamicInterface(sum.FieldName, ev) + if err != nil { if err == utils.ErrNotFound { err = utils.ErrPrefix(err, sum.FieldName) } - return - } else if val, err = utils.IfaceAsFloat64(ival); err != nil { - return + return 0, err } - return + + // Check for connection status strings before numeric conversion. + if str, ok := ival.(string); ok { + if v, isConnStatus := connStatusToFloat(str); isConnStatus { + return v, nil + } + } + + return utils.IfaceAsFloat64(ival) } func (sum *StatSum) AddEvent(evID string, ev utils.DataProvider) (err error) { diff --git a/utils/consts.go b/utils/consts.go index 8cfb86288..5ee66d543 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -630,9 +630,12 @@ const ( EventConnectionStatusReport = "ConnectionStatusReport" // Connection status event fields. - ConnLocalAddr = "LocalAddr" - ConnRemoteAddr = "RemoteAddr" - ConnStatus = "ConnectionStatus" // -1=down, 0=duplicate, 1=up + ConnLocalAddr = "LocalAddr" + ConnRemoteAddr = "RemoteAddr" + ConnStatus = "ConnectionStatus" // sum metric: UP=1, DOWN=-1, DUPLICATE=0 + ConnStatusUp = "UP" + ConnStatusDown = "DOWN" + ConnStatusDuplicate = "DUPLICATE" // ReplyState error constants ErrReplyStateAuthorize = "ERR_AUTHORIZE"