howdy/telemetry/recorder

Recent traces and log lines, held in memory for the dev admin.

let recorder = recorder.new(keep: 200)

let assert Ok(Nil) =
  telemetry.new("acme-web")
  |> telemetry.record(recorder)
  |> telemetry.start

admin.new()
|> admin.telemetry(recorder)

A trace is kept from the moment its root span ends, the request in most cases, until keep newer traces have arrived. Spans whose root never ends here are dropped after a few minutes. The last 2,000 log lines are kept, with the trace they were logged in.

The tables belong to a process that exits with the process that called new, so make the recorder in main.

Types

Something that happened during a span: a log line, an exception.

pub type Event {
  Event(
    name: String,
    at: Int,
    attributes: List(#(String, Value)),
  )
}

Constructors

  • Event(name: String, at: Int, attributes: List(#(String, Value)))
pub type Log {
  Log(
    at: Int,
    level: String,
    message: String,
    trace_id: option.Option(String),
    span_id: option.Option(String),
  )
}

Constructors

pub opaque type Recorder

A finished span. Times are in microseconds: start since the Unix epoch, duration from start to end.

pub type Span {
  Span(
    trace_id: String,
    span_id: String,
    parent_id: option.Option(String),
    name: String,
    kind: trace.Kind,
    start: Int,
    duration: Int,
    attributes: List(#(String, Value)),
    events: List(Event),
    links: List(#(String, String)),
    status: Status,
    scope: String,
  )
}

Constructors

  • Span(
      trace_id: String,
      span_id: String,
      parent_id: option.Option(String),
      name: String,
      kind: trace.Kind,
      start: Int,
      duration: Int,
      attributes: List(#(String, Value)),
      events: List(Event),
      links: List(#(String, String)),
      status: Status,
      scope: String,
    )

    Arguments

    links

    The trace and span ids of the spans this one links to.

    scope

    The library that opened the span, such as howdy or pgo.

pub type Status {
  Unset
  Succeeded
  Failed(message: String)
}

Constructors

  • Unset
  • Succeeded
  • Failed(message: String)

A trace, summarised by its root span.

pub type Trace {
  Trace(root: Span, spans: Int, failed: Int)
}

Constructors

  • Trace(root: Span, spans: Int, failed: Int)
pub type Value {
  Text(String)
  Integer(Int)
  Number(Float)
  Boolean(Bool)
  Many(List(Value))
}

Constructors

  • Text(String)
  • Integer(Int)
  • Number(Float)
  • Boolean(Bool)
  • Many(List(Value))

Values

pub fn attribute(span: Span, key: String) -> option.Option(Value)

The value of the attribute key on span, if it has one.

pub fn clear(recorder: Recorder) -> Nil

Forget every trace and log line.

pub fn logs(recorder: Recorder, trace_id: String) -> List(Log)

The log lines written while the trace with id trace_id ran.

pub fn new(keep keep: Int) -> Recorder

A recorder holding the last keep traces.

pub fn recent_logs(
  recorder: Recorder,
  limit limit: Int,
) -> List(Log)

The last limit log lines, oldest first.

pub fn trace(
  recorder: Recorder,
  trace_id: String,
) -> Result(List(Span), Nil)

Every span of the trace with id trace_id, earliest first.

pub fn traces(
  recorder: Recorder,
  limit limit: Int,
) -> List(Trace)

Up to limit traces, newest first.

pub fn value_to_string(value: Value) -> String

A value as text, the way the admin shows it.

pub fn version(recorder: Recorder) -> Int

A number that goes up whenever a trace is recorded or the recorder is cleared, so a page that polls can tell whether anything changed.

✨ Search Document