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 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