Skip to content

Telemetry

The telemetry module provides structured events that monitoring tools can consume. Events carry a name, numeric measurements, and arbitrary metadata.

Emitting an event

gleam
import gleam/dict
import mistweaver/telemetry

telemetry.emit(telemetry.Event(
  name: "myapp.request.stop",
  measurements: dict.from_list([#("duration_ms", 42.0)]),
  metadata: dict.from_list([#("path", dynamic.string("/api/users"))]),
))

Attaching a handler

Handlers are called synchronously when a matching event is emitted. Attach them at startup:

gleam
telemetry.attach("request-logger", "myapp.request.stop", fn(event) {
  let duration =
    dict.get(event.measurements, "duration_ms")
    |> result.unwrap(0.0)
  logging.log(logging.Info, "request finished in " <> float.to_string(duration) <> "ms")
})

Detaching a handler

gleam
telemetry.detach("request-logger")

Event naming convention

Use dot-separated names in the form app.component.action:

NameWhen
myapp.request.startRequest received
myapp.request.stopResponse sent
myapp.db.queryDatabase query completed
myapp.job.startBackground job started
myapp.job.stopBackground job finished

Instrumenting a handler

Wrap a handler to emit start/stop events:

gleam
fn instrumented(c, params) {
  telemetry.emit(Event(name: "myapp.request.start", ...))
  let start = erlang.system_time(erlang.Millisecond)
  let resp = my_handler(c, params)
  let duration = int.to_float(erlang.system_time(erlang.Millisecond) - start)
  telemetry.emit(Event(
    name: "myapp.request.stop",
    measurements: dict.from_list([#("duration_ms", duration)]),
    metadata: dict.new(),
  ))
  resp
}

Released under the Apache 2.0 License.