in sharedlibraries/metricevents/metricevents.go [104:159]
func AddEvent(ctx context.Context, p Parameters) bool {
mu.Lock()
defer mu.Unlock()
if events == nil {
events = make(map[string]eventData)
}
if logDelayEvents == nil {
logDelayEvents = make(map[string]eventData)
}
key := p.Path + p.Identifier
stateChange := false
if event, exists := events[key]; exists && event.lastValue != p.Value {
stateChange = true
// Some metric paths are sent multiple times - one for each service.
// To avoid logging the same event multiple times, we will group labels
// that share the same path and value and log after a short delay.
logDelayKey := p.Path + p.Value
if logEvent, exists := logDelayEvents[logDelayKey]; exists {
for k, v := range event.labels {
if logEvent.labels[k] != v {
logEvent.labels[k] += ", " + v
}
}
} else {
logDelayEvents[logDelayKey] = event
time.AfterFunc(defaultLogDelay, func() {
// Lock the mutex as this runs in a separate goroutine.
mu.Lock()
defer mu.Unlock()
logEvent := logDelayEvents[logDelayKey]
// Sort and remove duplicate labels.
for k, labels := range logEvent.labels {
labelSlice := strings.Split(labels, ", ")
sort.Strings(labelSlice)
logEvent.labels[k] = strings.Join(slices.Compact(labelSlice), ", ")
}
logLevel, ok := logLevelMap[p.Path][p.Value]
if !ok {
logLevel = zapcore.InfoLevel
}
// NOTE: This log message has specific keys used in querying Cloud Logging.
// Never change these keys since it would have downstream effects.
log.CtxLogger(ctx).Logw(logLevel, p.Message, "metricEvent", true, "metric", p.Path, "previousValue", logEvent.lastValue, "currentValue", p.Value, "previousLabels", p.Labels, "currentLabels", logEvent.labels, "lastUpdated", logEvent.lastUpdated)
delete(logDelayEvents, logDelayKey)
})
}
}
events[key] = eventData{
labels: p.Labels,
lastValue: p.Value,
lastUpdated: time.Now(),
}
return stateChange
}