mochi/telemetry

Types

Summary of telemetry metrics for a request

pub type MetricsSummary {
  MetricsSummary(
    total_duration_ns: Int,
    parse_duration_ns: Int,
    validation_duration_ns: Int,
    field_count: Int,
    error_count: Int,
    slowest_fields: List(#(String, Int)),
  )
}

Constructors

  • MetricsSummary(
      total_duration_ns: Int,
      parse_duration_ns: Int,
      validation_duration_ns: Int,
      field_count: Int,
      error_count: Int,
      slowest_fields: List(#(String, Int)),
    )

    Arguments

    total_duration_ns

    Total execution time in nanoseconds

    parse_duration_ns

    Parse time in nanoseconds

    validation_duration_ns

    Validation time in nanoseconds

    field_count

    Number of fields resolved

    error_count

    Number of errors

    slowest_fields

    Slowest field resolutions (field_key, duration_ns)

Type of GraphQL operation

pub type OperationType {
  Query
  Mutation
  Subscription
}

Constructors

  • Query
  • Mutation
  • Subscription

Configuration for telemetry collection

pub type TelemetryConfig {
  TelemetryConfig(
    enabled: Bool,
    track_fields: Bool,
    track_dataloaders: Bool,
    handler: fn(TelemetryEvent) -> Nil,
  )
}

Constructors

  • TelemetryConfig(
      enabled: Bool,
      track_fields: Bool,
      track_dataloaders: Bool,
      handler: fn(TelemetryEvent) -> Nil,
    )

    Arguments

    enabled

    Whether telemetry is enabled

    track_fields

    Whether to track individual field resolutions (can be expensive)

    track_dataloaders

    Whether to track DataLoader batches

    handler

    Event handler function

Telemetry context that accumulates events during execution

pub type TelemetryContext {
  TelemetryContext(
    config: TelemetryConfig,
    events: List(TelemetryEvent),
    operation_start: option.Option(Int),
    field_timings: dict.Dict(String, #(Int, Int)),
    current_path: List(String),
  )
}

Constructors

  • TelemetryContext(
      config: TelemetryConfig,
      events: List(TelemetryEvent),
      operation_start: option.Option(Int),
      field_timings: dict.Dict(String, #(Int, Int)),
      current_path: List(String),
    )

    Arguments

    config

    Configuration

    events

    Accumulated events (most recent first)

    operation_start

    Start time of the operation

    field_timings

    Field timing data: (parent_type.field_name) -> (start_time, duration)

    current_path

    Current path in the query

Telemetry events emitted during GraphQL execution

pub type TelemetryEvent {
  ParseStart(timestamp: Int)
  ParseEnd(timestamp: Int, success: Bool)
  ValidationStart(timestamp: Int)
  ValidationEnd(timestamp: Int, success: Bool, error_count: Int)
  OperationStart(
    timestamp: Int,
    operation_name: option.Option(String),
    operation_type: OperationType,
  )
  OperationEnd(
    timestamp: Int,
    operation_name: option.Option(String),
    success: Bool,
    error_count: Int,
  )
  FieldResolveStart(
    timestamp: Int,
    field_name: String,
    parent_type: String,
    path: List(String),
  )
  FieldResolveEnd(
    timestamp: Int,
    field_name: String,
    parent_type: String,
    path: List(String),
    success: Bool,
    duration_ns: Int,
  )
  DataLoaderBatch(
    timestamp: Int,
    loader_name: String,
    batch_size: Int,
    duration_ns: Int,
  )
  Custom(
    timestamp: Int,
    name: String,
    data: dict.Dict(String, dynamic.Dynamic),
  )
}

Constructors

  • ParseStart(timestamp: Int)

    Query parsing started

  • ParseEnd(timestamp: Int, success: Bool)

    Query parsing completed

  • ValidationStart(timestamp: Int)

    Query validation started

  • ValidationEnd(timestamp: Int, success: Bool, error_count: Int)

    Query validation completed

  • OperationStart(
      timestamp: Int,
      operation_name: option.Option(String),
      operation_type: OperationType,
    )

    Operation execution started

  • OperationEnd(
      timestamp: Int,
      operation_name: option.Option(String),
      success: Bool,
      error_count: Int,
    )

    Operation execution completed

  • FieldResolveStart(
      timestamp: Int,
      field_name: String,
      parent_type: String,
      path: List(String),
    )

    Field resolution started

  • FieldResolveEnd(
      timestamp: Int,
      field_name: String,
      parent_type: String,
      path: List(String),
      success: Bool,
      duration_ns: Int,
    )

    Field resolution completed

  • DataLoaderBatch(
      timestamp: Int,
      loader_name: String,
      batch_size: Int,
      duration_ns: Int,
    )

    DataLoader batch executed

  • Custom(
      timestamp: Int,
      name: String,
      data: dict.Dict(String, dynamic.Dynamic),
    )

    Custom event

Values

pub fn build_metrics_summary(
  ctx: TelemetryContext,
) -> MetricsSummary

Build a metrics summary from the telemetry context

pub fn build_tracing_extension(
  ctx: TelemetryContext,
) -> dict.Dict(String, dynamic.Dynamic)

Build an Apollo-compatible tracing extension from the telemetry context This can be included in the GraphQL response extensions

pub fn disabled() -> TelemetryConfig

Create a disabled telemetry config

pub fn emit(
  ctx: TelemetryContext,
  event: TelemetryEvent,
) -> TelemetryContext

Emit an event to the telemetry context

pub fn emit_if_present(
  ctx: option.Option(TelemetryContext),
  event: TelemetryEvent,
) -> option.Option(TelemetryContext)

Emit an event if telemetry context is present

pub fn format_duration(ns: Int) -> String

Format duration in nanoseconds to human-readable string

pub fn format_metrics_summary(summary: MetricsSummary) -> String

Format metrics summary to string for logging

pub fn from_option(
  config: option.Option(TelemetryConfig),
) -> option.Option(TelemetryContext)

Create a context from an Option config

pub fn get_timestamp_ns() -> Int

Get current timestamp in nanoseconds (monotonic clock)

pub fn new_context(config: TelemetryConfig) -> TelemetryContext

Create a new telemetry context from config

pub fn record_custom(
  ctx: TelemetryContext,
  name: String,
  data: dict.Dict(String, dynamic.Dynamic),
) -> TelemetryContext

Record a custom event

pub fn record_dataloader_batch(
  ctx: TelemetryContext,
  loader_name: String,
  batch_size: Int,
  duration_ns: Int,
) -> TelemetryContext

Record DataLoader batch execution

pub fn record_field_end(
  ctx: TelemetryContext,
  field_name: String,
  parent_type: String,
  path: List(String),
  success: Bool,
) -> TelemetryContext

Record field resolve end (if field tracking is enabled)

pub fn record_field_start(
  ctx: TelemetryContext,
  field_name: String,
  parent_type: String,
  path: List(String),
) -> TelemetryContext

Record field resolve start (if field tracking is enabled)

pub fn record_operation_end(
  ctx: TelemetryContext,
  operation_name: option.Option(String),
  success: Bool,
  error_count: Int,
) -> TelemetryContext

Record operation end

pub fn record_operation_start(
  ctx: TelemetryContext,
  operation_name: option.Option(String),
  operation_type: OperationType,
) -> TelemetryContext

Record operation start

pub fn record_parse_end(
  ctx: TelemetryContext,
  success: Bool,
) -> TelemetryContext

Record parse end

pub fn record_parse_start(
  ctx: TelemetryContext,
) -> TelemetryContext

Record parse start

pub fn record_validation_end(
  ctx: TelemetryContext,
  success: Bool,
  error_count: Int,
) -> TelemetryContext

Record validation end

pub fn record_validation_start(
  ctx: TelemetryContext,
) -> TelemetryContext

Record validation start

pub fn to_schema_fn(
  config: TelemetryConfig,
) -> fn(schema.SchemaEvent) -> Nil

Convert a TelemetryConfig into a schema.TelemetryFn callback.

This bridges the full telemetry system into the executor’s event callback. Use this with schema.with_telemetry_fn/2 to enable instrumentation:

let config = telemetry.with_handler(fn(event) { echo event })
let ctx = schema.execution_context(user_data)
  |> schema.with_telemetry_fn(telemetry.to_schema_fn(config))
pub fn with_dataloader_tracking(
  config: TelemetryConfig,
) -> TelemetryConfig

Enable DataLoader tracking

pub fn with_field_tracking(
  config: TelemetryConfig,
) -> TelemetryConfig

Enable field-level tracking (can be expensive for large queries)

pub fn with_handler(
  handler: fn(TelemetryEvent) -> Nil,
) -> TelemetryConfig

Create an enabled telemetry config with a handler

pub fn without_field_tracking(
  config: TelemetryConfig,
) -> TelemetryConfig

Disable field-level tracking

Search Document