From 1d3c74bc5370a02cff84fe43ed8451e8c278d7e6 Mon Sep 17 00:00:00 2001 From: Nikolay Sivko Date: Tue, 15 Oct 2024 17:13:57 +0300 Subject: [PATCH] fix .NET app name collisions --- containers/container.go | 17 +++++++++++++++-- containers/dotnet.go | 9 +++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/containers/container.go b/containers/container.go index cb85971..34c4542 100644 --- a/containers/container.go +++ b/containers/container.go @@ -2,6 +2,7 @@ package containers import ( "os" + "sort" "strings" "sync" "time" @@ -19,6 +20,7 @@ import ( "github.com/coroot/logparser" "github.com/prometheus/client_golang/prometheus" "github.com/vishvananda/netns" + "golang.org/x/exp/maps" "inet.af/netaddr" "k8s.io/klog/v2" ) @@ -335,7 +337,14 @@ func (c *Container) Collect(ch chan<- prometheus.Metric) { appTypes := map[string]struct{}{} seenJvms := map[string]bool{} - for pid, process := range c.processes { + seenDotNetApps := map[string]bool{} + pids := maps.Keys(c.processes) + sort.Slice(pids, func(i, j int) bool { + return pids[i] < pids[j] + }) + + for _, pid := range pids { + process := c.processes[pid] cmdline := proc.GetCmdline(pid) if len(cmdline) == 0 { continue @@ -358,7 +367,11 @@ func (c *Container) Collect(ch chan<- prometheus.Metric) { } case process.dotNetMonitor != nil: appTypes["dotnet"] = struct{}{} - process.dotNetMonitor.Collect(ch) + appName := process.dotNetMonitor.AppName() + if !seenDotNetApps[appName] { + seenDotNetApps[appName] = true + process.dotNetMonitor.Collect(ch) + } } } for appType := range appTypes { diff --git a/containers/dotnet.go b/containers/dotnet.go index 872dd0f..759ff29 100644 --- a/containers/dotnet.go +++ b/containers/dotnet.go @@ -53,6 +53,7 @@ func (m *dotNetMetric) units() string { type DotNetMonitor struct { pid uint32 + appName string cancel context.CancelFunc lastUpdate time.Time runtimeVersion string @@ -74,8 +75,8 @@ func NewDotNetMonitor(ctx context.Context, pid uint32, appName string) *DotNetMo constLabels := prometheus.Labels{"application": appName} m := &DotNetMonitor{ - pid: pid, - + pid: pid, + appName: appName, info: newGaugeVec("container_dotnet_info", "Meta information about the Common Language Runtime (CLR)", constLabels, "runtime_version"), memoryAllocatedBytes: newCounter("container_dotnet_memory_allocated_bytes_total", "The number of bytes allocated", constLabels), exceptionCount: newGauge("container_dotnet_exceptions_total", "The number of exceptions that have occurred", constLabels), @@ -91,6 +92,10 @@ func NewDotNetMonitor(ctx context.Context, pid uint32, appName string) *DotNetMo return m } +func (m *DotNetMonitor) AppName() string { + return m.appName +} + func (m *DotNetMonitor) Collect(ch chan<- prometheus.Metric) { if m.lastUpdate.Before(time.Now().Add(-2 * dotNetEventInterval)) { return