Skip to content

Custom route filter, header propagation, etc #3

@garthk

Description

@garthk

Splitting this one out of #1

  @doc false
  def handle_start(_, _measurements, %{conn: conn}, _config) do
    # TODO: add config for what paths are traced

Users might want to customise:

  • Which paths are traced and which aren't
  • What sample rate to apply, either through a kludge like Provide interim sampling capability in exporter garthk/opentelemetry_honeycomb#5 or some later API-blessed solution
  • How http.client_ip is derived from headers eg. they need RFC 7239 Forwarded as well as X-Forwarded-For
  • How the trace context is derived from headers eg. they need to handle Honeycomb beeline as well as traceparent
  • Their own attributes derived from the conn
  • Other stuff that hasn't occurred to me

Strikes me we could let them do all that with one config item instead of half a dozen:

  • Add a custom_start callback option
  • Expose our attributes making machinery so they can call it to get most of the heavy lifting done for free

Our code would look something like this:

  # our code
  def handle_start(_, _, %{conn: conn}, %{custom_start: custom_start}) do
    custom_start.(conn)
  rescue
    _ -> :any_plans_for_how_to_stop_one_mistake_from_turning_off_tracing_forever?
  end

  @doc "Call `OpenTelemetry.Tracer.start_span/2` with our tracer, not yours."
  def start_span(span_name, start_opts), do:
    OpenTelemetry.Tracer.start_span(span_name, start_opts)

Not hard, and lets them get as custom as they want:

  # their code
  def my_custom_start(conn, start_span) do
    if my_should_trace?(conn) do
      my_propagate_from(conn.req_headers)
      OpentelemetryPlug.start_span(span_name, %{attributes: my_attributes(conn)})
    end
  end

  defp my_should_trace?(conn) do
    # checks the method or route, whatever
  end

  defp my_propagate_from(conn) do
    # calls :ot_propagation.http_extract/1 if it sees a traceparent
    # ensures equivalent if it sees another header
  end

  defp my_attributes(conn) do
    # calls OpentelemetryPlug.default_attributes/1
    # pipes it through Map.merge/2 with some more attributes
  end

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions