OpentelemetryTelemetry (Opentelemetry Telemetry v1.0.0-beta.4) View Source

OpentelemetryTelemetry provides conveniences for leveraging telemetry events for OpenTelemetry bridge libraries.

OpenTelemetry Contexts

opentelemetry does not automatically set current span context when ending another span. Since telemetry events are executed in separate handlers with no shared context, correlating individual events requires a mechanism to do so. Additionally, when ending telemetry-based spans, the user must set the correct parent context back as the current context. This ensures sibling spans are correctly correlated to the shared parent span.

This library provides helper functions to manage contexts automatically with start_telemetry_span/4, set_current_telemetry_span/2, and end_telemetry_span/2 to give bridge library authors a mechanism for working with these challenges. Once start_telemetry_span/4 or set_current_telemetry_span/2 are called, users can use all of OpenTelemetry as normal. By providing the application tracer id and the event's metadata, the provided span functions will identify and manage span contexts automatically.

Example Telemetry Event Handlers

  def handle_event(_event,
            %{system_time: start_time},
            metadata,
            %{type: :start, tracer_id: tracer_id, span_name: name}) do
    start_opts = %{start_time: start_time}
    OpentelemetryTelemetry.start_telemetry_span(tracer_id, name, metadata, start_opts)
    :ok
  end

  def handle_event(_event,
              %{duration: duration},
              metadata,
              %{type: :stop, tracer_id: tracer_id}) do
      OpentelemetryTelemetry.set_current_telemetry_span(tracer_id, metadata)
      OpenTelemetry.Tracer.set_attribute(:duration, duration)
      OpentelemetryTelemetry.end_telemetry_span(tracer_id, metadata)
      :ok
  end

  def handle_event(_event,
              %{duration: duration},
              %{kind: kind, reason: reason, stacktrace: stacktrace} = metadata,
              %{type: :exception, tracer_id: tracer_id}) do
      ctx = OpentelemetryTelemetry.set_current_telemetry_span(tracer_id, metadata),
      status = Opentelemetry.status(:error, to_string(reason, :utf8))
      OpenTelemetry.Span.record_exception(ctx, kind, reason, stacktrace, [duration: duration])
      OpenTelemetry.Tracer.set_status(status)
      OpentelemetryTelemetry.end_telemetry_span(tracer_id, metadata)
      :ok
    end
  def handle_event(_event, _measurements, _metadata, _config), do: :ok

Limitations

Span contexts are currently stored in the process dictionary, so spans can only be correlated within a single process at this time. This covers the primary use case where library authors have implemented telemetry:with_span or the pattern established in said function. Non-library authors should use opentelemetry directly wherever possible.

If the event_metadata includes a telemetry_span_context (introduced in telemetry v0.4.3), contexts are correlated by the telemetry_span_context id to guarantee the correct otel span context. Span events in earlier versions of telemetry are stored in a stack by tracer_id to lessen the likelihood of inadvertently closing the wrong span.

Link to this section Summary

Types

The parent span ctx for a telemetry-based span. This is what the current span ctx was at the time of starting a telemetry-based span.

A span ctx for a telemetry-based span.

Functions

End a telemetry-based span based on the tracer_id and telemetry event metadata and restore the current ctx to the span's parent ctx.

Set the current span ctx based on the tracer_id and telemetry event metadata.

Link to this section Types

Specs

ctx_set() :: {parent_span_ctx(), telemetry_span_ctx()}

Specs

parent_span_ctx() :: :opentelemetry.span_ctx()

The parent span ctx for a telemetry-based span. This is what the current span ctx was at the time of starting a telemetry-based span.

Specs

telemetry_span_ctx() :: :opentelemetry.span_ctx()

A span ctx for a telemetry-based span.

Link to this section Functions

Link to this function

end_telemetry_span(tracer_id, event_metadata)

View Source

Specs

end_telemetry_span(tracer_id(), :telemetry.event_metadata()) :: :ok

End a telemetry-based span based on the tracer_id and telemetry event metadata and restore the current ctx to the span's parent ctx.

Link to this function

set_current_telemetry_span(tracer_id, event_metadata)

View Source

Specs

set_current_telemetry_span(tracer_id(), :telemetry.event_metadata()) ::
  OpenTelemetry.span_ctx()

Set the current span ctx based on the tracer_id and telemetry event metadata.

Link to this function

start_telemetry_span(tracer_id, span_name, event_metadata, start_opts)

View Source

Specs

Start a telemetry-based span.