module
CQL::Telemetry
Overview
Observability for every statement CQL runs: subscribers receive a QueryEvent
after each one (successful or not), and an optional Tracer wraps the
statement in a span (OpenTelemetry, Dashforge, ...).
CQL::Telemetry.subscribe("metrics") { |event| Log.info { "sql.#{event.operation} #{event.duration.total_milliseconds}ms" } }
CQL::Telemetry.alert_on_slow(200.milliseconds) { |event| Log.warn { "slow query: #{event.sql}" } }
.subscribe_transactions additionally reports Schema#transaction
begin/commit/rollback, and Schema#pool_stats exposes the connection pool.
Parameter values are not included in events unless .capture_params is on,
since they often contain personal data. A subscriber that raises is logged
and never affects the query.
Defined in:
telemetry.crtelemetry/event_queue.cr
Constant Summary
-
Log =
::Log.for(self)
Class Method Summary
-
.alert_on_slow(threshold : Time::Span, name : String = "cql.slow_query", *, async : Bool = false, &block : QueryEvent -> ) : Nil
Calls the block for statements that took at least threshold, off the query's path when async (see
.subscribe). -
.async_queue_capacity : Int32
Events the async queue holds before it drops new ones.
- .async_queue_capacity=(value : Int32)
-
.begin_transaction(adapter : Adapter, nested : Bool) : TransactionObserver | Nil
Publishes Begin and returns the observer that publishes the end of the transaction, or nil (without allocating or reading the clock) when nobody subscribed.
- .capture_params : Bool
- .capture_params=(value : Bool)
-
.current_context : String | Nil
The context set by
.with_contexton the current fiber, if any. -
.dropped_events : Int64
Events the async queue dropped because it was full.
-
.flush(timeout : Time::Span | Nil = nil) : Bool
Waits until async subscribers have handled every event published before it; false on timeout, true without a queue.
-
.log_queries(severity : ::Log::Severity = ::Log::Severity::Debug, name : String = "cql.log", *, async : Bool = false) : Nil
Logs one line per statement, off the query's path when async (see
.subscribe). -
.next_transaction_id : Int64
Process-wide, strictly increasing transaction id.
-
.observe(adapter : Adapter, operation : Symbol, sql : String, params : Array(DB::Any), & : -> T) : T forall T
Runs the block as one observed statement: inside the tracer's span, then reports the event to the subscribers.
- .reset! : Nil
-
.subscribe(name : String, *, async : Bool = false, &block : QueryEvent -> ) : Nil
Registers (or replaces) the subscriber called name, by default called inline after each statement.
-
.subscribe_transactions(name : String, *, async : Bool = false, &block : TransactionEvent -> ) : Nil
Registers (or replaces) the transaction subscriber called name; async works as in
.subscribe. -
.subscribed?(name : String) : Bool
Whether a query or transaction subscriber is registered under name.
- .tracer : Tracer | Nil
- .tracer=(value : Tracer | Nil)
- .unsubscribe(name : String) : Nil
- .unsubscribe_transactions(name : String) : Nil
-
.with_context(context : String, &)
Tags events emitted by the current fiber while the block runs.
Class Method Detail
Calls the block for statements that took at least threshold, off the query's path when async (see .subscribe).
Events the async queue holds before it drops new ones. Set it before the first async subscriber: the queue
is built then and kept until .reset!, which also restores the default.
Publishes Begin and returns the observer that publishes the end of the transaction, or nil (without allocating or reading the clock) when nobody subscribed.
The context set by .with_context on the current fiber, if any.
Waits until async subscribers have handled every event published before it; false on timeout, true without a queue.
Logs one line per statement, off the query's path when async (see .subscribe).
Runs the block as one observed statement: inside the tracer's span, then reports the event to the subscribers.
Registers (or replaces) the subscriber called name, by default called inline after each statement.
An async subscriber runs on one background fiber after the statement returns, fed by a bounded
queue that drops events when full (.dropped_events). On a single Crystal thread this moves its work
out of the query's latency, not out of the CPU; under multi-threading a push to a parked consumer
can cost a scheduler wake.
Registers (or replaces) the transaction subscriber called name; async works as in .subscribe.
Whether a query or transaction subscriber is registered under name.
Tags events emitted by the current fiber while the block runs.