diff --git a/remappers/hostmetrics/hostmetrics_test.go b/remappers/hostmetrics/hostmetrics_test.go index 5e42495..5323424 100644 --- a/remappers/hostmetrics/hostmetrics_test.go +++ b/remappers/hostmetrics/hostmetrics_test.go @@ -23,6 +23,7 @@ import ( "time" "github.com/elastic/opentelemetry-lib/remappers/common" + "github.com/elastic/opentelemetry-lib/remappers/internal" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/stretchr/testify/assert" @@ -78,115 +79,115 @@ func doTestRemap(t *testing.T, id string, remapOpts ...Option) { name string scraper string resourceAttrs map[string]any - input []testMetric - expected []testMetric + input []internal.TestMetric + expected []internal.TestMetric }{ { name: "cpu", scraper: "cpu", - input: []testMetric{ - {Type: Gauge, Name: "system.cpu.utilization", DP: testDP{Ts: now, Dbl: ptr(0.26), Attrs: map[string]any{"cpu": "cpu0", "state": "user"}}}, - {Type: Gauge, Name: "system.cpu.utilization", DP: testDP{Ts: now, Dbl: ptr(0.24), Attrs: map[string]any{"cpu": "cpu0", "state": "system"}}}, - {Type: Gauge, Name: "system.cpu.utilization", DP: testDP{Ts: now, Dbl: ptr(0.5), Attrs: map[string]any{"cpu": "cpu0", "state": "idle"}}}, - {Type: Gauge, Name: "system.cpu.utilization", DP: testDP{Ts: now, Dbl: ptr(0.1), Attrs: map[string]any{"cpu": "cpu0", "state": "steal"}}}, - {Type: Gauge, Name: "system.cpu.utilization", DP: testDP{Ts: now, Dbl: ptr(0.24), Attrs: map[string]any{"cpu": "cpu1", "state": "user"}}}, - {Type: Gauge, Name: "system.cpu.utilization", DP: testDP{Ts: now, Dbl: ptr(0.44), Attrs: map[string]any{"cpu": "cpu1", "state": "system"}}}, - {Type: Gauge, Name: "system.cpu.utilization", DP: testDP{Ts: now, Dbl: ptr(0.32), Attrs: map[string]any{"cpu": "cpu1", "state": "idle"}}}, - {Type: Gauge, Name: "system.cpu.utilization", DP: testDP{Ts: now, Dbl: ptr(0.05), Attrs: map[string]any{"cpu": "cpu1", "state": "steal"}}}, - {Type: Sum, Name: "system.cpu.logical.count", DP: testDP{Ts: now, Int: ptr(int64(4))}}, + input: []internal.TestMetric{ + {Type: Gauge, Name: "system.cpu.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.26), Attrs: map[string]any{"cpu": "cpu0", "state": "user"}}}, + {Type: Gauge, Name: "system.cpu.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.24), Attrs: map[string]any{"cpu": "cpu0", "state": "system"}}}, + {Type: Gauge, Name: "system.cpu.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.5), Attrs: map[string]any{"cpu": "cpu0", "state": "idle"}}}, + {Type: Gauge, Name: "system.cpu.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.1), Attrs: map[string]any{"cpu": "cpu0", "state": "steal"}}}, + {Type: Gauge, Name: "system.cpu.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.24), Attrs: map[string]any{"cpu": "cpu1", "state": "user"}}}, + {Type: Gauge, Name: "system.cpu.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.44), Attrs: map[string]any{"cpu": "cpu1", "state": "system"}}}, + {Type: Gauge, Name: "system.cpu.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.32), Attrs: map[string]any{"cpu": "cpu1", "state": "idle"}}}, + {Type: Gauge, Name: "system.cpu.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.05), Attrs: map[string]any{"cpu": "cpu1", "state": "steal"}}}, + {Type: Sum, Name: "system.cpu.logical.count", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(4))}}, }, - expected: []testMetric{ - {Type: Gauge, Name: "system.cpu.total.pct", DP: testDP{Ts: now, Dbl: ptr(1.33), Attrs: outAttr("cpu")}}, - {Type: Gauge, Name: "system.cpu.idle.pct", DP: testDP{Ts: now, Dbl: ptr(0.82), Attrs: outAttr("cpu")}}, - {Type: Gauge, Name: "system.cpu.system.pct", DP: testDP{Ts: now, Dbl: ptr(0.68), Attrs: outAttr("cpu")}}, - {Type: Gauge, Name: "system.cpu.user.pct", DP: testDP{Ts: now, Dbl: ptr(0.5), Attrs: outAttr("cpu")}}, - {Type: Gauge, Name: "system.cpu.steal.pct", DP: testDP{Ts: now, Dbl: ptr(0.15), Attrs: outAttr("cpu")}}, - {Type: Gauge, Name: "system.cpu.wait.pct", DP: testDP{Ts: now, Dbl: ptr(0.0), Attrs: outAttr("cpu")}}, - {Type: Gauge, Name: "system.cpu.nice.pct", DP: testDP{Ts: now, Dbl: ptr(0.0), Attrs: outAttr("cpu")}}, - {Type: Gauge, Name: "system.cpu.irq.pct", DP: testDP{Ts: now, Dbl: ptr(0.0), Attrs: outAttr("cpu")}}, - {Type: Gauge, Name: "system.cpu.softirq.pct", DP: testDP{Ts: now, Dbl: ptr(0.0), Attrs: outAttr("cpu")}}, - {Type: Sum, Name: "system.cpu.cores", DP: testDP{Ts: now, Int: ptr(int64(4)), Attrs: outAttr("cpu")}}, - {Type: Sum, Name: "system.load.cores", DP: testDP{Ts: now, Int: ptr(int64(4)), Attrs: outAttr("cpu")}}, - {Type: Gauge, Name: "system.cpu.total.norm.pct", DP: testDP{Ts: now, Dbl: ptr(0.3325), Attrs: outAttr("cpu")}}, - {Type: Gauge, Name: "system.cpu.idle.norm.pct", DP: testDP{Ts: now, Dbl: ptr(0.205), Attrs: outAttr("cpu")}}, - {Type: Gauge, Name: "system.cpu.system.norm.pct", DP: testDP{Ts: now, Dbl: ptr(0.17), Attrs: outAttr("cpu")}}, - {Type: Gauge, Name: "system.cpu.user.norm.pct", DP: testDP{Ts: now, Dbl: ptr(0.125), Attrs: outAttr("cpu")}}, - {Type: Gauge, Name: "system.cpu.steal.norm.pct", DP: testDP{Ts: now, Dbl: ptr(0.0375), Attrs: outAttr("cpu")}}, - {Type: Gauge, Name: "system.cpu.wait.norm.pct", DP: testDP{Ts: now, Dbl: ptr(0.0), Attrs: outAttr("cpu")}}, - {Type: Gauge, Name: "system.cpu.nice.norm.pct", DP: testDP{Ts: now, Dbl: ptr(0.0), Attrs: outAttr("cpu")}}, - {Type: Gauge, Name: "system.cpu.irq.norm.pct", DP: testDP{Ts: now, Dbl: ptr(0.0), Attrs: outAttr("cpu")}}, - {Type: Gauge, Name: "system.cpu.softirq.norm.pct", DP: testDP{Ts: now, Dbl: ptr(0.0), Attrs: outAttr("cpu")}}, + expected: []internal.TestMetric{ + {Type: Gauge, Name: "system.cpu.total.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(1.33), Attrs: outAttr("cpu")}}, + {Type: Gauge, Name: "system.cpu.idle.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.82), Attrs: outAttr("cpu")}}, + {Type: Gauge, Name: "system.cpu.system.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.68), Attrs: outAttr("cpu")}}, + {Type: Gauge, Name: "system.cpu.user.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.5), Attrs: outAttr("cpu")}}, + {Type: Gauge, Name: "system.cpu.steal.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.15), Attrs: outAttr("cpu")}}, + {Type: Gauge, Name: "system.cpu.wait.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.0), Attrs: outAttr("cpu")}}, + {Type: Gauge, Name: "system.cpu.nice.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.0), Attrs: outAttr("cpu")}}, + {Type: Gauge, Name: "system.cpu.irq.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.0), Attrs: outAttr("cpu")}}, + {Type: Gauge, Name: "system.cpu.softirq.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.0), Attrs: outAttr("cpu")}}, + {Type: Sum, Name: "system.cpu.cores", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(4)), Attrs: outAttr("cpu")}}, + {Type: Sum, Name: "system.load.cores", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(4)), Attrs: outAttr("cpu")}}, + {Type: Gauge, Name: "system.cpu.total.norm.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.3325), Attrs: outAttr("cpu")}}, + {Type: Gauge, Name: "system.cpu.idle.norm.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.205), Attrs: outAttr("cpu")}}, + {Type: Gauge, Name: "system.cpu.system.norm.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.17), Attrs: outAttr("cpu")}}, + {Type: Gauge, Name: "system.cpu.user.norm.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.125), Attrs: outAttr("cpu")}}, + {Type: Gauge, Name: "system.cpu.steal.norm.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.0375), Attrs: outAttr("cpu")}}, + {Type: Gauge, Name: "system.cpu.wait.norm.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.0), Attrs: outAttr("cpu")}}, + {Type: Gauge, Name: "system.cpu.nice.norm.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.0), Attrs: outAttr("cpu")}}, + {Type: Gauge, Name: "system.cpu.irq.norm.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.0), Attrs: outAttr("cpu")}}, + {Type: Gauge, Name: "system.cpu.softirq.norm.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.0), Attrs: outAttr("cpu")}}, }, }, { name: "cpu_without_logical_count", scraper: "cpu", - input: []testMetric{ - {Type: Gauge, Name: "system.cpu.utilization", DP: testDP{Ts: now, Dbl: ptr(0.26), Attrs: map[string]any{"cpu": "cpu0", "state": "user"}}}, - {Type: Gauge, Name: "system.cpu.utilization", DP: testDP{Ts: now, Dbl: ptr(0.24), Attrs: map[string]any{"cpu": "cpu0", "state": "system"}}}, - {Type: Gauge, Name: "system.cpu.utilization", DP: testDP{Ts: now, Dbl: ptr(0.5), Attrs: map[string]any{"cpu": "cpu0", "state": "idle"}}}, - {Type: Gauge, Name: "system.cpu.utilization", DP: testDP{Ts: now, Dbl: ptr(0.1), Attrs: map[string]any{"cpu": "cpu0", "state": "steal"}}}, - {Type: Gauge, Name: "system.cpu.utilization", DP: testDP{Ts: now, Dbl: ptr(0.24), Attrs: map[string]any{"cpu": "cpu1", "state": "user"}}}, - {Type: Gauge, Name: "system.cpu.utilization", DP: testDP{Ts: now, Dbl: ptr(0.44), Attrs: map[string]any{"cpu": "cpu1", "state": "system"}}}, - {Type: Gauge, Name: "system.cpu.utilization", DP: testDP{Ts: now, Dbl: ptr(0.32), Attrs: map[string]any{"cpu": "cpu1", "state": "idle"}}}, - {Type: Gauge, Name: "system.cpu.utilization", DP: testDP{Ts: now, Dbl: ptr(0.05), Attrs: map[string]any{"cpu": "cpu1", "state": "steal"}}}, + input: []internal.TestMetric{ + {Type: Gauge, Name: "system.cpu.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.26), Attrs: map[string]any{"cpu": "cpu0", "state": "user"}}}, + {Type: Gauge, Name: "system.cpu.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.24), Attrs: map[string]any{"cpu": "cpu0", "state": "system"}}}, + {Type: Gauge, Name: "system.cpu.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.5), Attrs: map[string]any{"cpu": "cpu0", "state": "idle"}}}, + {Type: Gauge, Name: "system.cpu.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.1), Attrs: map[string]any{"cpu": "cpu0", "state": "steal"}}}, + {Type: Gauge, Name: "system.cpu.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.24), Attrs: map[string]any{"cpu": "cpu1", "state": "user"}}}, + {Type: Gauge, Name: "system.cpu.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.44), Attrs: map[string]any{"cpu": "cpu1", "state": "system"}}}, + {Type: Gauge, Name: "system.cpu.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.32), Attrs: map[string]any{"cpu": "cpu1", "state": "idle"}}}, + {Type: Gauge, Name: "system.cpu.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.05), Attrs: map[string]any{"cpu": "cpu1", "state": "steal"}}}, }, - expected: []testMetric{ - {Type: Gauge, Name: "system.cpu.total.pct", DP: testDP{Ts: now, Dbl: ptr(1.33), Attrs: outAttr("cpu")}}, - {Type: Gauge, Name: "system.cpu.idle.pct", DP: testDP{Ts: now, Dbl: ptr(0.82), Attrs: outAttr("cpu")}}, - {Type: Gauge, Name: "system.cpu.system.pct", DP: testDP{Ts: now, Dbl: ptr(0.68), Attrs: outAttr("cpu")}}, - {Type: Gauge, Name: "system.cpu.user.pct", DP: testDP{Ts: now, Dbl: ptr(0.5), Attrs: outAttr("cpu")}}, - {Type: Gauge, Name: "system.cpu.steal.pct", DP: testDP{Ts: now, Dbl: ptr(0.15), Attrs: outAttr("cpu")}}, - {Type: Gauge, Name: "system.cpu.wait.pct", DP: testDP{Ts: now, Dbl: ptr(0.0), Attrs: outAttr("cpu")}}, - {Type: Gauge, Name: "system.cpu.nice.pct", DP: testDP{Ts: now, Dbl: ptr(0.0), Attrs: outAttr("cpu")}}, - {Type: Gauge, Name: "system.cpu.irq.pct", DP: testDP{Ts: now, Dbl: ptr(0.0), Attrs: outAttr("cpu")}}, - {Type: Gauge, Name: "system.cpu.softirq.pct", DP: testDP{Ts: now, Dbl: ptr(0.0), Attrs: outAttr("cpu")}}, + expected: []internal.TestMetric{ + {Type: Gauge, Name: "system.cpu.total.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(1.33), Attrs: outAttr("cpu")}}, + {Type: Gauge, Name: "system.cpu.idle.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.82), Attrs: outAttr("cpu")}}, + {Type: Gauge, Name: "system.cpu.system.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.68), Attrs: outAttr("cpu")}}, + {Type: Gauge, Name: "system.cpu.user.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.5), Attrs: outAttr("cpu")}}, + {Type: Gauge, Name: "system.cpu.steal.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.15), Attrs: outAttr("cpu")}}, + {Type: Gauge, Name: "system.cpu.wait.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.0), Attrs: outAttr("cpu")}}, + {Type: Gauge, Name: "system.cpu.nice.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.0), Attrs: outAttr("cpu")}}, + {Type: Gauge, Name: "system.cpu.irq.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.0), Attrs: outAttr("cpu")}}, + {Type: Gauge, Name: "system.cpu.softirq.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.0), Attrs: outAttr("cpu")}}, }, }, { name: "load", scraper: "load", - input: []testMetric{ - {Type: Gauge, Name: "system.cpu.load_average.1m", DP: testDP{Ts: now, Dbl: ptr(0.14)}}, - {Type: Gauge, Name: "system.cpu.load_average.5m", DP: testDP{Ts: now, Dbl: ptr(0.12)}}, - {Type: Gauge, Name: "system.cpu.load_average.15m", DP: testDP{Ts: now, Dbl: ptr(0.05)}}, + input: []internal.TestMetric{ + {Type: Gauge, Name: "system.cpu.load_average.1m", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.14)}}, + {Type: Gauge, Name: "system.cpu.load_average.5m", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.12)}}, + {Type: Gauge, Name: "system.cpu.load_average.15m", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.05)}}, }, - expected: []testMetric{ - {Type: Gauge, Name: "system.load.1", DP: testDP{Ts: now, Dbl: ptr(0.14), Attrs: outAttr("load")}}, - {Type: Gauge, Name: "system.load.5", DP: testDP{Ts: now, Dbl: ptr(0.12), Attrs: outAttr("load")}}, - {Type: Gauge, Name: "system.load.15", DP: testDP{Ts: now, Dbl: ptr(0.05), Attrs: outAttr("load")}}, + expected: []internal.TestMetric{ + {Type: Gauge, Name: "system.load.1", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.14), Attrs: outAttr("load")}}, + {Type: Gauge, Name: "system.load.5", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.12), Attrs: outAttr("load")}}, + {Type: Gauge, Name: "system.load.15", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.05), Attrs: outAttr("load")}}, }, }, { name: "memory", scraper: "memory", - input: []testMetric{ - {Type: Sum, Name: "system.memory.usage", DP: testDP{Ts: now, Int: ptr(int64(1024)), Attrs: map[string]any{"state": "buffered"}}}, - {Type: Sum, Name: "system.memory.usage", DP: testDP{Ts: now, Int: ptr(int64(512)), Attrs: map[string]any{"state": "cached"}}}, - {Type: Sum, Name: "system.memory.usage", DP: testDP{Ts: now, Int: ptr(int64(256)), Attrs: map[string]any{"state": "inactive"}}}, - {Type: Sum, Name: "system.memory.usage", DP: testDP{Ts: now, Int: ptr(int64(2048)), Attrs: map[string]any{"state": "free"}}}, - {Type: Sum, Name: "system.memory.usage", DP: testDP{Ts: now, Int: ptr(int64(128)), Attrs: map[string]any{"state": "slab_reclaimable"}}}, - {Type: Sum, Name: "system.memory.usage", DP: testDP{Ts: now, Int: ptr(int64(64)), Attrs: map[string]any{"state": "slab_unreclaimable"}}}, - {Type: Sum, Name: "system.memory.usage", DP: testDP{Ts: now, Int: ptr(int64(4096)), Attrs: map[string]any{"state": "used"}}}, - {Type: Gauge, Name: "system.memory.utilization", DP: testDP{Ts: now, Dbl: ptr(0.133), Attrs: map[string]any{"state": "buffered"}}}, - {Type: Gauge, Name: "system.memory.utilization", DP: testDP{Ts: now, Dbl: ptr(0.066), Attrs: map[string]any{"state": "cached"}}}, - {Type: Gauge, Name: "system.memory.utilization", DP: testDP{Ts: now, Dbl: ptr(0.033), Attrs: map[string]any{"state": "inactive"}}}, - {Type: Gauge, Name: "system.memory.utilization", DP: testDP{Ts: now, Dbl: ptr(0.266), Attrs: map[string]any{"state": "free"}}}, - {Type: Gauge, Name: "system.memory.utilization", DP: testDP{Ts: now, Dbl: ptr(0.016), Attrs: map[string]any{"state": "slab_reclaimable"}}}, - {Type: Gauge, Name: "system.memory.utilization", DP: testDP{Ts: now, Dbl: ptr(0.008), Attrs: map[string]any{"state": "slab_unreclaimable"}}}, - {Type: Gauge, Name: "system.memory.utilization", DP: testDP{Ts: now, Dbl: ptr(0.533), Attrs: map[string]any{"state": "used"}}}, + input: []internal.TestMetric{ + {Type: Sum, Name: "system.memory.usage", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(1024)), Attrs: map[string]any{"state": "buffered"}}}, + {Type: Sum, Name: "system.memory.usage", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(512)), Attrs: map[string]any{"state": "cached"}}}, + {Type: Sum, Name: "system.memory.usage", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(256)), Attrs: map[string]any{"state": "inactive"}}}, + {Type: Sum, Name: "system.memory.usage", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(2048)), Attrs: map[string]any{"state": "free"}}}, + {Type: Sum, Name: "system.memory.usage", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(128)), Attrs: map[string]any{"state": "slab_reclaimable"}}}, + {Type: Sum, Name: "system.memory.usage", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(64)), Attrs: map[string]any{"state": "slab_unreclaimable"}}}, + {Type: Sum, Name: "system.memory.usage", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(4096)), Attrs: map[string]any{"state": "used"}}}, + {Type: Gauge, Name: "system.memory.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.133), Attrs: map[string]any{"state": "buffered"}}}, + {Type: Gauge, Name: "system.memory.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.066), Attrs: map[string]any{"state": "cached"}}}, + {Type: Gauge, Name: "system.memory.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.033), Attrs: map[string]any{"state": "inactive"}}}, + {Type: Gauge, Name: "system.memory.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.266), Attrs: map[string]any{"state": "free"}}}, + {Type: Gauge, Name: "system.memory.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.016), Attrs: map[string]any{"state": "slab_reclaimable"}}}, + {Type: Gauge, Name: "system.memory.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.008), Attrs: map[string]any{"state": "slab_unreclaimable"}}}, + {Type: Gauge, Name: "system.memory.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.533), Attrs: map[string]any{"state": "used"}}}, }, - expected: []testMetric{ + expected: []internal.TestMetric{ // total = used + free + buffered + cached as gopsutil calculates used = total - free - buffered - cached - {Type: Sum, Name: "system.memory.total", DP: testDP{Ts: now, Int: ptr(int64(7680)), Attrs: outAttr("memory")}}, - {Type: Sum, Name: "system.memory.free", DP: testDP{Ts: now, Int: ptr(int64(2048)), Attrs: outAttr("memory")}}, - {Type: Sum, Name: "system.memory.cached", DP: testDP{Ts: now, Int: ptr(int64(512)), Attrs: outAttr("memory")}}, + {Type: Sum, Name: "system.memory.total", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(7680)), Attrs: outAttr("memory")}}, + {Type: Sum, Name: "system.memory.free", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(2048)), Attrs: outAttr("memory")}}, + {Type: Sum, Name: "system.memory.cached", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(512)), Attrs: outAttr("memory")}}, // used = used + buffered + cached as gopsutil calculates used = total - free - buffered - cached - {Type: Sum, Name: "system.memory.used.bytes", DP: testDP{Ts: now, Int: ptr(int64(5632)), Attrs: outAttr("memory")}}, - {Type: Sum, Name: "system.memory.actual.used.bytes", DP: testDP{Ts: now, Int: ptr(int64(5312)), Attrs: outAttr("memory")}}, - {Type: Sum, Name: "system.memory.actual.free", DP: testDP{Ts: now, Int: ptr(int64(2368)), Attrs: outAttr("memory")}}, - {Type: Gauge, Name: "system.memory.used.pct", DP: testDP{Ts: now, Dbl: ptr(0.734), Attrs: outAttr("memory")}}, - {Type: Gauge, Name: "system.memory.actual.used.pct", DP: testDP{Ts: now, Dbl: ptr(0.69), Attrs: outAttr("memory")}}, + {Type: Sum, Name: "system.memory.used.bytes", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(5632)), Attrs: outAttr("memory")}}, + {Type: Sum, Name: "system.memory.actual.used.bytes", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(5312)), Attrs: outAttr("memory")}}, + {Type: Sum, Name: "system.memory.actual.free", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(2368)), Attrs: outAttr("memory")}}, + {Type: Gauge, Name: "system.memory.used.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.734), Attrs: outAttr("memory")}}, + {Type: Gauge, Name: "system.memory.actual.used.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.69), Attrs: outAttr("memory")}}, }, }, { @@ -198,107 +199,107 @@ func doTestRemap(t *testing.T, id string, remapOpts ...Option) { "process.executable.path": ProcPath, "process.executable.name": ProcName, }, - input: []testMetric{ - {Type: Sum, Name: "process.threads", DP: testDP{Ts: now, Int: ptr(int64(7))}}, - {Type: Gauge, Name: "process.memory.utilization", DP: testDP{Ts: now, Dbl: ptr(15.0)}}, - {Type: Sum, Name: "process.memory.usage", DP: testDP{Ts: now, Int: ptr(int64(2048))}}, - {Type: Sum, Name: "process.memory.virtual", DP: testDP{Ts: now, Int: ptr(int64(128))}}, - {Type: Sum, Name: "process.open_file_descriptors", DP: testDP{Ts: now, Int: ptr(int64(10))}}, - {Type: Sum, Name: "process.cpu.time", DP: testDP{Ts: now, Int: ptr(int64(3)), Attrs: map[string]any{"state": "system"}}}, - {Type: Sum, Name: "process.cpu.time", DP: testDP{Ts: now, Int: ptr(int64(4)), Attrs: map[string]any{"state": "user"}}}, - {Type: Sum, Name: "process.cpu.time", DP: testDP{Ts: now, Int: ptr(int64(5)), Attrs: map[string]any{"state": "wait"}}}, - {Type: Sum, Name: "process.disk.io", DP: testDP{Ts: now, Int: ptr(int64(1024))}}, - {Type: Sum, Name: "process.disk.operations", DP: testDP{Ts: now, Int: ptr(int64(10))}}, + input: []internal.TestMetric{ + {Type: Sum, Name: "process.threads", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(7))}}, + {Type: Gauge, Name: "process.memory.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(15.0)}}, + {Type: Sum, Name: "process.memory.usage", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(2048))}}, + {Type: Sum, Name: "process.memory.virtual", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(128))}}, + {Type: Sum, Name: "process.open_file_descriptors", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(10))}}, + {Type: Sum, Name: "process.cpu.time", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(3)), Attrs: map[string]any{"state": "system"}}}, + {Type: Sum, Name: "process.cpu.time", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(4)), Attrs: map[string]any{"state": "user"}}}, + {Type: Sum, Name: "process.cpu.time", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(5)), Attrs: map[string]any{"state": "wait"}}}, + {Type: Sum, Name: "process.disk.io", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(1024))}}, + {Type: Sum, Name: "process.disk.operations", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(10))}}, }, - expected: []testMetric{ - {Type: Sum, Name: "process.cpu.start_time", DP: testDP{Ts: now, Int: ptr(int64(0)), Attrs: outAttr("process")}}, - {Type: Sum, Name: "system.process.num_threads", DP: testDP{Ts: now, Int: ptr(int64(7)), Attrs: outAttr("process")}}, - {Type: Gauge, Name: "system.process.memory.rss.pct", DP: testDP{Ts: now, Dbl: ptr(0.15), Attrs: outAttr("process")}}, - {Type: Sum, Name: "system.process.memory.rss.bytes", DP: testDP{Ts: now, Int: ptr(int64(2048)), Attrs: outAttr("process")}}, - {Type: Sum, Name: "system.process.memory.size", DP: testDP{Ts: now, Int: ptr(int64(128)), Attrs: outAttr("process")}}, - {Type: Sum, Name: "system.process.fd.open", DP: testDP{Ts: now, Int: ptr(int64(10)), Attrs: outAttr("process")}}, - {Type: Gauge, Name: "process.memory.pct", DP: testDP{Ts: now, Dbl: ptr(0.15), Attrs: outAttr("process")}}, - {Type: Sum, Name: "system.process.cpu.total.value", DP: testDP{Ts: now, Dbl: ptr(0.0), Attrs: outAttr("process")}}, - {Type: Sum, Name: "system.process.cpu.system.ticks", DP: testDP{Ts: now, Dbl: ptr(0.0), Attrs: outAttr("process")}}, - {Type: Sum, Name: "system.process.cpu.user.ticks", DP: testDP{Ts: now, Dbl: ptr(0.0), Attrs: outAttr("process")}}, - {Type: Sum, Name: "system.process.cpu.total.ticks", DP: testDP{Ts: now, Dbl: ptr(0.0), Attrs: outAttr("process")}}, - {Type: Sum, Name: "system.process.io.read_bytes", DP: testDP{Ts: now, Int: ptr(int64(0)), Attrs: outAttr("process")}}, - {Type: Sum, Name: "system.process.io.write_bytes", DP: testDP{Ts: now, Int: ptr(int64(0)), Attrs: outAttr("process")}}, - {Type: Sum, Name: "system.process.io.read_ops", DP: testDP{Ts: now, Int: ptr(int64(0)), Attrs: outAttr("process")}}, - {Type: Sum, Name: "system.process.io.write_ops", DP: testDP{Ts: now, Int: ptr(int64(0)), Attrs: outAttr("process")}}, - {Type: Gauge, Name: "system.process.cpu.total.pct", DP: testDP{Ts: now, Dbl: ptr(0.0), Attrs: outAttr("process")}}, + expected: []internal.TestMetric{ + {Type: Sum, Name: "process.cpu.start_time", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(0)), Attrs: outAttr("process")}}, + {Type: Sum, Name: "system.process.num_threads", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(7)), Attrs: outAttr("process")}}, + {Type: Gauge, Name: "system.process.memory.rss.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.15), Attrs: outAttr("process")}}, + {Type: Sum, Name: "system.process.memory.rss.bytes", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(2048)), Attrs: outAttr("process")}}, + {Type: Sum, Name: "system.process.memory.size", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(128)), Attrs: outAttr("process")}}, + {Type: Sum, Name: "system.process.fd.open", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(10)), Attrs: outAttr("process")}}, + {Type: Gauge, Name: "process.memory.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.15), Attrs: outAttr("process")}}, + {Type: Sum, Name: "system.process.cpu.total.value", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.0), Attrs: outAttr("process")}}, + {Type: Sum, Name: "system.process.cpu.system.ticks", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.0), Attrs: outAttr("process")}}, + {Type: Sum, Name: "system.process.cpu.user.ticks", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.0), Attrs: outAttr("process")}}, + {Type: Sum, Name: "system.process.cpu.total.ticks", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.0), Attrs: outAttr("process")}}, + {Type: Sum, Name: "system.process.io.read_bytes", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(0)), Attrs: outAttr("process")}}, + {Type: Sum, Name: "system.process.io.write_bytes", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(0)), Attrs: outAttr("process")}}, + {Type: Sum, Name: "system.process.io.read_ops", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(0)), Attrs: outAttr("process")}}, + {Type: Sum, Name: "system.process.io.write_ops", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(0)), Attrs: outAttr("process")}}, + {Type: Gauge, Name: "system.process.cpu.total.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.0), Attrs: outAttr("process")}}, }, }, { name: "processes", scraper: "processes", - input: []testMetric{ - {Type: Sum, Name: "system.processes.count", DP: testDP{Ts: now, Int: ptr(int64(7)), Attrs: map[string]any{"status": "idle"}}}, - {Type: Sum, Name: "system.processes.count", DP: testDP{Ts: now, Int: ptr(int64(3)), Attrs: map[string]any{"status": "sleeping"}}}, - {Type: Sum, Name: "system.processes.count", DP: testDP{Ts: now, Int: ptr(int64(5)), Attrs: map[string]any{"status": "stopped"}}}, - {Type: Sum, Name: "system.processes.count", DP: testDP{Ts: now, Int: ptr(int64(1)), Attrs: map[string]any{"status": "zombies"}}}, + input: []internal.TestMetric{ + {Type: Sum, Name: "system.processes.count", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(7)), Attrs: map[string]any{"status": "idle"}}}, + {Type: Sum, Name: "system.processes.count", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(3)), Attrs: map[string]any{"status": "sleeping"}}}, + {Type: Sum, Name: "system.processes.count", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(5)), Attrs: map[string]any{"status": "stopped"}}}, + {Type: Sum, Name: "system.processes.count", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(1)), Attrs: map[string]any{"status": "zombies"}}}, }, - expected: []testMetric{ - {Type: Sum, Name: "system.process.summary.idle", DP: testDP{Ts: now, Int: ptr(int64(7)), Attrs: outAttr("processes")}}, - {Type: Sum, Name: "system.process.summary.sleeping", DP: testDP{Ts: now, Int: ptr(int64(3)), Attrs: outAttr("processes")}}, - {Type: Sum, Name: "system.process.summary.stopped", DP: testDP{Ts: now, Int: ptr(int64(5)), Attrs: outAttr("processes")}}, - {Type: Sum, Name: "system.process.summary.zombie", DP: testDP{Ts: now, Int: ptr(int64(1)), Attrs: outAttr("processes")}}, - {Type: Sum, Name: "system.process.summary.total", DP: testDP{Ts: now, Int: ptr(int64(16)), Attrs: outAttr("processes")}}, + expected: []internal.TestMetric{ + {Type: Sum, Name: "system.process.summary.idle", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(7)), Attrs: outAttr("processes")}}, + {Type: Sum, Name: "system.process.summary.sleeping", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(3)), Attrs: outAttr("processes")}}, + {Type: Sum, Name: "system.process.summary.stopped", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(5)), Attrs: outAttr("processes")}}, + {Type: Sum, Name: "system.process.summary.zombie", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(1)), Attrs: outAttr("processes")}}, + {Type: Sum, Name: "system.process.summary.total", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(16)), Attrs: outAttr("processes")}}, }, }, { name: "network", scraper: "network", - input: []testMetric{ - {Type: Sum, Name: "system.network.io", DP: testDP{Ts: now, Int: ptr(int64(1024)), Attrs: map[string]any{"device": Device, "direction": "receive"}}}, - {Type: Sum, Name: "system.network.io", DP: testDP{Ts: now, Int: ptr(int64(2048)), Attrs: map[string]any{"device": Device, "direction": "transmit"}}}, - {Type: Sum, Name: "system.network.packets", DP: testDP{Ts: now, Int: ptr(int64(11)), Attrs: map[string]any{"device": Device, "direction": "receive"}}}, - {Type: Sum, Name: "system.network.packets", DP: testDP{Ts: now, Int: ptr(int64(9)), Attrs: map[string]any{"device": Device, "direction": "transmit"}}}, - {Type: Sum, Name: "system.network.dropped", DP: testDP{Ts: now, Int: ptr(int64(3)), Attrs: map[string]any{"device": Device, "direction": "receive"}}}, - {Type: Sum, Name: "system.network.dropped", DP: testDP{Ts: now, Int: ptr(int64(4)), Attrs: map[string]any{"device": Device, "direction": "transmit"}}}, - {Type: Sum, Name: "system.network.errors", DP: testDP{Ts: now, Int: ptr(int64(1)), Attrs: map[string]any{"device": Device, "direction": "receive"}}}, - {Type: Sum, Name: "system.network.errors", DP: testDP{Ts: now, Int: ptr(int64(2)), Attrs: map[string]any{"device": Device, "direction": "transmit"}}}, + input: []internal.TestMetric{ + {Type: Sum, Name: "system.network.io", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(1024)), Attrs: map[string]any{"device": Device, "direction": "receive"}}}, + {Type: Sum, Name: "system.network.io", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(2048)), Attrs: map[string]any{"device": Device, "direction": "transmit"}}}, + {Type: Sum, Name: "system.network.packets", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(11)), Attrs: map[string]any{"device": Device, "direction": "receive"}}}, + {Type: Sum, Name: "system.network.packets", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(9)), Attrs: map[string]any{"device": Device, "direction": "transmit"}}}, + {Type: Sum, Name: "system.network.dropped", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(3)), Attrs: map[string]any{"device": Device, "direction": "receive"}}}, + {Type: Sum, Name: "system.network.dropped", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(4)), Attrs: map[string]any{"device": Device, "direction": "transmit"}}}, + {Type: Sum, Name: "system.network.errors", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(1)), Attrs: map[string]any{"device": Device, "direction": "receive"}}}, + {Type: Sum, Name: "system.network.errors", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(2)), Attrs: map[string]any{"device": Device, "direction": "transmit"}}}, }, - expected: []testMetric{ - {Type: Sum, Name: "system.network.in.bytes", DP: testDP{Ts: now, Int: ptr(int64(1024)), Attrs: outAttr("network")}}, - {Type: Sum, Name: "system.network.out.bytes", DP: testDP{Ts: now, Int: ptr(int64(2048)), Attrs: outAttr("network")}}, - {Type: Sum, Name: "system.network.in.packets", DP: testDP{Ts: now, Int: ptr(int64(11)), Attrs: outAttr("network")}}, - {Type: Sum, Name: "system.network.out.packets", DP: testDP{Ts: now, Int: ptr(int64(9)), Attrs: outAttr("network")}}, - {Type: Sum, Name: "system.network.in.dropped", DP: testDP{Ts: now, Int: ptr(int64(3)), Attrs: outAttr("network")}}, - {Type: Sum, Name: "system.network.out.dropped", DP: testDP{Ts: now, Int: ptr(int64(4)), Attrs: outAttr("network")}}, - {Type: Sum, Name: "system.network.in.errors", DP: testDP{Ts: now, Int: ptr(int64(1)), Attrs: outAttr("network")}}, - {Type: Sum, Name: "system.network.out.errors", DP: testDP{Ts: now, Int: ptr(int64(2)), Attrs: outAttr("network")}}, + expected: []internal.TestMetric{ + {Type: Sum, Name: "system.network.in.bytes", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(1024)), Attrs: outAttr("network")}}, + {Type: Sum, Name: "system.network.out.bytes", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(2048)), Attrs: outAttr("network")}}, + {Type: Sum, Name: "system.network.in.packets", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(11)), Attrs: outAttr("network")}}, + {Type: Sum, Name: "system.network.out.packets", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(9)), Attrs: outAttr("network")}}, + {Type: Sum, Name: "system.network.in.dropped", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(3)), Attrs: outAttr("network")}}, + {Type: Sum, Name: "system.network.out.dropped", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(4)), Attrs: outAttr("network")}}, + {Type: Sum, Name: "system.network.in.errors", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(1)), Attrs: outAttr("network")}}, + {Type: Sum, Name: "system.network.out.errors", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(2)), Attrs: outAttr("network")}}, }, }, { name: "disk", scraper: "disk", - input: []testMetric{ - {Type: Sum, Name: "system.disk.io", DP: testDP{Ts: now, Int: ptr(int64(1888256)), Attrs: map[string]any{"device": Disk, "direction": "read"}}}, - {Type: Sum, Name: "system.disk.io", DP: testDP{Ts: now, Int: ptr(int64(512)), Attrs: map[string]any{"device": Disk, "direction": "write"}}}, - {Type: Sum, Name: "system.disk.operations", DP: testDP{Ts: now, Int: ptr(int64(15390)), Attrs: map[string]any{"device": Disk, "direction": "read"}}}, - {Type: Sum, Name: "system.disk.operations", DP: testDP{Ts: now, Int: ptr(int64(371687)), Attrs: map[string]any{"device": Disk, "direction": "write"}}}, - {Type: Sum, Name: "system.disk.operation_time", DP: testDP{Ts: now, Dbl: ptr(11.182), Attrs: map[string]any{"device": Disk, "direction": "read"}}}, - {Type: Sum, Name: "system.disk.operation_time", DP: testDP{Ts: now, Dbl: ptr(617.289), Attrs: map[string]any{"device": Disk, "direction": "write"}}}, - {Type: Sum, Name: "system.disk.io_time", DP: testDP{Ts: now, Dbl: ptr(520.3), Attrs: map[string]any{"device": Disk}}}, - {Type: Sum, Name: "system.disk.pending_operations", DP: testDP{Ts: now, Int: ptr(int64(102)), Attrs: map[string]any{"device": Disk}}}, + input: []internal.TestMetric{ + {Type: Sum, Name: "system.disk.io", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(1888256)), Attrs: map[string]any{"device": Disk, "direction": "read"}}}, + {Type: Sum, Name: "system.disk.io", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(512)), Attrs: map[string]any{"device": Disk, "direction": "write"}}}, + {Type: Sum, Name: "system.disk.operations", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(15390)), Attrs: map[string]any{"device": Disk, "direction": "read"}}}, + {Type: Sum, Name: "system.disk.operations", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(371687)), Attrs: map[string]any{"device": Disk, "direction": "write"}}}, + {Type: Sum, Name: "system.disk.operation_time", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(11.182), Attrs: map[string]any{"device": Disk, "direction": "read"}}}, + {Type: Sum, Name: "system.disk.operation_time", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(617.289), Attrs: map[string]any{"device": Disk, "direction": "write"}}}, + {Type: Sum, Name: "system.disk.io_time", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(520.3), Attrs: map[string]any{"device": Disk}}}, + {Type: Sum, Name: "system.disk.pending_operations", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(102)), Attrs: map[string]any{"device": Disk}}}, }, - expected: []testMetric{ - {Type: Sum, Name: "system.diskio.read.bytes", DP: testDP{Ts: now, Int: ptr(int64(1888256)), Attrs: outAttr("disk")}}, - {Type: Sum, Name: "system.diskio.write.bytes", DP: testDP{Ts: now, Int: ptr(int64(512)), Attrs: outAttr("disk")}}, - {Type: Sum, Name: "system.diskio.read.count", DP: testDP{Ts: now, Int: ptr(int64(15390)), Attrs: outAttr("disk")}}, - {Type: Sum, Name: "system.diskio.write.count", DP: testDP{Ts: now, Int: ptr(int64(371687)), Attrs: outAttr("disk")}}, - {Type: Sum, Name: "system.diskio.read.time", DP: testDP{Ts: now, Dbl: ptr(11182.0), Attrs: outAttr("disk")}}, - {Type: Sum, Name: "system.diskio.write.time", DP: testDP{Ts: now, Dbl: ptr(617289.0), Attrs: outAttr("disk")}}, - {Type: Sum, Name: "system.diskio.io.time", DP: testDP{Ts: now, Dbl: ptr(520300.0), Attrs: outAttr("disk")}}, - {Type: Sum, Name: "system.diskio.io.ops", DP: testDP{Ts: now, Int: ptr(int64(102)), Attrs: outAttr("disk")}}, + expected: []internal.TestMetric{ + {Type: Sum, Name: "system.diskio.read.bytes", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(1888256)), Attrs: outAttr("disk")}}, + {Type: Sum, Name: "system.diskio.write.bytes", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(512)), Attrs: outAttr("disk")}}, + {Type: Sum, Name: "system.diskio.read.count", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(15390)), Attrs: outAttr("disk")}}, + {Type: Sum, Name: "system.diskio.write.count", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(371687)), Attrs: outAttr("disk")}}, + {Type: Sum, Name: "system.diskio.read.time", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(11182.0), Attrs: outAttr("disk")}}, + {Type: Sum, Name: "system.diskio.write.time", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(617289.0), Attrs: outAttr("disk")}}, + {Type: Sum, Name: "system.diskio.io.time", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(520300.0), Attrs: outAttr("disk")}}, + {Type: Sum, Name: "system.diskio.io.ops", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(102)), Attrs: outAttr("disk")}}, }, }, } { t.Run(fmt.Sprintf("%s/%s", tc.name, id), func(t *testing.T) { sm := pmetric.NewScopeMetrics() sm.Scope().SetName(fmt.Sprintf("%s/%s", scopePrefix, tc.scraper)) - testMetricToMetricSlice(t, tc.input, sm.Metrics()) + internal.TestMetricToMetricSlice(t, tc.input, sm.Metrics()) resource := pcommon.NewResource() resource.Attributes().FromRaw(tc.resourceAttrs) @@ -306,67 +307,67 @@ func doTestRemap(t *testing.T, id string, remapOpts ...Option) { actual := pmetric.NewMetricSlice() r := NewRemapper(zaptest.NewLogger(t), remapOpts...) r.Remap(sm, actual, resource) - assert.Empty(t, cmp.Diff(tc.expected, metricSliceToTestMetric(t, actual), cmpopts.EquateApprox(0, 0.001))) + assert.Empty(t, cmp.Diff(tc.expected, internal.MetricSliceToTestMetric(t, actual), cmpopts.EquateApprox(0, 0.001))) }) } } func BenchmarkRemap(b *testing.B) { now := pcommon.NewTimestampFromTime(time.Now()) - in := map[string][]testMetric{ - "cpu": []testMetric{ - {Type: Gauge, Name: "system.cpu.utilization", DP: testDP{Ts: now, Dbl: ptr(0.26), Attrs: map[string]any{"cpu": "cpu0", "state": "user"}}}, - {Type: Gauge, Name: "system.cpu.utilization", DP: testDP{Ts: now, Dbl: ptr(0.24), Attrs: map[string]any{"cpu": "cpu0", "state": "system"}}}, - {Type: Gauge, Name: "system.cpu.utilization", DP: testDP{Ts: now, Dbl: ptr(0.5), Attrs: map[string]any{"cpu": "cpu0", "state": "idle"}}}, - {Type: Gauge, Name: "system.cpu.utilization", DP: testDP{Ts: now, Dbl: ptr(0.1), Attrs: map[string]any{"cpu": "cpu0", "state": "steal"}}}, - {Type: Gauge, Name: "system.cpu.utilization", DP: testDP{Ts: now, Dbl: ptr(0.24), Attrs: map[string]any{"cpu": "cpu1", "state": "user"}}}, - {Type: Gauge, Name: "system.cpu.utilization", DP: testDP{Ts: now, Dbl: ptr(0.44), Attrs: map[string]any{"cpu": "cpu1", "state": "system"}}}, - {Type: Gauge, Name: "system.cpu.utilization", DP: testDP{Ts: now, Dbl: ptr(0.32), Attrs: map[string]any{"cpu": "cpu1", "state": "idle"}}}, - {Type: Gauge, Name: "system.cpu.utilization", DP: testDP{Ts: now, Dbl: ptr(0.05), Attrs: map[string]any{"cpu": "cpu1", "state": "steal"}}}, - {Type: Sum, Name: "system.cpu.logical.count", DP: testDP{Ts: now, Int: ptr(int64(4))}}, + in := map[string][]internal.TestMetric{ + "cpu": []internal.TestMetric{ + {Type: Gauge, Name: "system.cpu.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.26), Attrs: map[string]any{"cpu": "cpu0", "state": "user"}}}, + {Type: Gauge, Name: "system.cpu.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.24), Attrs: map[string]any{"cpu": "cpu0", "state": "system"}}}, + {Type: Gauge, Name: "system.cpu.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.5), Attrs: map[string]any{"cpu": "cpu0", "state": "idle"}}}, + {Type: Gauge, Name: "system.cpu.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.1), Attrs: map[string]any{"cpu": "cpu0", "state": "steal"}}}, + {Type: Gauge, Name: "system.cpu.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.24), Attrs: map[string]any{"cpu": "cpu1", "state": "user"}}}, + {Type: Gauge, Name: "system.cpu.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.44), Attrs: map[string]any{"cpu": "cpu1", "state": "system"}}}, + {Type: Gauge, Name: "system.cpu.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.32), Attrs: map[string]any{"cpu": "cpu1", "state": "idle"}}}, + {Type: Gauge, Name: "system.cpu.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.05), Attrs: map[string]any{"cpu": "cpu1", "state": "steal"}}}, + {Type: Sum, Name: "system.cpu.logical.count", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(4))}}, }, - "load": []testMetric{ - {Type: Gauge, Name: "system.cpu.load_average.1m", DP: testDP{Ts: now, Dbl: ptr(0.14)}}, - {Type: Gauge, Name: "system.cpu.load_average.5m", DP: testDP{Ts: now, Dbl: ptr(0.12)}}, - {Type: Gauge, Name: "system.cpu.load_average.15m", DP: testDP{Ts: now, Dbl: ptr(0.05)}}, + "load": []internal.TestMetric{ + {Type: Gauge, Name: "system.cpu.load_average.1m", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.14)}}, + {Type: Gauge, Name: "system.cpu.load_average.5m", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.12)}}, + {Type: Gauge, Name: "system.cpu.load_average.15m", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.05)}}, }, - "memory": []testMetric{ - {Type: Sum, Name: "system.memory.usage", DP: testDP{Ts: now, Int: ptr(int64(1024)), Attrs: map[string]any{"state": "buffered"}}}, - {Type: Sum, Name: "system.memory.usage", DP: testDP{Ts: now, Int: ptr(int64(512)), Attrs: map[string]any{"state": "cached"}}}, - {Type: Sum, Name: "system.memory.usage", DP: testDP{Ts: now, Int: ptr(int64(256)), Attrs: map[string]any{"state": "inactive"}}}, - {Type: Sum, Name: "system.memory.usage", DP: testDP{Ts: now, Int: ptr(int64(2048)), Attrs: map[string]any{"state": "free"}}}, - {Type: Sum, Name: "system.memory.usage", DP: testDP{Ts: now, Int: ptr(int64(128)), Attrs: map[string]any{"state": "slab_reclaimable"}}}, - {Type: Sum, Name: "system.memory.usage", DP: testDP{Ts: now, Int: ptr(int64(64)), Attrs: map[string]any{"state": "slab_unreclaimable"}}}, - {Type: Sum, Name: "system.memory.usage", DP: testDP{Ts: now, Int: ptr(int64(4096)), Attrs: map[string]any{"state": "used"}}}, - {Type: Gauge, Name: "system.memory.utilization", DP: testDP{Ts: now, Dbl: ptr(0.133), Attrs: map[string]any{"state": "buffered"}}}, - {Type: Gauge, Name: "system.memory.utilization", DP: testDP{Ts: now, Dbl: ptr(0.066), Attrs: map[string]any{"state": "cached"}}}, - {Type: Gauge, Name: "system.memory.utilization", DP: testDP{Ts: now, Dbl: ptr(0.033), Attrs: map[string]any{"state": "inactive"}}}, - {Type: Gauge, Name: "system.memory.utilization", DP: testDP{Ts: now, Dbl: ptr(0.266), Attrs: map[string]any{"state": "free"}}}, - {Type: Gauge, Name: "system.memory.utilization", DP: testDP{Ts: now, Dbl: ptr(0.016), Attrs: map[string]any{"state": "slab_reclaimable"}}}, - {Type: Gauge, Name: "system.memory.utilization", DP: testDP{Ts: now, Dbl: ptr(0.008), Attrs: map[string]any{"state": "slab_unreclaimable"}}}, - {Type: Gauge, Name: "system.memory.utilization", DP: testDP{Ts: now, Dbl: ptr(0.533), Attrs: map[string]any{"state": "used"}}}, + "memory": []internal.TestMetric{ + {Type: Sum, Name: "system.memory.usage", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(1024)), Attrs: map[string]any{"state": "buffered"}}}, + {Type: Sum, Name: "system.memory.usage", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(512)), Attrs: map[string]any{"state": "cached"}}}, + {Type: Sum, Name: "system.memory.usage", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(256)), Attrs: map[string]any{"state": "inactive"}}}, + {Type: Sum, Name: "system.memory.usage", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(2048)), Attrs: map[string]any{"state": "free"}}}, + {Type: Sum, Name: "system.memory.usage", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(128)), Attrs: map[string]any{"state": "slab_reclaimable"}}}, + {Type: Sum, Name: "system.memory.usage", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(64)), Attrs: map[string]any{"state": "slab_unreclaimable"}}}, + {Type: Sum, Name: "system.memory.usage", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(4096)), Attrs: map[string]any{"state": "used"}}}, + {Type: Gauge, Name: "system.memory.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.133), Attrs: map[string]any{"state": "buffered"}}}, + {Type: Gauge, Name: "system.memory.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.066), Attrs: map[string]any{"state": "cached"}}}, + {Type: Gauge, Name: "system.memory.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.033), Attrs: map[string]any{"state": "inactive"}}}, + {Type: Gauge, Name: "system.memory.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.266), Attrs: map[string]any{"state": "free"}}}, + {Type: Gauge, Name: "system.memory.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.016), Attrs: map[string]any{"state": "slab_reclaimable"}}}, + {Type: Gauge, Name: "system.memory.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.008), Attrs: map[string]any{"state": "slab_unreclaimable"}}}, + {Type: Gauge, Name: "system.memory.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.533), Attrs: map[string]any{"state": "used"}}}, }, - "process": []testMetric{ - {Type: Sum, Name: "process.threads", DP: testDP{Ts: now, Int: ptr(int64(7))}}, - {Type: Gauge, Name: "process.memory.utilization", DP: testDP{Ts: now, Dbl: ptr(15.0)}}, - {Type: Sum, Name: "process.memory.usage", DP: testDP{Ts: now, Int: ptr(int64(2048))}}, - {Type: Sum, Name: "process.memory.virtual", DP: testDP{Ts: now, Int: ptr(int64(128))}}, - {Type: Sum, Name: "process.open_file_descriptors", DP: testDP{Ts: now, Int: ptr(int64(10))}}, - {Type: Sum, Name: "process.cpu.time", DP: testDP{Ts: now, Int: ptr(int64(3)), Attrs: map[string]any{"state": "system"}}}, - {Type: Sum, Name: "process.cpu.time", DP: testDP{Ts: now, Int: ptr(int64(4)), Attrs: map[string]any{"state": "user"}}}, - {Type: Sum, Name: "process.cpu.time", DP: testDP{Ts: now, Int: ptr(int64(5)), Attrs: map[string]any{"state": "wait"}}}, - {Type: Sum, Name: "process.disk.io", DP: testDP{Ts: now, Int: ptr(int64(1024))}}, - {Type: Sum, Name: "process.disk.operations", DP: testDP{Ts: now, Int: ptr(int64(10))}}, + "process": []internal.TestMetric{ + {Type: Sum, Name: "process.threads", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(7))}}, + {Type: Gauge, Name: "process.memory.utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(15.0)}}, + {Type: Sum, Name: "process.memory.usage", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(2048))}}, + {Type: Sum, Name: "process.memory.virtual", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(128))}}, + {Type: Sum, Name: "process.open_file_descriptors", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(10))}}, + {Type: Sum, Name: "process.cpu.time", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(3)), Attrs: map[string]any{"state": "system"}}}, + {Type: Sum, Name: "process.cpu.time", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(4)), Attrs: map[string]any{"state": "user"}}}, + {Type: Sum, Name: "process.cpu.time", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(5)), Attrs: map[string]any{"state": "wait"}}}, + {Type: Sum, Name: "process.disk.io", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(1024))}}, + {Type: Sum, Name: "process.disk.operations", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(10))}}, }, - "network": []testMetric{ - {Type: Sum, Name: "system.network.io", DP: testDP{Ts: now, Int: ptr(int64(1024)), Attrs: map[string]any{"device": Device, "direction": "receive"}}}, - {Type: Sum, Name: "system.network.io", DP: testDP{Ts: now, Int: ptr(int64(2048)), Attrs: map[string]any{"device": Device, "direction": "transmit"}}}, - {Type: Sum, Name: "system.network.packets", DP: testDP{Ts: now, Int: ptr(int64(11)), Attrs: map[string]any{"device": Device, "direction": "receive"}}}, - {Type: Sum, Name: "system.network.packets", DP: testDP{Ts: now, Int: ptr(int64(9)), Attrs: map[string]any{"device": Device, "direction": "transmit"}}}, - {Type: Sum, Name: "system.network.dropped", DP: testDP{Ts: now, Int: ptr(int64(3)), Attrs: map[string]any{"device": Device, "direction": "receive"}}}, - {Type: Sum, Name: "system.network.dropped", DP: testDP{Ts: now, Int: ptr(int64(4)), Attrs: map[string]any{"device": Device, "direction": "transmit"}}}, - {Type: Sum, Name: "system.network.errors", DP: testDP{Ts: now, Int: ptr(int64(1)), Attrs: map[string]any{"device": Device, "direction": "receive"}}}, - {Type: Sum, Name: "system.network.errors", DP: testDP{Ts: now, Int: ptr(int64(2)), Attrs: map[string]any{"device": Device, "direction": "transmit"}}}, + "network": []internal.TestMetric{ + {Type: Sum, Name: "system.network.io", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(1024)), Attrs: map[string]any{"device": Device, "direction": "receive"}}}, + {Type: Sum, Name: "system.network.io", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(2048)), Attrs: map[string]any{"device": Device, "direction": "transmit"}}}, + {Type: Sum, Name: "system.network.packets", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(11)), Attrs: map[string]any{"device": Device, "direction": "receive"}}}, + {Type: Sum, Name: "system.network.packets", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(9)), Attrs: map[string]any{"device": Device, "direction": "transmit"}}}, + {Type: Sum, Name: "system.network.dropped", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(3)), Attrs: map[string]any{"device": Device, "direction": "receive"}}}, + {Type: Sum, Name: "system.network.dropped", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(4)), Attrs: map[string]any{"device": Device, "direction": "transmit"}}}, + {Type: Sum, Name: "system.network.errors", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(1)), Attrs: map[string]any{"device": Device, "direction": "receive"}}}, + {Type: Sum, Name: "system.network.errors", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(2)), Attrs: map[string]any{"device": Device, "direction": "transmit"}}}, }, } @@ -374,7 +375,7 @@ func BenchmarkRemap(b *testing.B) { for scraper, m := range in { sm := pmetric.NewScopeMetrics() sm.Scope().SetName(fmt.Sprintf("%s/%s", scopePrefix, scraper)) - testMetricToMetricSlice(b, m, sm.Metrics()) + internal.TestMetricToMetricSlice(b, m, sm.Metrics()) scopeMetrics = append(scopeMetrics, sm) } @@ -389,82 +390,3 @@ func BenchmarkRemap(b *testing.B) { } } } - -type testMetric struct { - Name string - Type pmetric.MetricType - DP testDP -} - -type testDP struct { - Ts pcommon.Timestamp - Dbl *float64 - Int *int64 - Attrs map[string]any -} - -func metricSliceToTestMetric(t *testing.T, ms pmetric.MetricSlice) []testMetric { - testMetrics := make([]testMetric, ms.Len()) - for i := 0; i < ms.Len(); i++ { - m := ms.At(i) - testMetrics[i].Name = m.Name() - testMetrics[i].Type = m.Type() - - var dps pmetric.NumberDataPointSlice - switch m.Type() { - case pmetric.MetricTypeGauge: - dps = m.Gauge().DataPoints() - case pmetric.MetricTypeSum: - dps = m.Sum().DataPoints() - } - - if dps.Len() != 1 { - t.Fatalf("unexpected metric, test is written assuming each metric with a single datapoint") - } - - dp := dps.At(0) - testMetrics[i].DP = testDP{Ts: dp.Timestamp(), Attrs: dp.Attributes().AsRaw()} - switch dp.ValueType() { - case pmetric.NumberDataPointValueTypeInt: - testMetrics[i].DP.Int = ptr(dp.IntValue()) - case pmetric.NumberDataPointValueTypeDouble: - testMetrics[i].DP.Dbl = ptr(dp.DoubleValue()) - } - } - - return testMetrics -} - -func testMetricToMetricSlice(t testing.TB, testMetrics []testMetric, out pmetric.MetricSlice) { - out.EnsureCapacity(len(testMetrics)) - - for _, testm := range testMetrics { - m := out.AppendEmpty() - m.SetName(testm.Name) - - var dps pmetric.NumberDataPointSlice - switch typ := testm.Type; typ { - case pmetric.MetricTypeGauge: - dps = m.SetEmptyGauge().DataPoints() - case pmetric.MetricTypeSum: - dps = m.SetEmptySum().DataPoints() - default: - t.Fatalf("unhandled metric type %s", typ) - } - - dp := dps.AppendEmpty() - dp.SetTimestamp(testm.DP.Ts) - if testm.DP.Int != nil { - dp.SetIntValue(*testm.DP.Int) - } else if testm.DP.Dbl != nil { - dp.SetDoubleValue(*testm.DP.Dbl) - } - if err := dp.Attributes().FromRaw(testm.DP.Attrs); err != nil { - t.Fatalf("failed to copy attributes from test data: %v", err) - } - } -} - -func ptr[T any](v T) *T { - return &v -} diff --git a/remappers/internal/metric.go b/remappers/internal/metric.go index 613b9f2..6c543c5 100644 --- a/remappers/internal/metric.go +++ b/remappers/internal/metric.go @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -package hostmetrics +package internal import ( "github.com/elastic/opentelemetry-lib/remappers/common" diff --git a/remappers/internal/testing.go b/remappers/internal/testing.go new file mode 100644 index 0000000..62e71c7 --- /dev/null +++ b/remappers/internal/testing.go @@ -0,0 +1,104 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package internal + +import ( + "testing" + + "go.opentelemetry.io/collector/pdata/pcommon" + "go.opentelemetry.io/collector/pdata/pmetric" +) + +type TestMetric struct { + DP TestDP + Name string + Type pmetric.MetricType +} + +type TestDP struct { + Dbl *float64 + Int *int64 + Attrs map[string]any + Ts pcommon.Timestamp +} + +func MetricSliceToTestMetric(t *testing.T, ms pmetric.MetricSlice) []TestMetric { + testMetrics := make([]TestMetric, ms.Len()) + for i := 0; i < ms.Len(); i++ { + m := ms.At(i) + testMetrics[i].Name = m.Name() + testMetrics[i].Type = m.Type() + + var dps pmetric.NumberDataPointSlice + switch m.Type() { + case pmetric.MetricTypeGauge: + dps = m.Gauge().DataPoints() + case pmetric.MetricTypeSum: + dps = m.Sum().DataPoints() + } + + if dps.Len() != 1 { + t.Fatalf("unexpected metric, test is written assuming each metric with a single datapoint") + } + + dp := dps.At(0) + testMetrics[i].DP = TestDP{Ts: dp.Timestamp(), Attrs: dp.Attributes().AsRaw()} + switch dp.ValueType() { + case pmetric.NumberDataPointValueTypeInt: + testMetrics[i].DP.Int = Ptr(dp.IntValue()) + case pmetric.NumberDataPointValueTypeDouble: + testMetrics[i].DP.Dbl = Ptr(dp.DoubleValue()) + } + } + + return testMetrics +} + +func TestMetricToMetricSlice(t testing.TB, testMetrics []TestMetric, out pmetric.MetricSlice) { + out.EnsureCapacity(len(testMetrics)) + + for _, testm := range testMetrics { + m := out.AppendEmpty() + m.SetName(testm.Name) + + var dps pmetric.NumberDataPointSlice + switch typ := testm.Type; typ { + case pmetric.MetricTypeGauge: + dps = m.SetEmptyGauge().DataPoints() + case pmetric.MetricTypeSum: + dps = m.SetEmptySum().DataPoints() + default: + t.Fatalf("unhandled metric type %s", typ) + } + + dp := dps.AppendEmpty() + dp.SetTimestamp(testm.DP.Ts) + if testm.DP.Int != nil { + dp.SetIntValue(*testm.DP.Int) + } else if testm.DP.Dbl != nil { + dp.SetDoubleValue(*testm.DP.Dbl) + } + if err := dp.Attributes().FromRaw(testm.DP.Attrs); err != nil { + t.Fatalf("failed to copy attributes from test data: %v", err) + } + } +} + +func Ptr[T any](v T) *T { + return &v +} diff --git a/remappers/kubernetesmetrics/clustermetrics.go b/remappers/kubernetesmetrics/clustermetrics.go new file mode 100644 index 0000000..acf9c92 --- /dev/null +++ b/remappers/kubernetesmetrics/clustermetrics.go @@ -0,0 +1,69 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package kubernetesmetrics + +import ( + remappers "github.com/elastic/opentelemetry-lib/remappers/internal" + + "go.opentelemetry.io/collector/pdata/pcommon" + "go.opentelemetry.io/collector/pdata/pmetric" +) + +func addClusterMetrics( + src, out pmetric.MetricSlice, + _ pcommon.Resource, + dataset string, +) error { + var timestamp pcommon.Timestamp + var node_allocatable_memory, node_allocatable_cpu int64 + + // iterate all metrics in the current scope and generate the additional Elastic kubernetes integration metrics + for i := 0; i < src.Len(); i++ { + metric := src.At(i) + if metric.Name() == "k8s.node.allocatable_cpu" { + dp := metric.Gauge().DataPoints().At(0) + if timestamp == 0 { + timestamp = dp.Timestamp() + } + node_allocatable_cpu = dp.IntValue() + } else if metric.Name() == "k8s.node.allocatable_memory" { + dp := metric.Gauge().DataPoints().At(0) + if timestamp == 0 { + timestamp = dp.Timestamp() + } + node_allocatable_memory = dp.IntValue() + } + } + + remappers.AddMetrics(out, dataset, remappers.EmptyMutator, + remappers.Metric{ + DataType: pmetric.MetricTypeGauge, + Name: "kubernetes.node.cpu.allocatable.cores", + Timestamp: timestamp, + IntValue: &node_allocatable_cpu, + }, + remappers.Metric{ + DataType: pmetric.MetricTypeGauge, + Name: "kubernetes.node.memory.allocatable.bytes", + Timestamp: timestamp, + IntValue: &node_allocatable_memory, + }, + ) + + return nil +} diff --git a/remappers/kubernetesmetrics/config.go b/remappers/kubernetesmetrics/config.go new file mode 100644 index 0000000..ab7c2ea --- /dev/null +++ b/remappers/kubernetesmetrics/config.go @@ -0,0 +1,41 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package kubernetesmetrics + +type config struct { + KubernetesIntegrationDataset bool +} + +// Option allows configuring the behavior of the kubernetes remapper. +type Option func(config) config + +func newConfig(opts ...Option) (cfg config) { + for _, opt := range opts { + cfg = opt(cfg) + } + return cfg +} + +// WithKubernetesIntegrationDataset sets the dataset of the remapped metrics as +// as per the kubernetes integration. Example: kubernetes.pod +func WithKubernetesIntegrationDataset(b bool) Option { + return func(c config) config { + c.KubernetesIntegrationDataset = b + return c + } +} diff --git a/remappers/kubernetesmetrics/config_test.go b/remappers/kubernetesmetrics/config_test.go new file mode 100644 index 0000000..70e9b30 --- /dev/null +++ b/remappers/kubernetesmetrics/config_test.go @@ -0,0 +1,51 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package kubernetesmetrics + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestConfig(t *testing.T) { + for _, tc := range []struct { + name string + opts []Option + expected config + }{ + { + name: "default", + opts: nil, + expected: config{ + KubernetesIntegrationDataset: false, + }, + }, + { + name: "k8s_integration_dataset", + opts: []Option{WithKubernetesIntegrationDataset(true)}, + expected: config{ + KubernetesIntegrationDataset: true, + }, + }, + } { + t.Run(tc.name, func(t *testing.T) { + assert.Equal(t, tc.expected, newConfig(tc.opts...)) + }) + } +} diff --git a/remappers/kubernetesmetrics/k8smetrics.go b/remappers/kubernetesmetrics/k8smetrics.go new file mode 100644 index 0000000..f353374 --- /dev/null +++ b/remappers/kubernetesmetrics/k8smetrics.go @@ -0,0 +1,104 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package kubernetesmetrics + +import ( + "path" + "strings" + + "go.opentelemetry.io/collector/pdata/pcommon" + "go.opentelemetry.io/collector/pdata/pmetric" + "go.uber.org/zap" +) + +var scraperToElasticDataset = map[string]string{ + "kubeletstatsreceiver": "kubernetes.pod", + "k8sclusterreceiver": "kubernetes.node", +} + +type remapFunc func(metrics pmetric.MetricSlice, out pmetric.MetricSlice, resource pcommon.Resource, dataset string) error + +// Remapper maps the OTel Kubernetes to Elastic Kubernetes metrics. These remapped +// metrics power the curated Kibana dashboards. Each datapoint translated using +// the remapper has the `event.processor` attribute set to `kubernetes`. +type Remapper struct { + logger *zap.Logger + cfg config +} + +// NewRemapper creates a new instance of kubernetes remapper. +func NewRemapper(logger *zap.Logger, opts ...Option) *Remapper { + return &Remapper{ + cfg: newConfig(opts...), + logger: logger, + } +} + +var remapFuncs = map[string]remapFunc{ + "kubeletstatsreceiver": addKubeletMetrics, + "k8sclusterreceiver": addClusterMetrics, +} + +// Remap remaps an OTel ScopeMetrics to a list of OTel metrics such that the +// remapped metrics could be trivially converted into Elastic system metrics. +// It accepts the resource attributes to enrich the remapped metrics as per +// Elastic convention. The current remapping logic assumes that each Metric +// in the ScopeMetric will have datapoints for a single timestamp only. The +// remapped metrics are added to the output `MetricSlice`. +func (r *Remapper) Remap( + src pmetric.ScopeMetrics, + out pmetric.MetricSlice, + resource pcommon.Resource, +) { + if !r.Valid(src) { + return + } + + scope := src.Scope() + scraper := path.Base(scope.Name()) + + var dataset string // an empty dataset defers setting dataset to the caller + if r.cfg.KubernetesIntegrationDataset { + var ok bool + dataset, ok = scraperToElasticDataset[scraper] + if !ok { + r.logger.Warn("no dataset defined for scraper", zap.String("scraper", scraper)) + return + } + } + + remapFunc, ok := remapFuncs[scraper] + if !ok { + return + } + + err := remapFunc(src.Metrics(), out, resource, dataset) + if err != nil { + r.logger.Warn( + "failed to remap OTel kubernetes", + zap.String("scope", scope.Name()), + zap.Error(err), + ) + } +} + +// Valid validates a ScopeMetric against the kubernetes metrics remapper requirements. +// Kubernetes remapper only remaps metrics from kubeletstatsreceiver or k8sclusterreceiver. +func (r *Remapper) Valid(sm pmetric.ScopeMetrics) bool { + return strings.HasPrefix(sm.Scope().Name(), "otelcol/kubeletstatsreceiver") || strings.HasPrefix(sm.Scope().Name(), "otelcol/k8sclusterreceiver") +} diff --git a/remappers/kubernetesmetrics/k8smetrics_test.go b/remappers/kubernetesmetrics/k8smetrics_test.go new file mode 100644 index 0000000..59576de --- /dev/null +++ b/remappers/kubernetesmetrics/k8smetrics_test.go @@ -0,0 +1,142 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package kubernetesmetrics + +import ( + "fmt" + "testing" + "time" + + "github.com/elastic/opentelemetry-lib/remappers/common" + "github.com/elastic/opentelemetry-lib/remappers/internal" + "github.com/stretchr/testify/assert" + "go.opentelemetry.io/collector/pdata/pcommon" + "go.opentelemetry.io/collector/pdata/pmetric" + "go.uber.org/zap/zaptest" +) + +var ( + Sum = pmetric.MetricTypeSum + Gauge = pmetric.MetricTypeGauge + scopePrefix = "otelcol/kubeletstatsreceiver" + // Test values to make assertion easier + POD = "pod0" + NAMESPACE = "kube-system" + DEVICE string = "eth0" +) + +func TestRemap(t *testing.T) { + doTestRemap(t, "without_k8s_integration", WithKubernetesIntegrationDataset(false)) + doTestRemap(t, "with_k8s_integration", WithKubernetesIntegrationDataset(true)) +} + +func doTestRemap(t *testing.T, id string, remapOpts ...Option) { + t.Helper() + + kubernetesIntegration := newConfig(remapOpts...).KubernetesIntegrationDataset + outAttr := func(scraper string) map[string]any { + m := map[string]any{"event.module": "elastic/opentelemetry-lib"} + m["service.type"] = "kubernetes" + if kubernetesIntegration { + m[common.DatastreamDatasetLabel] = scraperToElasticDataset[scraper] + } + return m + } + now := pcommon.NewTimestampFromTime(time.Now()) + + for _, tc := range []struct { + name string + scraper string + resourceAttrs map[string]any + input []internal.TestMetric + expected []internal.TestMetric + }{ + { + name: "kubeletstats", + scraper: "kubeletstatsreceiver", + resourceAttrs: map[string]any{ + "k8s.pod.name": POD, + "k8s.namespace.name": NAMESPACE, + "k8s.device": DEVICE, + }, + input: []internal.TestMetric{ + {Type: Gauge, Name: "k8s.pod.cpu_limit_utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.26), Attrs: map[string]any{"k8s.pod.name": POD, "k8s.namespace.name": NAMESPACE}}}, + {Type: Gauge, Name: "k8s.pod.memory_limit_utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.18), Attrs: map[string]any{"k8s.pod.name": "pod0", "k8s.pod.namespace": NAMESPACE}}}, + {Type: Sum, Name: "k8s.pod.network.io", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(1024)), Attrs: map[string]any{"device": DEVICE, "direction": "receive"}}}, + {Type: Sum, Name: "k8s.pod.network.io", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(2048)), Attrs: map[string]any{"device": DEVICE, "direction": "transmit"}}}, + }, + expected: []internal.TestMetric{ + {Type: Gauge, Name: "kubernetes.pod.cpu.usage.limit.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.26), Attrs: outAttr("kubeletstatsreceiver")}}, + {Type: Gauge, Name: "kubernetes.pod.cpu.usage.node.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.0), Attrs: outAttr("kubeletstatsreceiver")}}, + {Type: Gauge, Name: "kubernetes.pod.memory.usage.node.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.0), Attrs: outAttr("kubeletstatsreceiver")}}, + {Type: Gauge, Name: "kubernetes.pod.memory.usage.limit.pct", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.18), Attrs: outAttr("kubeletstatsreceiver")}}, + {Type: Sum, Name: "kubernetes.pod.network.tx.bytes", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(2048)), Attrs: outAttr("kubeletstatsreceiver")}}, + {Type: Sum, Name: "kubernetes.pod.network.rx.bytes", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(1024)), Attrs: outAttr("kubeletstatsreceiver")}}, + {Type: Gauge, Name: "kubernetes.node.cpu.usage.nanocores", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.0), Attrs: outAttr("kubeletstatsreceiver")}}, + {Type: Gauge, Name: "kubernetes.node.memory.usage.bytes", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(0)), Attrs: outAttr("kubeletstatsreceiver")}}, + {Type: Gauge, Name: "kubernetes.node.fs.capacity.bytes", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(0)), Attrs: outAttr("kubeletstatsreceiver")}}, + {Type: Gauge, Name: "kubernetes.node.fs.used.bytes", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(0)), Attrs: outAttr("kubeletstatsreceiver")}}, + }, + }, + } { + t.Run(fmt.Sprintf("%s/%s", tc.name, id), func(t *testing.T) { + sm := pmetric.NewScopeMetrics() + sm.Scope().SetName(fmt.Sprintf("%s/%s", scopePrefix, tc.scraper)) + internal.TestMetricToMetricSlice(t, tc.input, sm.Metrics()) + + resource := pcommon.NewResource() + resource.Attributes().FromRaw(tc.resourceAttrs) + + actual := pmetric.NewMetricSlice() + r := NewRemapper(zaptest.NewLogger(t), remapOpts...) + r.Remap(sm, actual, resource) + assert.Equal(t, tc.expected, internal.MetricSliceToTestMetric(t, actual)) + }) + } +} + +func BenchmarkRemap(b *testing.B) { + now := pcommon.NewTimestampFromTime(time.Now()) + in := map[string][]internal.TestMetric{ + "kubeletstats": []internal.TestMetric{ + {Type: Gauge, Name: "k8s.pod.cpu_limit_utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.26), Attrs: map[string]any{"k8s.pod.name": POD, "k8s.namespace.name": NAMESPACE}}}, + {Type: Gauge, Name: "k8s.pod.memory_limit_utilization", DP: internal.TestDP{Ts: now, Dbl: internal.Ptr(0.18), Attrs: map[string]any{"k8s.pod.name": "pod0", "k8s.pod.namespace": NAMESPACE}}}, + {Type: Sum, Name: "k8s.pod.network.io", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(1024)), Attrs: map[string]any{"device": DEVICE, "direction": "receive"}}}, + {Type: Sum, Name: "k8s.pod.network.io", DP: internal.TestDP{Ts: now, Int: internal.Ptr(int64(2048)), Attrs: map[string]any{"device": DEVICE, "direction": "transmit"}}}, + }, + } + + scopeMetrics := make([]pmetric.ScopeMetrics, 0, len(in)) + for scraper, m := range in { + sm := pmetric.NewScopeMetrics() + sm.Scope().SetName(fmt.Sprintf("%s/%s", scopePrefix, scraper)) + internal.TestMetricToMetricSlice(b, m, sm.Metrics()) + scopeMetrics = append(scopeMetrics, sm) + } + + r := NewRemapper(zaptest.NewLogger(b)) + resource := pcommon.NewResource() + + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + for _, sm := range scopeMetrics { + r.Remap(sm, pmetric.NewMetricSlice(), resource) + } + } +} diff --git a/remappers/kubernetesmetrics/kubelet.go b/remappers/kubernetesmetrics/kubelet.go new file mode 100644 index 0000000..e5016e7 --- /dev/null +++ b/remappers/kubernetesmetrics/kubelet.go @@ -0,0 +1,167 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package kubernetesmetrics + +import ( + "math" + + remappers "github.com/elastic/opentelemetry-lib/remappers/internal" + "go.opentelemetry.io/collector/pdata/pcommon" + "go.opentelemetry.io/collector/pdata/pmetric" +) + +func addKubeletMetrics( + src, out pmetric.MetricSlice, + _ pcommon.Resource, + dataset string, +) error { + var timestamp pcommon.Timestamp + var total_transmited, total_received, node_memory_usage, filesystem_capacity, filesystem_usage int64 + var cpu_limit_utilization, memory_limit_utilization, node_cpu_usage, pod_cpu_usage_node, pod_memory_usage_node float64 + + // iterate all metrics in the current scope and generate the additional Elastic kubernetes integration metrics + //pod + for i := 0; i < src.Len(); i++ { + metric := src.At(i) + // kubernetes.pod.cpu.usage.node.pct and kubernetes.pod.memory.usage.node.pct still needs to be implemented + if metric.Name() == "k8s.pod.cpu_limit_utilization" { + dp := metric.Gauge().DataPoints().At(0) + if timestamp == 0 { + timestamp = dp.Timestamp() + } + cpu_limit_utilization = dp.DoubleValue() + } else if metric.Name() == "k8s.pod.memory_limit_utilization" { + dp := metric.Gauge().DataPoints().At(0) + if timestamp == 0 { + timestamp = dp.Timestamp() + } + memory_limit_utilization = dp.DoubleValue() + } else if metric.Name() == "k8s.pod.network.io" { + dataPoints := metric.Sum().DataPoints() + for j := 0; j < dataPoints.Len(); j++ { + dp := dataPoints.At(j) + if timestamp == 0 { + timestamp = dp.Timestamp() + } + + value := dp.IntValue() + if direction, ok := dp.Attributes().Get("direction"); ok { + switch direction.Str() { + case "receive": + total_received += value + case "transmit": + total_transmited += value + } + } + } + //node + } else if metric.Name() == "k8s.node.cpu.usage" { + dp := metric.Gauge().DataPoints().At(0) + if timestamp == 0 { + timestamp = dp.Timestamp() + } + node_cpu_usage = dp.DoubleValue() * math.Pow10(9) + } else if metric.Name() == "k8s.node.memory.usage" { + dp := metric.Gauge().DataPoints().At(0) + if timestamp == 0 { + timestamp = dp.Timestamp() + } + node_memory_usage = dp.IntValue() + } else if metric.Name() == "k8s.node.filesystem.capacity" { + dp := metric.Gauge().DataPoints().At(0) + if timestamp == 0 { + timestamp = dp.Timestamp() + } + filesystem_capacity = dp.IntValue() + } else if metric.Name() == "k8s.node.filesystem.usage" { + dp := metric.Gauge().DataPoints().At(0) + if timestamp == 0 { + timestamp = dp.Timestamp() + } + filesystem_usage = dp.IntValue() + } + + } + + remappers.AddMetrics(out, dataset, func(dp pmetric.NumberDataPoint) { + dp.Attributes().PutStr("service.type", "kubernetes") + }, + remappers.Metric{ + DataType: pmetric.MetricTypeGauge, + Name: "kubernetes.pod.cpu.usage.limit.pct", + Timestamp: timestamp, + DoubleValue: &cpu_limit_utilization, + }, + remappers.Metric{ + DataType: pmetric.MetricTypeGauge, + Name: "kubernetes.pod.cpu.usage.node.pct", + Timestamp: timestamp, + DoubleValue: &pod_cpu_usage_node, + }, + remappers.Metric{ + DataType: pmetric.MetricTypeGauge, + Name: "kubernetes.pod.memory.usage.node.pct", + Timestamp: timestamp, + DoubleValue: &pod_memory_usage_node, + }, + remappers.Metric{ + DataType: pmetric.MetricTypeGauge, + Name: "kubernetes.pod.memory.usage.limit.pct", + Timestamp: timestamp, + DoubleValue: &memory_limit_utilization, + }, + remappers.Metric{ + DataType: pmetric.MetricTypeSum, + Name: "kubernetes.pod.network.tx.bytes", + Timestamp: timestamp, + IntValue: &total_transmited, + }, + remappers.Metric{ + DataType: pmetric.MetricTypeSum, + Name: "kubernetes.pod.network.rx.bytes", + Timestamp: timestamp, + IntValue: &total_received, + }, + remappers.Metric{ + DataType: pmetric.MetricTypeGauge, + Name: "kubernetes.node.cpu.usage.nanocores", + Timestamp: timestamp, + DoubleValue: &node_cpu_usage, + }, + remappers.Metric{ + DataType: pmetric.MetricTypeGauge, + Name: "kubernetes.node.memory.usage.bytes", + Timestamp: timestamp, + IntValue: &node_memory_usage, + }, + remappers.Metric{ + DataType: pmetric.MetricTypeGauge, + Name: "kubernetes.node.fs.capacity.bytes", + Timestamp: timestamp, + IntValue: &filesystem_capacity, + }, + remappers.Metric{ + DataType: pmetric.MetricTypeGauge, + Name: "kubernetes.node.fs.used.bytes", + Timestamp: timestamp, + IntValue: &filesystem_usage, + }, + ) + + return nil +}