translator/translate/otel/common/metrics.go (123 lines of code) (raw):
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT
package common
import (
"strings"
"go.opentelemetry.io/collector/confmap"
"github.com/aws/amazon-cloudwatch-agent/internal/metric"
"github.com/aws/amazon-cloudwatch-agent/internal/util/collections"
"github.com/aws/amazon-cloudwatch-agent/translator/translate/metrics/config"
)
const (
dropOriginalWildcard = "*"
)
// Map to support dropping metrics without measurement.
var toDropMap = collections.NewSet("collectd", "statsd", "ethtool")
func GetRollupDimensions(conf *confmap.Conf) [][]string {
key := ConfigKey(MetricsKey, AggregationDimensionsKey)
value := conf.Get(key)
if value == nil {
return nil
}
aggregates, ok := value.([]interface{})
if !ok || !isValidRollupList(aggregates) {
return nil
}
rollup := make([][]string, len(aggregates))
for i, aggregate := range aggregates {
dimensions := aggregate.([]interface{})
rollup[i] = make([]string, len(dimensions))
for j, dimension := range dimensions {
rollup[i][j] = dimension.(string)
}
}
return rollup
}
// isValidRollupList confirms whether the supplied aggregate_dimension is a valid type ([][]string)
func isValidRollupList(aggregates []interface{}) bool {
if len(aggregates) == 0 {
return false
}
for _, aggregate := range aggregates {
if dimensions, ok := aggregate.([]interface{}); ok {
if len(dimensions) != 0 {
for _, dimension := range dimensions {
if _, ok := dimension.(string); !ok {
return false
}
}
}
} else {
return false
}
}
return true
}
func GetDropOriginalMetrics(conf *confmap.Conf) map[string]bool {
key := ConfigKey(MetricsKey, MetricsCollectedKey)
value := conf.Get(key)
if value == nil {
return nil
}
categories := value.(map[string]interface{})
dropOriginalMetrics := make(map[string]bool)
for category := range categories {
realCategoryName := config.GetRealPluginName(category)
measurementCfgKey := ConfigKey(key, category, MeasurementKey)
dropOriginalCfgKey := ConfigKey(key, category, DropOriginalMetricsKey)
/* Drop original metrics does not support procstat since procstat can monitor multiple process
"procstat": [
{
"exe": "W3SVC",
"measurement": [
"pid_count"
]
},
{
"exe": "IISADMIN",
"measurement": [
"pid_count"
]
}]
Therefore, dropping the original metrics can conflict between these two processes (e.g customers can drop pid_count with the first
process but not the second process)
*/
if dropMetrics := GetArray[any](conf, dropOriginalCfgKey); dropMetrics != nil {
for _, dropMetric := range dropMetrics {
if _, in := toDropMap[category]; in {
dropMetricStr, ok := dropMetric.(string)
if ok {
dropOriginalMetrics[dropMetricStr] = true
}
continue
}
measurements := GetArray[any](conf, measurementCfgKey)
if measurements == nil {
continue
}
dropMetricStr, ok := dropMetric.(string)
if !ok {
continue
}
if !strings.Contains(dropMetricStr, category) && dropMetricStr != dropOriginalWildcard {
dropMetricStr = metric.DecorateMetricName(realCategoryName, dropMetricStr)
}
isMetricDecoration := false
for _, measurement := range measurements {
switch val := measurement.(type) {
/*
"disk": {
"measurement": [
{
"name": "free",
"rename": "DISK_FREE",
"unit": "unit"
}
]
}
*/
case map[string]interface{}:
metricName, ok := val["name"].(string)
if !ok {
continue
}
if !strings.Contains(metricName, category) {
metricName = metric.DecorateMetricName(realCategoryName, metricName)
}
// If customers provides drop_original_metrics with a wildcard (*), adding the renamed metric or add the original metric
// if customers only re-unit the metric
if strings.Contains(dropMetricStr, metricName) || dropMetricStr == dropOriginalWildcard {
isMetricDecoration = true
if newMetricName, ok := val["rename"].(string); ok {
dropOriginalMetrics[newMetricName] = true
} else {
dropOriginalMetrics[metricName] = true
}
}
/*
"measurement": ["free"]
*/
case string:
if dropMetricStr != dropOriginalWildcard {
continue
}
metricName := val
if !strings.Contains(metricName, category) {
metricName = metric.DecorateMetricName(realCategoryName, metricName)
}
dropOriginalMetrics[metricName] = true
default:
continue
}
}
if !isMetricDecoration && dropMetricStr != dropOriginalWildcard {
dropOriginalMetrics[dropMetricStr] = true
}
}
}
}
return dropOriginalMetrics
}