howdy/trace

Tracing with OpenTelemetry.

Howdy and its packages open a span around each request, database query, remote call and email, and your code can add its own:

import howdy/trace

pub fn checkout(cart: Cart) {
  use <- trace.span("checkout", [trace.int("cart.items", cart.count)])
  ...
}

Nothing is recorded or sent anywhere until an OpenTelemetry SDK is running. Without one every function here does next to nothing, so instrumented code costs almost nothing in an app that does not collect telemetry. Add howdy_telemetry to switch it on; see its docs.

Spans nest by process: a span opened while another is running in the same process becomes its child. Other Gleam libraries built on opentelemetry_api, such as opengleametry, share the same context, so their spans nest under Howdy’s and the other way round. Work handed to another process starts a new trace unless you carry the context across with context and within.

Types

A key and value recorded on a span or event. Use the OpenTelemetry semantic convention names where one fits, such as http.route or db.system.name.

pub opaque type Attribute

A span waiting to be run. Build one with new when you need more than span offers.

pub opaque type Builder

The tracing context of a process, to carry into another process with within.

pub opaque type Context

What a span represents. Tracing backends use it to recognise requests, so the request Howdy serves is a Server span and a call out to another service is a Client span.

pub type Kind {
  Internal
  Server
  Client
  Producer
  Consumer
}

Constructors

  • Internal
  • Server
  • Client
  • Producer
  • Consumer

A reference to another span, usually in another trace, that caused this one: an email sent by a worker links to the request that queued it.

pub opaque type Link

Values

pub fn attributes(
  builder: Builder,
  attributes: List(Attribute),
) -> Builder

Add attributes to the span when it starts. Samplers only see attributes given here, not ones added later with set_attributes.

pub fn bool(key: String, value: Bool) -> Attribute
pub fn context() -> Context

The tracing context of this process.

pub fn continue_from(
  builder: Builder,
  headers: List(#(String, String)),
) -> Builder

Continue the trace described by the traceparent and tracestate headers of an incoming request, if they are there. Header names must be lowercase, as they are in a gleam/http request. Without trace headers the span starts a new trace, or continues the current one.

pub fn event(name: String, attributes: List(Attribute)) -> Nil

Record that something happened at this moment in the current span.

pub fn float(key: String, value: Float) -> Attribute
pub fn inject(
  headers: List(#(String, String)),
) -> List(#(String, String))

Add the current trace’s traceparent and tracestate headers to headers, so a service you call can continue the trace. Returns headers unchanged outside a span.

pub fn int(key: String, value: Int) -> Attribute
pub fn is_recording() -> Bool

Whether the current span is being recorded. Use it to skip work that only feeds a span, such as formatting a large attribute.

pub fn kind(builder: Builder, kind: Kind) -> Builder
pub fn link(builder: Builder, link: Link) -> Builder
pub fn link_to(traceparent: String) -> Result(Link, Nil)

A link to the span a traceparent value describes.

pub fn new(name: String) -> Builder

Start building a span called name. It is an Internal span with no attributes until you say otherwise.

pub fn run(builder: Builder, body: fn() -> a) -> a

Run run inside the span and return what it returns.

pub fn set_attributes(attributes: List(Attribute)) -> Nil

Add attributes to the current span. Does nothing outside a span.

pub fn set_error(message: String) -> Nil

Mark the current span as failed, with a short description of what went wrong. A span that panics is marked for you.

pub fn span(
  name: String,
  with: List(Attribute),
  body: fn() -> a,
) -> a

Run run inside a span called name, and return what it returns. The span ends when run returns. If run panics, the panic is recorded on the span, the span is marked as failed, and the panic carries on.

pub fn string(key: String, value: String) -> Attribute
pub fn strings(key: String, values: List(String)) -> Attribute

A list of strings, such as the tags on a message.

pub fn trace_id() -> option.Option(String)

The current trace’s id as 32 lowercase hex characters, if the current span is being recorded. Show it on an error page or in a log line so the trace can be found later.

pub fn traceparent() -> option.Option(String)

The current span as a W3C traceparent header value, if it is being recorded. Store it alongside work queued for later, then link_to it.

pub fn within(context: Context, run: fn() -> a) -> a

Run run in context, typically one captured with context in the process that handed over the work. Spans run opens become children of the span that was current there.

✨ Search Document