diff --git a/internal/app/ec2/ec2.go b/internal/app/ec2/ec2.go index 902db0c..0f68376 100644 --- a/internal/app/ec2/ec2.go +++ b/internal/app/ec2/ec2.go @@ -7,9 +7,9 @@ import ( aws_ec2 "github.com/aws/aws-sdk-go-v2/service/ec2" aws_ec2_types "github.com/aws/aws-sdk-go-v2/service/ec2/types" + "github.com/qonto/prometheus-rds-exporter/internal/app/trace" converter "github.com/qonto/prometheus-rds-exporter/internal/app/unit" "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" ) @@ -67,7 +67,7 @@ func (e *EC2Fetcher) GetDBInstanceTypeInformation(instanceTypes []string) (Metri _, instanceTypeSpan := tracer.Start(ctx, "collect-ec2-instance-types-metrics") defer instanceTypeSpan.End() - instanceTypeSpan.SetAttributes(attribute.Int("com.qonto.prometheus_rds_exporter.instance-types-count", len(instances))) + instanceTypeSpan.SetAttributes(trace.AWSInstanceTypesCount(int64(len(instances)))) // Remove "db." prefix from instance types instanceTypesToFetch := make([]aws_ec2_types.InstanceType, len(instances)) diff --git a/internal/app/servicequotas/servicequotas.go b/internal/app/servicequotas/servicequotas.go index b08fe2b..f61b6ec 100644 --- a/internal/app/servicequotas/servicequotas.go +++ b/internal/app/servicequotas/servicequotas.go @@ -7,9 +7,9 @@ import ( "fmt" aws_servicequotas "github.com/aws/aws-sdk-go-v2/service/servicequotas" + "github.com/qonto/prometheus-rds-exporter/internal/app/trace" converter "github.com/qonto/prometheus-rds-exporter/internal/app/unit" "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" "golang.org/x/exp/slog" ) @@ -67,7 +67,7 @@ func (s *serviceQuotaFetcher) getQuota(serviceCode string, quotaCode string) (fl _, span := tracer.Start(s.ctx, "get-quota") defer span.End() - span.SetAttributes(attribute.String("com.qonto.prometheus_rds_exporter.aws.quota.service_code", serviceCode), attribute.String("com.qonto.prometheus_rds_exporter.aws.quota.code", quotaCode)) + span.SetAttributes(trace.AWSQuotaServiceCode(serviceCode), trace.AWSQuotaCode(quotaCode)) params := &aws_servicequotas.GetServiceQuotaInput{ ServiceCode: &serviceCode, diff --git a/internal/app/trace/attibute.go b/internal/app/trace/attibute.go new file mode 100644 index 0000000..d1272b8 --- /dev/null +++ b/internal/app/trace/attibute.go @@ -0,0 +1,28 @@ +// Package trace provides OTEL tracing resources +package trace + +import "go.opentelemetry.io/otel/attribute" + +// Attribute Naming convention +// +// Use namespacing to avoid name clashes. Delimit the namespaces using a dot character. For example service.version denotes the service version where service is the namespace and version is an attribute in that namespace. +// For each multi-word dot-delimited component of the attribute name separate the words by underscores (i.e. use snake_case). +// See https://opentelemetry.io/docs/specs/semconv/general/attribute-naming/ + +const ( + AWSServiceCodeOtelKey = attribute.Key("qonto.prometheus_rds_exporter.aws.quota.service_code") + AWSQuotaCodeOtelKey = attribute.Key("qonto.prometheus_rds_exporter.aws.quota.code") + AWSInstanceTypesCountKey = attribute.Key("qonto.prometheus_rds_exporter.aws.instance-types-count") +) + +func AWSQuotaServiceCode(val string) attribute.KeyValue { + return AWSServiceCodeOtelKey.String(val) +} + +func AWSQuotaCode(val string) attribute.KeyValue { + return AWSQuotaCodeOtelKey.String(val) +} + +func AWSInstanceTypesCount(val int64) attribute.KeyValue { + return AWSInstanceTypesCountKey.Int64(val) +} diff --git a/internal/app/trace/attibute_test.go b/internal/app/trace/attibute_test.go new file mode 100644 index 0000000..cf9bed7 --- /dev/null +++ b/internal/app/trace/attibute_test.go @@ -0,0 +1,43 @@ +package trace_test + +import ( + "reflect" + "testing" + + "github.com/qonto/prometheus-rds-exporter/internal/app/trace" + "go.opentelemetry.io/otel/attribute" +) + +func TestOtelKeys(t *testing.T) { + type test struct { + name string + want attribute.KeyValue + key string + value any + } + + tests := []test{ + {"QuotaServiceCode", trace.AWSQuotaServiceCode("unittest"), "qonto.prometheus_rds_exporter.aws.quota.service_code", "unittest"}, + {"QuotaCode", trace.AWSQuotaCode("unittest"), "qonto.prometheus_rds_exporter.aws.quota.code", "unittest"}, + {"InstanceTypesCount", trace.AWSInstanceTypesCount(42), "qonto.prometheus_rds_exporter.aws.instance-types-count", int64(42)}, + } + + for _, tc := range tests { + if !reflect.DeepEqual(string(tc.want.Key), tc.key) { + t.Fatalf("%s: expected key: %v, got: %v", tc.name, tc.want.Key, tc.key) + } + + switch tc.value.(type) { + case string: + if !reflect.DeepEqual(tc.want.Value.AsString(), tc.value) { + t.Fatalf("%s: expected value: %v, got: %v", tc.name, tc.want.Value.AsString(), tc.value) + } + case int64: + if !reflect.DeepEqual(tc.want.Value.AsInt64(), tc.value) { + t.Fatalf("%s: expected value: %v, got: %v", tc.name, tc.want.Value.AsInt64(), tc.value) + } + default: + t.Fatalf("%s: %s type is not implemented. Add it to the test suite", tc.name, reflect.TypeOf(tc.value)) + } + } +}