receiver/elasticapmreceiver/internal/mappers/intakeV2ToSemConv.go (71 lines of code) (raw):

// 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. // This file contains all the mapping from IntakeV2 fields to OTel Semantic Convention package mappers // import "github.com/elastic/opentelemetry-collector-components/receiver/elasticapmreceiver/internal/mappers" import ( "strings" "github.com/elastic/apm-data/model/modelpb" "go.opentelemetry.io/collector/pdata/pcommon" semconv "go.opentelemetry.io/collector/semconv/v1.27.0" ) // Translates resource attributes from the Elastic APM model to SemConv resource attributes func TranslateToOtelResourceAttributes(event *modelpb.APMEvent, attributes pcommon.Map) { attributes.PutStr(semconv.AttributeServiceName, event.Service.Name) attributes.PutStr(semconv.AttributeServiceVersion, event.Service.Version) if event.Service.Language != nil && event.Service.Language.Name != "" { attributes.PutStr(semconv.AttributeTelemetrySDKLanguage, translateElasticServiceLanguageToOtelSdkLanguage(event.Service.Language.Name)) } attributes.PutStr(semconv.AttributeTelemetrySDKName, "ElasticAPM") if event.Service.Environment != "" { attributes.PutStr(semconv.AttributeDeploymentEnvironmentName, event.Service.Environment) } } // SemConv defines a well known list of values of telemetry.sdk.language: https://opentelemetry.io/docs/specs/semconv/attributes-registry/telemetry/ // The classic Elastic APM Agents report values that may not be in the SemConv well known list. // This method maps those values to the closest SemConv well known value. func translateElasticServiceLanguageToOtelSdkLanguage(language string) string { language_lower_case := strings.ToLower(language) switch language_lower_case { case "c#": return "dotnet" default: return language_lower_case } } // Translates transaction attributes from the Elastic APM model to SemConv attributes func TranslateIntakeV2TransactionToOTelAttributes(event *modelpb.APMEvent, attributes pcommon.Map) { setHttpAttributes(event, attributes) if event.Span.Message != nil { attributes.PutStr(semconv.AttributeMessagingDestinationName, event.Transaction.Message.QueueName) attributes.PutStr(semconv.AttributeMessagingRabbitmqDestinationRoutingKey, event.Transaction.Message.RoutingKey) // This may need to be unified, see AttributeMessagingSystem for spans attributes.PutStr(semconv.AttributeMessagingSystem, event.Service.Framework.Name) } } // Translates span attributes from the Elastic APM model to SemConv attributes func TranslateIntakeV2SpanToOTelAttributes(event *modelpb.APMEvent, attributes pcommon.Map) { if event.Http != nil { setHttpAttributes(event, attributes) if event.Url != nil && event.Url.Full != "" { attributes.PutStr(semconv.AttributeURLFull, event.Url.Full) } } if event.Span.Db != nil { attributes.PutStr(semconv.AttributeDBSystem, event.Span.Db.Type) attributes.PutStr(semconv.AttributeDBNamespace, event.Span.Db.Instance) attributes.PutStr(semconv.AttributeDBQueryText, event.Span.Db.Statement) } if event.Span.Message != nil { // Elastic APM span.subtype does not 100% overlap with https://opentelemetry.io/docs/specs/semconv/attributes-registry/messaging/#messaging-system // E.g. azureservicebus in Elastic APM vs servicebus in SemConv attributes.PutStr(semconv.AttributeMessagingSystem, event.Span.Subtype) // No 100% overlap either attributes.PutStr(semconv.AttributeMessagingOperationName, event.Span.Action) if event.Span.Message.QueueName != "" { attributes.PutStr(semconv.AttributeMessagingDestinationName, event.Span.Message.QueueName) } if event.Span.Message.RoutingKey != "" { attributes.PutStr(semconv.AttributeMessagingRabbitmqDestinationRoutingKey, event.Span.Message.RoutingKey) } } } func setHttpAttributes(event *modelpb.APMEvent, attributes pcommon.Map) { if event.Http != nil { if event.Http.Request != nil { attributes.PutStr(semconv.AttributeHTTPRequestMethod, event.Http.Request.Method) if event.Url != nil && event.Url.Full != "" { attributes.PutStr(semconv.AttributeURLFull, event.Url.Full) } } if event.Http.Response != nil { attributes.PutInt(semconv.AttributeHTTPResponseStatusCode, int64(event.Http.Response.StatusCode)) } } }