Skip to content

[OTLP] Generate Sentry issues based on OTel span exception events #5097

@gregoiredx

Description

@gregoiredx

Problem Statement

Currently, the OpenTelemetry SentrySpanProcessor does not interpret span events at all.

This means that when a span has an exception event attached, there's no issue visible in Sentry when using INSTRUMENTER.OTEL and the OTel Python SDK.

When using the OTel API to record and exception using trace.get_current_span().record_exception(error), it has no effect on Sentry issues, while one would expect it to do something equivalent to sentry_sdk.capture_exception(error).

Solution Brainstorm

In the docs, there's already an idea of what could be done, at least in TypeScript, see https://develop.sentry.dev/sdk/telemetry/traces/opentelemetry/#step-7-define-generatesentryerrorsfromotelspan

In OpenTelemetry, spans can have exception events. These have a stacktrace, message, and type. We want to convert these to Sentry errors and attach them to the trace.

function generateSentryErrorsFromOtelSpan(otelSpan) {
  otelSpan.events.forEach(event => {
    // Only convert exception events to Sentry errors.
    if (event.name !=== 'exception') {
      return;
    }
    const attributes = event.attributes;
    const message = attributes[SemanticAttributes.EXCEPTION_MESSAGE];
    const syntheticError = new Error(message);
    syntheticError.stack = attributes[SemanticAttributes.EXCEPTION_STACKTRACE];
    syntheticError.name = attributes[SemanticAttributes.EXCEPTION_TYPE];
    Sentry.captureException(syntheticError, {
      contexts: {
        otel: {
          attributes: otelSpan.attributes,
          resource: otelSpan.resource.attributes,
        },
        trace: {
          trace_id: otelSpan.spanContext().traceId,
          span_id: otelSpan.spanContext().spanId,
          parent_span_id: otelSpan.parentSpanId,
        },
      },
    });
  });
}

But it's not that easy to transpose in Python since sentry_sdk.capture_exception(error) relies a lot on having an actual exception instance which we don't have in SentrySpanProcessor.on_end(otel_span) where we could generate Sentry issues from OTel span events (we do have the exception type, message, and stacktrace, though).

Metadata

Metadata

Assignees

Projects

Status

No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions