Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(otel): Parse better op/description from otel span where possible (…
…#6084) Based on https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/7422ce2a06337f68a59b552b8c5a2ac125d6bae5/exporter/sentryexporter/sentry_exporter.go#L306, we now try to parse a better `op`/`description` from the otel span data, and update the span accordingly when it ends. Note that we do not do anything for transactions for now.
- Loading branch information
Showing
3 changed files
with
251 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
89 changes: 89 additions & 0 deletions
89
packages/opentelemetry-node/src/utils/parse-otel-span-description.ts
This file contains 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,89 @@ | ||
import { AttributeValue, SpanKind } from '@opentelemetry/api'; | ||
import { Span as OtelSpan } from '@opentelemetry/sdk-trace-base'; | ||
import { SemanticAttributes } from '@opentelemetry/semantic-conventions'; | ||
|
||
interface SpanDescription { | ||
op: string | undefined; | ||
description: string; | ||
} | ||
|
||
/** | ||
* Extract better op/description from an otel span. | ||
* | ||
* Based on https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/7422ce2a06337f68a59b552b8c5a2ac125d6bae5/exporter/sentryexporter/sentry_exporter.go#L306 | ||
* | ||
* @param otelSpan | ||
* @returns Better op/description to use, or undefined | ||
*/ | ||
export function parseSpanDescription(otelSpan: OtelSpan): SpanDescription { | ||
const { attributes, name } = otelSpan; | ||
|
||
// if http.method exists, this is an http request span | ||
const httpMethod = attributes[SemanticAttributes.HTTP_METHOD]; | ||
if (httpMethod) { | ||
return descriptionForHttpMethod(otelSpan, httpMethod); | ||
} | ||
|
||
// If db.type exists then this is a database call span. | ||
const dbSystem = attributes[SemanticAttributes.DB_SYSTEM]; | ||
if (dbSystem) { | ||
return descriptionForDbSystem(otelSpan, dbSystem); | ||
} | ||
|
||
// If rpc.service exists then this is a rpc call span. | ||
const rpcService = attributes[SemanticAttributes.RPC_SERVICE]; | ||
if (rpcService) { | ||
return { | ||
op: 'rpc', | ||
description: name, | ||
}; | ||
} | ||
|
||
// If messaging.system exists then this is a messaging system span. | ||
const messagingSystem = attributes[SemanticAttributes.MESSAGING_SYSTEM]; | ||
if (messagingSystem) { | ||
return { | ||
op: 'message', | ||
description: name, | ||
}; | ||
} | ||
|
||
// If faas.trigger exists then this is a function as a service span. | ||
const faasTrigger = attributes[SemanticAttributes.FAAS_TRIGGER]; | ||
if (faasTrigger) { | ||
return { op: faasTrigger.toString(), description: name }; | ||
} | ||
|
||
return { op: undefined, description: name }; | ||
} | ||
|
||
function descriptionForDbSystem(otelSpan: OtelSpan, _dbSystem: AttributeValue): SpanDescription { | ||
const { attributes, name } = otelSpan; | ||
|
||
// Use DB statement (Ex "SELECT * FROM table") if possible as description. | ||
const statement = attributes[SemanticAttributes.DB_STATEMENT]; | ||
|
||
const description = statement ? statement.toString() : name; | ||
|
||
return { op: 'db', description }; | ||
} | ||
|
||
function descriptionForHttpMethod(otelSpan: OtelSpan, httpMethod: AttributeValue): SpanDescription { | ||
const { name, kind } = otelSpan; | ||
|
||
const opParts = ['http']; | ||
|
||
switch (kind) { | ||
case SpanKind.CLIENT: | ||
opParts.push('client'); | ||
break; | ||
case SpanKind.SERVER: | ||
opParts.push('server'); | ||
break; | ||
} | ||
|
||
// Ex. description="GET /api/users/{user_id}". | ||
const description = `${httpMethod} ${name}`; | ||
|
||
return { op: opParts.join('.'), description }; | ||
} |
This file contains 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