-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Transform Processor function set_semconv_span_name()
#43145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
cyrille-leclerc
wants to merge
52
commits into
open-telemetry:main
Choose a base branch
from
cyrille-leclerc:ottl-GetSemConvSpanName
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
52 commits
Select commit
Hold shift + click to select a range
af3293a
OTTL function get_sem_conv_span_name
cyrille-leclerc 3a8d2a6
OTTL function get_sem_conv_span_name
cyrille-leclerc 5bc2e46
Merge branch 'main' into ottl-GetSemConvSpanName
cyrille-leclerc 1d7f81c
Rename OTTL function get_sem_conv_span_name -> get_semconv_span_name
cyrille-leclerc d760120
make generate
cyrille-leclerc 6e64951
OTTL function get_semconv_span_name
cyrille-leclerc b8b2926
OTTL function GetSemconvSpanName()
cyrille-leclerc 999a423
Add docs README
cyrille-leclerc d0e568e
Changelog and better docs
cyrille-leclerc c89ca08
rename file
cyrille-leclerc 8875bd6
Merge branch 'main' into ottl-GetSemConvSpanName
cyrille-leclerc 03947d8
cleanup chlog
cyrille-leclerc e272862
Better docs
cyrille-leclerc 2a3d7a0
OTTL function GetSemconvSpanName()
cyrille-leclerc 2494f08
OTTL function GetSemconvSpanName()
cyrille-leclerc b2a7d5f
Update pkg/ottl/ottlfuncs/README.md
cyrille-leclerc 88fb84e
Merge branch 'main' into ottl-GetSemConvSpanName
cyrille-leclerc 11b1ef8
Fix semconv for DB span names
cyrille-leclerc fcb3cb2
Merge remote-tracking branch 'cyrille-leclerc/ottl-GetSemConvSpanName…
cyrille-leclerc 7f37e56
Fix semconv for DB span names
cyrille-leclerc ccf7557
Merge branch 'main' into ottl-GetSemConvSpanName
cyrille-leclerc 1575830
Convert the OTTL function into a Transform Processor function
cyrille-leclerc 593608e
make gotidy
cyrille-leclerc 917157a
convert function to set_semconv_span_name()
cyrille-leclerc 8d032be
convert function to set_semconv_span_name()
cyrille-leclerc a065750
Fix docs
cyrille-leclerc 497c915
Merge branch 'main' into ottl-GetSemConvSpanName
cyrille-leclerc dedc7cf
Merge branch 'main' into ottl-GetSemConvSpanName
cyrille-leclerc 6fb2373
go tidy
cyrille-leclerc 7f639aa
Refactor code
cyrille-leclerc 5decfcf
Fix lint errors
cyrille-leclerc 751f170
Refactor code
cyrille-leclerc 90fa9ef
Cleanup code
cyrille-leclerc 063dd29
Cleanup code
cyrille-leclerc efbbb97
Cleanup code
cyrille-leclerc 533a766
Merge branch 'open-telemetry:main' into ottl-GetSemConvSpanName
cyrille-leclerc 6e87e07
Better README.md
cyrille-leclerc 9be059e
Merge branch 'main' into ottl-GetSemConvSpanName
cyrille-leclerc 17274db
Better README.md
cyrille-leclerc 7beeb65
Merge remote-tracking branch 'cyrille-leclerc/ottl-GetSemConvSpanName…
cyrille-leclerc 293de9c
Merge branch 'main' into ottl-GetSemConvSpanName
cyrille-leclerc 07a8604
clarify support for older semconv attributes.
cyrille-leclerc 73a844a
Merge branch 'main' into ottl-GetSemConvSpanName
cyrille-leclerc 7620d74
Merge remote-tracking branch 'origin/main' into ottl-GetSemConvSpanName
cyrille-leclerc 9034da3
Fix changelog and improve docs
cyrille-leclerc ff2bf32
Merge remote-tracking branch 'origin/main' into ottl-GetSemConvSpanName
cyrille-leclerc 51f02a3
fix deps bump
cyrille-leclerc bac7386
go mod tidy
cyrille-leclerc df56ef1
Merge branch 'main' into ottl-GetSemConvSpanName
cyrille-leclerc 020aaa4
Merge branch 'main' into ottl-GetSemConvSpanName
cyrille-leclerc e8f38c0
Merge branch 'main' into ottl-GetSemConvSpanName
cyrille-leclerc 9237424
go mod tidy
cyrille-leclerc File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| # Use this changelog template to create an entry for release notes. | ||
|
|
||
| # One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' | ||
| change_type: "enhancement" | ||
|
|
||
| # The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) | ||
| component: "processor/transform" | ||
|
|
||
| # A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). | ||
| note: "New Transform Processor function `set_semconv_span_name()` to overwrite the span name with the semantic conventions for HTTP, RPC, messaging, and database spans." | ||
|
|
||
| # Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. | ||
| issues: [43124] | ||
|
|
||
| # (Optional) One or more lines of additional information to render under the primary note. | ||
| # These lines will be padded with 2 spaces and then inserted directly into the document. | ||
| # Use pipe (|) for multiline entries. | ||
| subtext: | | ||
| In other cases, the original `span.name` is unchanged. | ||
| The primary use of `set_semconv_span_name()` is alongside the | ||
| [Span Metrics Connector](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/spanmetricsconnector) | ||
| to address high-cardinality issues in span metrics when `span.name` does not comply with the OTel requirement | ||
| that span names be low cardinality. | ||
|
|
||
| # If your change doesn't affect end users or the exported elements of any package, | ||
| # you should instead start your pull request title with [chore] or use the "Skip Changelog" label. | ||
| # Optional: The change log or logs in which this entry should be included. | ||
| # e.g. '[user]' or '[user, api]' | ||
| # Include 'user' if the change is relevant to end users. | ||
| # Include 'api' if there is a change to a library API. | ||
| # Default: '[user]' | ||
| change_logs: [user] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
256 changes: 256 additions & 0 deletions
256
processor/transformprocessor/internal/traces/func_set_semconv_span_name.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,256 @@ | ||
| // Copyright The OpenTelemetry Authors | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| package traces // import "github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor/internal/traces" | ||
|
|
||
| import ( | ||
| "context" | ||
| "errors" | ||
| "fmt" | ||
|
|
||
| "go.opentelemetry.io/collector/pdata/pcommon" | ||
| "go.opentelemetry.io/collector/pdata/ptrace" | ||
| "go.opentelemetry.io/otel/attribute" | ||
| semconv "go.opentelemetry.io/otel/semconv/v1.37.0" | ||
|
|
||
| "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" | ||
| "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottlspan" | ||
| ) | ||
|
|
||
| type setSemconvSpanNameArguments struct { | ||
| SemconvVersion string | ||
| OriginalSpanNameAttribute ottl.Optional[string] | ||
| } | ||
|
|
||
| func NewSetSemconvSpanNameFactory() ottl.Factory[ottlspan.TransformContext] { | ||
| return ottl.NewFactory("set_semconv_span_name", &setSemconvSpanNameArguments{}, createSetSemconvSpanNameFunction) | ||
| } | ||
|
|
||
| func createSetSemconvSpanNameFunction(_ ottl.FunctionContext, oArgs ottl.Arguments) (ottl.ExprFunc[ottlspan.TransformContext], error) { | ||
| args, ok := oArgs.(*setSemconvSpanNameArguments) | ||
|
|
||
| if !ok { | ||
| return nil, errors.New("NewSetSemconvSpanNameFactory args must be of type *setSemconvSpanNameArguments") | ||
| } | ||
| semconvVersion := args.SemconvVersion | ||
| originalSpanNameAttribute := args.OriginalSpanNameAttribute | ||
|
|
||
| // Currently only v1.37.0 is supported | ||
| supportedSemconvVersion := "1.37.0" | ||
| if semconvVersion != supportedSemconvVersion { | ||
| return nil, fmt.Errorf("unsupported semconv version: %s, supported version: %s", semconvVersion, supportedSemconvVersion) | ||
| } | ||
|
|
||
| return func(_ context.Context, tCtx ottlspan.TransformContext) (any, error) { | ||
| setSemconvSpanName(originalSpanNameAttribute, tCtx.GetSpan()) | ||
| return nil, nil | ||
| }, nil | ||
| } | ||
|
|
||
| func setSemconvSpanName(originalSpanNameAttribute ottl.Optional[string], span ptrace.Span) { | ||
| originalSpanName := span.Name() | ||
| semConvSpanName := SemconvSpanName(span) | ||
| span.SetName(semConvSpanName) | ||
| if originalSpanName != semConvSpanName && originalSpanNameAttribute.GetOr("") != "" { | ||
| span.Attributes().PutStr(originalSpanNameAttribute.Get(), originalSpanName) | ||
| } | ||
| } | ||
|
|
||
| func SemconvSpanName(span ptrace.Span) string { | ||
| switch span.Kind() { | ||
| case ptrace.SpanKindServer: | ||
| spanName := httpSpanName(span, semconv.HTTPRouteKey) | ||
| if spanName != "" { | ||
| return spanName | ||
| } | ||
| spanName = rpcSpanName(span) | ||
| if spanName != "" { | ||
| return spanName | ||
| } | ||
| spanName = messagingSpanName(span) | ||
| if spanName != "" { | ||
| return spanName | ||
| } | ||
| case ptrace.SpanKindConsumer: | ||
| spanName := messagingSpanName(span) | ||
| if spanName != "" { | ||
| return spanName | ||
| } | ||
| case ptrace.SpanKindClient: | ||
| spanName := httpSpanName(span, semconv.URLTemplateKey) | ||
| if spanName != "" { | ||
| return spanName | ||
| } | ||
| spanName = rpcSpanName(span) | ||
| if spanName != "" { | ||
| return spanName | ||
| } | ||
| spanName = dbSpanName(span) | ||
| if spanName != "" { | ||
| return spanName | ||
| } | ||
| spanName = messagingSpanName(span) | ||
| if spanName != "" { | ||
| return spanName | ||
| } | ||
| case ptrace.SpanKindProducer: | ||
| spanName := messagingSpanName(span) | ||
| if spanName != "" { | ||
| return spanName | ||
| } | ||
| } | ||
| // If no semantic convention defines the span name, default to the original span name | ||
| return span.Name() | ||
| } | ||
|
|
||
| // https://opentelemetry.io/docs/specs/semconv/http/http-spans/ | ||
| func httpSpanName(span ptrace.Span, subject attribute.Key) string { | ||
| if method, ok := attributeValue(span, semconv.HTTPRequestMethodKey, "http.method"); ok { | ||
| if subjectVal, ok := span.Attributes().Get(string(subject)); ok { | ||
| return method.AsString() + " " + subjectVal.AsString() | ||
| } | ||
| return method.AsString() | ||
| } | ||
| return "" | ||
| } | ||
|
|
||
| // https://opentelemetry.io/docs/specs/semconv/rpc/rpc-spans/ | ||
| func rpcSpanName(span ptrace.Span) string { | ||
| if system, ok := span.Attributes().Get(string(semconv.RPCSystemKey)); ok { | ||
| method, okMethod := attributeValue(span, semconv.RPCMethodKey, "rpc.grpc.method") | ||
| service, okService := attributeValue(span, semconv.RPCServiceKey, "rpc.grpc.service") | ||
|
|
||
| if okMethod && okService { | ||
| return service.AsString() + "/" + method.AsString() | ||
| } | ||
| if okMethod { | ||
| return method.AsString() | ||
| } | ||
| if okService { | ||
| return service.AsString() + "/*" | ||
| } | ||
| return system.AsString() | ||
| } | ||
| return "" | ||
| } | ||
|
|
||
| // https://opentelemetry.io/docs/specs/semconv/database/database-spans/ | ||
| func dbSpanName(span ptrace.Span) string { | ||
| if system, ok := attributeValue(span, semconv.DBSystemNameKey, "db.system"); ok { | ||
cyrille-leclerc marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if summary, ok := span.Attributes().Get(string(semconv.DBQuerySummaryKey)); ok { | ||
| return summary.AsString() | ||
| } | ||
| operationName := "" | ||
| if operation, ok := attributeValue(span, semconv.DBOperationNameKey, "db.operation"); ok { | ||
cyrille-leclerc marked this conversation as resolved.
Show resolved
Hide resolved
edmocosta marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| operationName = operation.AsString() | ||
| } | ||
|
|
||
| target := databaseTarget(span) | ||
|
|
||
| if operationName != "" && target != "" { | ||
| return operationName + " " + target | ||
| } | ||
| if operationName != "" { | ||
| return operationName | ||
| } | ||
| if target != "" { | ||
| return target | ||
| } | ||
| return system.AsString() | ||
| } | ||
| return "" | ||
| } | ||
|
|
||
| func databaseTarget(span ptrace.Span) string { | ||
| dbNamespace := "" | ||
| if namespace, ok := attributeValue(span, semconv.DBNamespaceKey, "db.name"); ok { | ||
| dbNamespace = namespace.AsString() | ||
| } | ||
|
|
||
| if collection, ok := span.Attributes().Get(string(semconv.DBCollectionNameKey)); ok { | ||
| if dbNamespace != "" { | ||
| return dbNamespace + "." + collection.AsString() | ||
| } | ||
| return collection.AsString() | ||
| } | ||
|
|
||
| if storedProcedure, ok := span.Attributes().Get(string(semconv.DBStoredProcedureNameKey)); ok { | ||
| if dbNamespace != "" { | ||
| return dbNamespace + "." + storedProcedure.AsString() | ||
| } | ||
| return storedProcedure.AsString() | ||
| } | ||
|
|
||
| if dbNamespace != "" { | ||
| return dbNamespace | ||
| } | ||
|
|
||
| if serverAddress, ok := span.Attributes().Get(string(semconv.ServerAddressKey)); ok { | ||
| if serverPort, ok := span.Attributes().Get(string(semconv.ServerPortKey)); ok { | ||
| return serverAddress.AsString() + ":" + serverPort.AsString() | ||
| } | ||
| return serverAddress.AsString() | ||
| } | ||
| return "" | ||
| } | ||
|
|
||
| // https://opentelemetry.io/docs/specs/semconv/messaging/messaging-spans/#span-name | ||
| func messagingSpanName(span ptrace.Span) string { | ||
| if system, ok := span.Attributes().Get(string(semconv.MessagingSystemKey)); ok { | ||
| operation, okOperation := attributeValue(span, semconv.MessagingOperationNameKey, "messaging.operation") | ||
| destination := messagingDestination(span) | ||
|
|
||
| if okOperation && destination != "" { | ||
| return operation.AsString() + " " + destination | ||
| } | ||
| if destination != "" { | ||
| return destination | ||
| } | ||
| if okOperation { | ||
| return operation.AsString() | ||
| } | ||
| return system.AsString() | ||
| } | ||
| return "" | ||
| } | ||
|
|
||
| // https://opentelemetry.io/docs/specs/semconv/messaging/messaging-spans/#span-name | ||
| func messagingDestination(span ptrace.Span) string { | ||
| if temporaryDestination, ok := span.Attributes().Get(string(semconv.MessagingDestinationTemporaryKey)); ok { | ||
| if temporaryDestination.Bool() { | ||
| return "(temporary)" | ||
| } | ||
| } | ||
| if anonymousDestination, ok := span.Attributes().Get(string(semconv.MessagingDestinationAnonymousKey)); ok { | ||
| // anonymous destinations should also be marked as temporary by the messaging instrumentation | ||
| // double check in case the instrumentation forgot to mark the anonymous destination as temporary | ||
| if anonymousDestination.Bool() { | ||
| return "(anonymous)" | ||
| } | ||
| } | ||
| if destinationTemplate, ok := span.Attributes().Get(string(semconv.MessagingDestinationTemplateKey)); ok { | ||
| return destinationTemplate.AsString() | ||
| } | ||
| if destinationName, ok := attributeValue(span, semconv.MessagingDestinationNameKey, "messaging.destination"); ok { | ||
| return destinationName.AsString() | ||
| } | ||
| if serverAddress, ok := span.Attributes().Get(string(semconv.ServerAddressKey)); ok { | ||
| if serverPort, ok := span.Attributes().Get(string(semconv.ServerPortKey)); ok { | ||
| return serverAddress.AsString() + ":" + serverPort.AsString() | ||
| } | ||
| return serverAddress.AsString() | ||
| } | ||
| return "" | ||
| } | ||
|
|
||
| func attributeValue(span ptrace.Span, name attribute.Key, alias string) (pcommon.Value, bool) { | ||
| if val, ok := span.Attributes().Get(string(name)); ok { | ||
| return val, true | ||
| } | ||
| if alias != "" { | ||
| if val, ok := span.Attributes().Get(alias); ok { | ||
| return val, true | ||
| } | ||
| } | ||
| return pcommon.Value{}, false | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.