Skip to content

Commit ca0feff

Browse files
Add helper functions for metric conversion [awsecscontainermetricsreceiver] (#1089)
This change adds helper functions for converting ECS resources metrics to OT metrics. **Link to tracking Issue:** #457 **Testing:** Unit test added. **Documentation:** README.md
1 parent 3b94b17 commit ca0feff

File tree

13 files changed

+889
-122
lines changed

13 files changed

+889
-122
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// Copyright 2020, OpenTelemetry Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package awsecscontainermetrics
16+
17+
import (
18+
"time"
19+
20+
metricspb "github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1"
21+
resourcepb "github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1"
22+
"go.opentelemetry.io/collector/consumer/consumerdata"
23+
)
24+
25+
// metricDataAccumulator defines the accumulator
26+
type metricDataAccumulator struct {
27+
md []*consumerdata.MetricsData
28+
}
29+
30+
// getMetricsData generates OT Metrics data from task metadata and docker stats
31+
func (acc *metricDataAccumulator) getMetricsData(containerStatsMap map[string]ContainerStats, metadata TaskMetadata) {
32+
33+
taskMetrics := ECSMetrics{}
34+
timestamp := timestampProto(time.Now())
35+
taskResource := taskResource(metadata)
36+
37+
for _, containerMetadata := range metadata.Containers {
38+
stats := containerStatsMap[containerMetadata.DockerID]
39+
containerMetrics := getContainerMetrics(stats)
40+
containerMetrics.MemoryReserved = *containerMetadata.Limits.Memory
41+
containerMetrics.CPUReserved = *containerMetadata.Limits.CPU
42+
43+
containerResource := containerResource(containerMetadata)
44+
for k, v := range taskResource.Labels {
45+
containerResource.Labels[k] = v
46+
}
47+
48+
acc.accumulate(
49+
containerResource,
50+
convertToOCMetrics(ContainerPrefix, containerMetrics, nil, nil, timestamp),
51+
)
52+
53+
aggregateTaskMetrics(&taskMetrics, containerMetrics)
54+
}
55+
56+
// Overwrite Memory limit with task level limit
57+
if metadata.Limits.Memory != nil {
58+
taskMetrics.MemoryReserved = *metadata.Limits.Memory
59+
}
60+
61+
taskMetrics.CPUReserved = taskMetrics.CPUReserved / CPUsInVCpu
62+
63+
// Overwrite CPU limit with task level limit
64+
if metadata.Limits.CPU != nil {
65+
taskMetrics.CPUReserved = *metadata.Limits.CPU
66+
}
67+
68+
acc.accumulate(
69+
taskResource,
70+
convertToOCMetrics(TaskPrefix, taskMetrics, nil, nil, timestamp),
71+
)
72+
}
73+
74+
func (acc *metricDataAccumulator) accumulate(
75+
r *resourcepb.Resource,
76+
m ...[]*metricspb.Metric,
77+
) {
78+
var resourceMetrics []*metricspb.Metric
79+
for _, metrics := range m {
80+
for _, metric := range metrics {
81+
if metric != nil {
82+
resourceMetrics = append(resourceMetrics, metric)
83+
}
84+
}
85+
}
86+
87+
acc.md = append(acc.md, &consumerdata.MetricsData{
88+
Metrics: resourceMetrics,
89+
Resource: r,
90+
})
91+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// Copyright 2020, OpenTelemetry Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package awsecscontainermetrics
16+
17+
import (
18+
"testing"
19+
20+
"github.com/stretchr/testify/require"
21+
"go.opentelemetry.io/collector/consumer/consumerdata"
22+
)
23+
24+
func TestGetMetricsData(t *testing.T) {
25+
v := uint64(1)
26+
f := float64(1.0)
27+
28+
memStats := make(map[string]uint64)
29+
memStats["cache"] = v
30+
31+
mem := MemoryStats{
32+
Usage: &v,
33+
MaxUsage: &v,
34+
Limit: &v,
35+
MemoryReserved: &v,
36+
MemoryUtilized: &v,
37+
Stats: memStats,
38+
}
39+
40+
disk := DiskStats{
41+
IoServiceBytesRecursives: []IoServiceBytesRecursive{
42+
{Op: "Read", Value: &v},
43+
{Op: "Write", Value: &v},
44+
{Op: "Total", Value: &v},
45+
},
46+
}
47+
48+
net := make(map[string]NetworkStats)
49+
net["eth0"] = NetworkStats{
50+
RxBytes: &v,
51+
RxPackets: &v,
52+
RxErrors: &v,
53+
RxDropped: &v,
54+
TxBytes: &v,
55+
TxPackets: &v,
56+
TxErrors: &v,
57+
TxDropped: &v,
58+
}
59+
60+
netRate := NetworkRateStats{
61+
RxBytesPerSecond: &f,
62+
TxBytesPerSecond: &f,
63+
}
64+
65+
percpu := []*uint64{&v, &v}
66+
cpuUsage := CPUUsage{
67+
TotalUsage: &v,
68+
UsageInKernelmode: &v,
69+
UsageInUserMode: &v,
70+
PerCPUUsage: percpu,
71+
}
72+
73+
cpuStats := CPUStats{
74+
CPUUsage: cpuUsage,
75+
OnlineCpus: &v,
76+
SystemCPUUsage: &v,
77+
CPUUtilized: &v,
78+
CPUReserved: &v,
79+
}
80+
containerStats := ContainerStats{
81+
Name: "test",
82+
ID: "001",
83+
Memory: mem,
84+
Disk: disk,
85+
Network: net,
86+
NetworkRate: netRate,
87+
CPU: cpuStats,
88+
}
89+
90+
tm := TaskMetadata{
91+
Cluster: "cluster-1",
92+
TaskARN: "arn:aws:some-value/001",
93+
Family: "task-def-family-1",
94+
Revision: "task-def-version",
95+
Containers: []ContainerMetadata{
96+
{ContainerName: "container-1", DockerID: "001", DockerName: "docker-container-1", Limits: Limit{CPU: &f, Memory: &v}},
97+
},
98+
Limits: Limit{CPU: &f, Memory: &v},
99+
}
100+
101+
cstats := make(map[string]ContainerStats)
102+
cstats["001"] = containerStats
103+
104+
var mds []*consumerdata.MetricsData
105+
acc := metricDataAccumulator{
106+
md: mds,
107+
}
108+
109+
acc.getMetricsData(cstats, tm)
110+
require.Less(t, 0, len(acc.md))
111+
}

receiver/awsecscontainermetricsreceiver/awsecscontainermetrics/constant.go

+43-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,47 @@ const (
2323
AttributeECSTaskRevesion = "ecs.task-definition-version"
2424
AttributeECSServiceName = "ecs.service"
2525

26-
ContainerMetricsLabelLen = 3
27-
TaskMetricsLabelLen = 6
26+
CPUsInVCpu = 1024
27+
BytesInMiB = 1024 * 1024
28+
29+
TaskPrefix = "ecs.task."
30+
ContainerPrefix = "container."
31+
MetricResourceType = "aoc.ecs"
32+
33+
AttributeMemoryUsage = "memory.usage"
34+
AttributeMemoryMaxUsage = "memory.usage.max"
35+
AttributeMemoryLimit = "memory.usage.limit"
36+
AttributeMemoryReserved = "memory.reserved"
37+
AttributeMemoryUtilized = "memory.utilized"
38+
39+
AttributeCPUTotalUsage = "cpu.usage.total"
40+
AttributeCPUKernelModeUsage = "cpu.usage.kernelmode"
41+
AttributeCPUUserModeUsage = "cpu.usage.usermode"
42+
AttributeCPUSystemUsage = "cpu.usage.system"
43+
AttributeCPUCores = "cpu.cores"
44+
AttributeCPUOnlines = "cpu.onlines"
45+
AttributeCPUReserved = "cpu.reserved"
46+
AttributeCPUUtilized = "cpu.utilized"
47+
48+
AttributeNetworkRateRx = "network.rate.rx"
49+
AttributeNetworkRateTx = "network.rate.tx"
50+
51+
AttributeNetworkRxBytes = "network.io.usage.rx_bytes"
52+
AttributeNetworkRxPackets = "network.io.usage.rx_packets"
53+
AttributeNetworkRxErrors = "network.io.usage.rx_errors"
54+
AttributeNetworkRxDropped = "network.io.usage.rx_dropped"
55+
AttributeNetworkTxBytes = "network.io.usage.tx_bytes"
56+
AttributeNetworkTxPackets = "network.io.usage.tx_packets"
57+
AttributeNetworkTxErrors = "network.io.usage.tx_errors"
58+
AttributeNetworkTxDropped = "network.io.usage.tx_dropped"
59+
60+
AttributeStorageRead = "storage.read_bytes"
61+
AttributeStorageWrite = "storage.write_bytes"
62+
63+
UnitBytes = "Bytes"
64+
UnitMegaBytes = "MB"
65+
UnitNanoSecond = "NS"
66+
UnitBytesPerSec = "Bytes/Sec"
67+
UnitCount = "Count"
68+
UnitVCpu = "vCPU"
2869
)

receiver/awsecscontainermetricsreceiver/awsecscontainermetrics/label.go

-72
This file was deleted.

0 commit comments

Comments
 (0)