cores: add GOMAXPROCS, GC percent and memlimit metrics

- gathered when Debug=true
- removed Lookups (always 0)
This commit is contained in:
ionutboangiu
2025-03-27 17:38:35 +02:00
committed by Dan Christian Bogos
parent 531a752078
commit 020e5c2569
2 changed files with 53 additions and 5 deletions

View File

@@ -19,9 +19,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
package cores
import (
"fmt"
"os"
"runtime"
"runtime/debug"
"runtime/metrics"
"strconv"
"time"
@@ -40,6 +42,9 @@ type StatusMetrics struct {
GCDurationStats GCDurationStats `json:"gc_duration_stats"`
ProcStats ProcStats `json:"proc_stats"`
CapsStats *CapsStats `json:"caps_stats"`
GoMaxProcs uint64 `json:"go_maxprocs"`
GoGCPercent uint64 `json:"go_gc_percent"`
GoMemLimit uint64 `json:"go_mem_limit"`
}
func (sm StatusMetrics) ToMap(debug bool, timezone string) (map[string]any, error) {
@@ -59,6 +64,9 @@ func (sm StatusMetrics) ToMap(debug bool, timezone string) (map[string]any, erro
if sm.CapsStats != nil {
m["caps_stats"] = sm.CapsStats.ToMap()
}
m["go_maxprocs"] = sm.GoMaxProcs
m["go_gc_percent"] = sm.GoGCPercent
m["go_mem_limit"] = sm.GoMemLimit
return m, nil
}
@@ -104,7 +112,6 @@ type GoMemStats struct {
Sys uint64 `json:"sys"`
Mallocs uint64 `json:"mallocs"`
Frees uint64 `json:"frees"`
Lookups uint64 `json:"lookups"`
HeapAlloc uint64 `json:"heap_alloc"`
HeapSys uint64 `json:"heap_sys"`
HeapIdle uint64 `json:"heap_idle"`
@@ -131,7 +138,6 @@ func (ms GoMemStats) ToMap() map[string]any {
m["sys"] = ms.Sys
m["mallocs"] = ms.Mallocs
m["frees"] = ms.Frees
m["lookups"] = ms.Lookups
m["heap_alloc"] = ms.HeapAlloc
m["heap_sys"] = ms.HeapSys
m["heap_idle"] = ms.HeapIdle
@@ -240,7 +246,6 @@ func computeAppMetrics() (StatusMetrics, error) {
GCSys: m.GCSys,
OtherSys: m.OtherSys,
NextGC: m.NextGC,
Lookups: m.Lookups,
}
threads, _ := runtime.ThreadCreateProfile(nil)
@@ -317,6 +322,21 @@ func computeAppMetrics() (StatusMetrics, error) {
return StatusMetrics{}, err
}
metricNames := []string{
"/sched/gomaxprocs:threads",
"/gc/gogc:percent",
"/memory/limit:bytes",
"/gc/gomemlimit:bytes",
}
samples := make([]metrics.Sample, len(metricNames))
for i, name := range metricNames {
samples[i].Name = name
}
metrics.Read(samples)
goMaxProcs := getUint64Metric(samples, "/sched/gomaxprocs:threads")
goGCPercent := getUint64Metric(samples, "/gc/gogc:percent")
goMemLimit := getUint64Metric(samples, "/gc/gomemlimit:bytes")
return StatusMetrics{
PID: pid,
GoVersion: runtime.Version(),
@@ -326,5 +346,27 @@ func computeAppMetrics() (StatusMetrics, error) {
MemStats: memStats,
GCDurationStats: gcDur,
ProcStats: procStats,
GoMaxProcs: goMaxProcs,
GoGCPercent: goGCPercent,
GoMemLimit: goMemLimit,
}, nil
}
// getUint64Metric retrieves a uint64 metric by name
func getUint64Metric(samples []metrics.Sample, name string) uint64 {
for _, sample := range samples {
if sample.Name == name {
switch sample.Value.Kind() {
case metrics.KindUint64:
return sample.Value.Uint64()
case metrics.KindFloat64:
return uint64(sample.Value.Float64())
case metrics.KindBad:
panic(fmt.Sprintf("metric %s has bad kind", name))
default:
panic(fmt.Sprintf("metric %s has unexpected unsupported kind: %v", name, sample.Value.Kind()))
}
}
}
return 0
}

View File

@@ -24,6 +24,7 @@ import (
"runtime"
"testing"
"github.com/cgrates/cgrates/utils"
"github.com/prometheus/procfs"
)
@@ -34,7 +35,6 @@ func TestStatusMetricsToMap(t *testing.T) {
Sys: 1,
Mallocs: 1,
Frees: 1,
Lookups: 2012,
HeapAlloc: 1000,
HeapSys: 10,
HeapIdle: 500,
@@ -68,6 +68,9 @@ func TestStatusMetricsToMap(t *testing.T) {
GCDurationStats: gcDurationStats,
ProcStats: procStats,
CapsStats: capsStats,
GoMaxProcs: 3,
GoGCPercent: 100,
GoMemLimit: 5555,
}
result, err := sm.ToMap(true, "UTC")
@@ -85,10 +88,13 @@ func TestStatusMetricsToMap(t *testing.T) {
"gc_duration_stats": gcDurationStats.ToMap(),
"proc_stats": procStats.ToMap(),
"caps_stats": capsStats.ToMap(),
"go_maxprocs": uint64(3),
"go_gc_percent": uint64(100),
"go_mem_limit": uint64(5555),
}
if !reflect.DeepEqual(result, expected) {
t.Errorf("Expected %v, got %v", expected, result)
t.Errorf("Expected %v, got %v", utils.ToJSON(expected), utils.ToJSON(result))
}
condensedResult, err := sm.ToMap(false, "UTC")