From df54b4c961e4dbcfb728405a408f2b644370c6e6 Mon Sep 17 00:00:00 2001 From: Evan Baker Date: Fri, 31 Jan 2025 22:41:17 +0000 Subject: [PATCH] feat: add apiserver FQDN to CNS log metadata in AKS Signed-off-by: Evan Baker --- cns/logger/cnslogger.go | 117 ++++++++++++++++------------------------ cns/logger/constants.go | 5 +- cns/logger/log.go | 2 +- cns/metric/heartbeat.go | 2 - cns/service/main.go | 2 + 5 files changed, 53 insertions(+), 75 deletions(-) diff --git a/cns/logger/cnslogger.go b/cns/logger/cnslogger.go index 86a1f67d98..a898859493 100644 --- a/cns/logger/cnslogger.go +++ b/cns/logger/cnslogger.go @@ -2,6 +2,7 @@ package logger import ( "fmt" + "maps" "os" "sync" @@ -13,21 +14,23 @@ import ( "go.uber.org/zap/zapcore" ) -type CNSLogger struct { - logger *log.Logger - th ai.TelemetryHandle - DisableTraceLogging bool - DisableMetricLogging bool - DisableEventLogging bool +// wait time for closing AI telemetry session. +const waitTimeInSecs = 10 +type CNSLogger struct { + logger *log.Logger zapLogger *zap.Logger + th ai.TelemetryHandle + + disableTraceLogging bool + disableMetricLogging bool + disableEventLogging bool - m sync.RWMutex - Orchestrator string - NodeID string + m sync.RWMutex + metadata map[string]string } -func NewCNSLogger(fileName string, logLevel, logTarget int, logDir string) (*CNSLogger, error) { +func New(fileName string, logLevel, logTarget int, logDir string) (*CNSLogger, error) { l, err := log.NewLoggerE(fileName, logLevel, logTarget, logDir) if err != nil { return nil, errors.Wrap(err, "could not get new logger") @@ -46,6 +49,7 @@ func NewCNSLogger(fileName string, logLevel, logTarget int, logDir string) (*CNS return &CNSLogger{ logger: l, zapLogger: zapLogger, + metadata: map[string]string{}, }, nil } @@ -59,17 +63,13 @@ func (c *CNSLogger) InitAIWithIKey(aiConfig ai.AIConfig, instrumentationKey stri c.logger.Errorf("Error initializing AI Telemetry:%v", err) return } - c.th = th c.logger.Printf("AI Telemetry Handle created") - c.DisableMetricLogging = disableMetricLogging - c.DisableTraceLogging = disableTraceLogging - c.DisableEventLogging = disableEventLogging + c.disableMetricLogging = disableMetricLogging + c.disableTraceLogging = disableTraceLogging + c.disableEventLogging = disableEventLogging } -// wait time for closing AI telemetry session. -const waitTimeInSecs = 10 - func (c *CNSLogger) Close() { c.logger.Close() if c.th != nil { @@ -80,19 +80,23 @@ func (c *CNSLogger) Close() { func (c *CNSLogger) SetContextDetails(orchestrator, nodeID string) { c.logger.Logf("SetContext details called with: %v orchestrator nodeID %v", orchestrator, nodeID) c.m.Lock() - c.Orchestrator = orchestrator - c.NodeID = nodeID + c.metadata[orchestratorTypeKey] = orchestrator + c.metadata[nodeIDKey] = nodeID + c.m.Unlock() +} + +func (c *CNSLogger) SetAPIServer(apiserver string) { + c.m.Lock() + c.metadata[apiServerKey] = apiserver c.m.Unlock() } func (c *CNSLogger) Printf(format string, args ...any) { c.logger.Logf(format, args...) c.zapLogger.Info(fmt.Sprintf(format, args...)) - - if c.th == nil || c.DisableTraceLogging { + if c.th == nil || c.disableTraceLogging { return } - msg := fmt.Sprintf(format, args...) c.sendTraceInternal(msg, ai.InfoLevel) } @@ -100,11 +104,9 @@ func (c *CNSLogger) Printf(format string, args ...any) { func (c *CNSLogger) Debugf(format string, args ...any) { c.logger.Debugf(format, args...) c.zapLogger.Debug(fmt.Sprintf(format, args...)) - - if c.th == nil || c.DisableTraceLogging { + if c.th == nil || c.disableTraceLogging { return } - msg := fmt.Sprintf(format, args...) c.sendTraceInternal(msg, ai.DebugLevel) } @@ -112,11 +114,9 @@ func (c *CNSLogger) Debugf(format string, args ...any) { func (c *CNSLogger) Warnf(format string, args ...any) { c.logger.Warnf(format, args...) c.zapLogger.Warn(fmt.Sprintf(format, args...)) - - if c.th == nil || c.DisableTraceLogging { + if c.th == nil || c.disableTraceLogging { return } - msg := fmt.Sprintf(format, args...) c.sendTraceInternal(msg, ai.WarnLevel) } @@ -124,22 +124,18 @@ func (c *CNSLogger) Warnf(format string, args ...any) { func (c *CNSLogger) Errorf(format string, args ...any) { c.logger.Errorf(format, args...) c.zapLogger.Error(fmt.Sprintf(format, args...)) - - if c.th == nil || c.DisableTraceLogging { + if c.th == nil || c.disableTraceLogging { return } - msg := fmt.Sprintf(format, args...) c.sendTraceInternal(msg, ai.ErrorLevel) } func (c *CNSLogger) Request(tag string, request any, err error) { c.logger.Request(tag, request, err) - - if c.th == nil || c.DisableTraceLogging { + if c.th == nil || c.disableTraceLogging { return } - var msg string lvl := ai.InfoLevel if err == nil { @@ -148,17 +144,14 @@ func (c *CNSLogger) Request(tag string, request any, err error) { msg = fmt.Sprintf("[%s] Failed to decode %T %+v %s.", tag, request, request, err.Error()) lvl = ai.ErrorLevel } - c.sendTraceInternal(msg, lvl) } func (c *CNSLogger) Response(tag string, response any, returnCode types.ResponseCode, err error) { c.logger.Response(tag, response, int(returnCode), returnCode.String(), err) - - if c.th == nil || c.DisableTraceLogging { + if c.th == nil || c.disableTraceLogging { return } - var msg string lvl := ai.InfoLevel switch { @@ -170,17 +163,14 @@ func (c *CNSLogger) Response(tag string, response any, returnCode types.Response default: msg = fmt.Sprintf("[%s] Code:%s, %+v.", tag, returnCode.String(), response) } - c.sendTraceInternal(msg, lvl) } func (c *CNSLogger) ResponseEx(tag string, request, response any, returnCode types.ResponseCode, err error) { c.logger.ResponseEx(tag, request, response, int(returnCode), returnCode.String(), err) - - if c.th == nil || c.DisableTraceLogging { + if c.th == nil || c.disableTraceLogging { return } - var msg string lvl := ai.InfoLevel switch { @@ -192,51 +182,38 @@ func (c *CNSLogger) ResponseEx(tag string, request, response any, returnCode typ default: msg = fmt.Sprintf("[%s] Code:%s, %+v, %+v.", tag, returnCode.String(), request, response) } - c.sendTraceInternal(msg, lvl) } -func (c *CNSLogger) getOrchestratorAndNodeID() (orch, nodeID string) { - c.m.RLock() - orch, nodeID = c.Orchestrator, c.NodeID - c.m.RUnlock() - return -} - func (c *CNSLogger) sendTraceInternal(msg string, lvl ai.Level) { - orch, nodeID := c.getOrchestratorAndNodeID() - report := ai.Report{ - Message: msg, - Level: lvl, - Context: nodeID, - CustomDimensions: map[string]string{ - OrchestratorTypeStr: orch, - NodeIDStr: nodeID, - }, + Message: msg, + Level: lvl, + Context: c.metadata[nodeIDKey], + CustomDimensions: map[string]string{"Level": lvl.String()}, } - + c.m.RLock() + maps.Copy(report.CustomDimensions, c.metadata) + c.m.RUnlock() c.th.TrackLog(report) } func (c *CNSLogger) LogEvent(event ai.Event) { - if c.th == nil || c.DisableEventLogging { + if c.th == nil || c.disableEventLogging { return } - - orch, nodeID := c.getOrchestratorAndNodeID() - event.Properties[OrchestratorTypeStr] = orch - event.Properties[NodeIDStr] = nodeID + c.m.RLock() + maps.Copy(event.Properties, c.metadata) + c.m.RUnlock() c.th.TrackEvent(event) } func (c *CNSLogger) SendMetric(metric ai.Metric) { - if c.th == nil || c.DisableMetricLogging { + if c.th == nil || c.disableMetricLogging { return } - - orch, nodeID := c.getOrchestratorAndNodeID() - metric.CustomDimensions[OrchestratorTypeStr] = orch - metric.CustomDimensions[NodeIDStr] = nodeID + c.m.RLock() + maps.Copy(metric.CustomDimensions, c.metadata) + c.m.RUnlock() c.th.TrackMetric(metric) } diff --git a/cns/logger/constants.go b/cns/logger/constants.go index ce4c0c80c0..db9f03b304 100644 --- a/cns/logger/constants.go +++ b/cns/logger/constants.go @@ -7,14 +7,15 @@ const ( ConfigSnapshotMetricsStr = "ConfigSnapshot" // Dimensions - OrchestratorTypeStr = "OrchestratorType" - NodeIDStr = "NodeID" + orchestratorTypeKey = "OrchestratorType" + nodeIDKey = "NodeID" HomeAZStr = "HomeAZ" IsAZRSupportedStr = "IsAZRSupported" HomeAZErrorCodeStr = "HomeAZErrorCode" HomeAZErrorMsgStr = "HomeAZErrorMsg" CNSConfigPropertyStr = "CNSConfiguration" CNSConfigMD5CheckSumPropertyStr = "CNSConfigurationMD5Checksum" + apiServerKey = "APIServer" // CNS NC Snspshot properties CnsNCSnapshotEventStr = "CNSNCSnapshot" diff --git a/cns/logger/log.go b/cns/logger/log.go index 1ded6d42f1..3397e132c1 100644 --- a/cns/logger/log.go +++ b/cns/logger/log.go @@ -18,7 +18,7 @@ func Close() { } func InitLogger(fileName string, logLevel, logTarget int, logDir string) { - Log, _ = NewCNSLogger(fileName, logLevel, logTarget, logDir) + Log, _ = New(fileName, logLevel, logTarget, logDir) } func InitAI(aiConfig aitelemetry.AIConfig, disableTraceLogging, disableMetricLogging, disableEventLogging bool) { diff --git a/cns/metric/heartbeat.go b/cns/metric/heartbeat.go index de65e4e5ea..8a20943a17 100644 --- a/cns/metric/heartbeat.go +++ b/cns/metric/heartbeat.go @@ -30,7 +30,6 @@ func SendHeartBeat(ctx context.Context, heartbeatInterval time.Duration, homeAzM Value: 1.0, CustomDimensions: make(map[string]string), } - // add azr metrics when channel mode is direct if channelMode == cns.Direct { getHomeAzResp := homeAzMonitor.GetHomeAz(ctx) @@ -41,7 +40,6 @@ func SendHeartBeat(ctx context.Context, heartbeatInterval time.Duration, homeAzM default: metric.CustomDimensions[logger.HomeAZErrorCodeStr] = getHomeAzResp.Response.ReturnCode.String() metric.CustomDimensions[logger.HomeAZErrorMsgStr] = getHomeAzResp.Response.Message - } } logger.SendMetric(metric) diff --git a/cns/service/main.go b/cns/service/main.go index f8235bba9e..7a6a64dccb 100644 --- a/cns/service/main.go +++ b/cns/service/main.go @@ -828,6 +828,8 @@ func main() { // Initialze state in if CNS is running in CRD mode // State must be initialized before we start HTTPRestService if config.ChannelMode == cns.CRD { + // Add APIServer FQDN to Log metadata + logger.Log.SetAPIServer(os.Getenv("KUBERNETES_SERVICE_HOST")) // Check the CNI statefile mount, and if the file is empty // stub an empty JSON object