What this driver reports about itself.
The event names are the sibling's, on purpose
[:typedb, :operation, …], [:typedb, :transaction, …] and
[:typedb, :sign_in, …] are exactly the events TypeDB.Telemetry emits, and
they mean the same things. That is the same argument as the shared
%TypeDB.Error{}: an application that switches transports should keep its
dashboards, and telemetry is precisely the sort of thing that breaks quietly
when it does not.
Both drivers put :transport in the metadata — :grpc here, :http there —
so an application running both can break a metric down by it, and one running
either can ignore it.
| event | emitted for | use it for |
|---|---|---|
[:typedb, :operation, …] | one call into the public API | request rates and latency |
[:typedb, :transaction, …] | one bracketed transaction | how long work holds a transaction |
[:typedb, :sign_in, …] | one sign-in | token churn |
[:typedb, :grpc, :stream, :batch] | one batch of a streamed read | back pressure, and whether it is working |
What is missing, and why
There is no [:typedb, :request, …] here. Over HTTP that span is one attempt
on the wire, and it exists because the driver retries: several spans per call
is the interesting fact. This transport has no per-request retry — a request
lives on a transaction stream whose failure destroys the transaction, so there
is nothing a retry could correctly re-send — and a span per message on the
stream would report the same duration as the operation that contains it.
Emitting it would be noise dressed as parity.
There is no [:typedb, :retry, :exhausted] for the same reason.
[:typedb, :operation, :start | :stop | :exception]
One span per call into the public API: TypeDB.GRPC.query/4,
TypeDB.GRPC.Database.list/2, TypeDB.GRPC.Transaction.commit/2 and so on.
Metadata:
:transport— always:grpc:connection— the connection name:operation— a low-cardinality atom such as:query,:commit,:databases_all. Safe as a metric tag; this is the one to tag on:database— present whenever the call names one:transaction_type—:read,:writeor:schema, where the call has one:queries— how many queries a call carried, onquery_many/3andexecute_many/3:error— theTypeDB.Error, on:stoponly, when the call failed
[:typedb, :transaction, :start | :stop | :exception]
One span per TypeDB.GRPC.Transaction.transaction/5, from opening the
transaction to the commit or close that ends it.
Metadata: :transport, :connection, :database, :type, and on :stop an
:outcome of :commit, :close or :commit_failed, plus :error when
there was one. A block that raises produces :exception.
[:typedb, :sign_in, :start | :stop | :exception]
One span per sign-in. Metadata: :transport, :connection, and :error on
failure.
[:typedb, :grpc, :stream, :batch]
Not a span, and with no counterpart on the other transport: one event per
batch handed to a consumer of TypeDB.GRPC.stream/4.
Measurements: :rows in the batch, and :wait — native time units the
consumer spent waiting for it. Metadata: :transport, :connection and
:database.
It is here because back pressure is invisible otherwise. A :wait near zero
every time means the server is ahead of the consumer and the batch size could
be larger; a :wait that dominates means the consumer is waiting on TypeDB,
which is the shape a healthy streamed read has.
Just show me what it is doing
TypeDB.GRPC.Telemetry.attach_default_logger(:info)
Summary
Functions
Attaches a handler that logs one line per operation, transaction and sign-in.
Removes the handler attach_default_logger/1 installed.
The event prefix for operation spans. The sibling's, deliberately.
The event prefix for sign-in spans.
The event emitted for each batch of a streamed read.
The event prefix for bracketed-transaction spans.
The value this driver puts in :transport.
Functions
@spec attach_default_logger(Logger.level()) :: :ok | {:error, :already_exists}
Attaches a handler that logs one line per operation, transaction and sign-in.
It filters on :transport so that attaching it alongside
TypeDB.Telemetry.attach_default_logger/1 does not log the sibling's spans
twice — they share event names, which is the point, and this is the cost.
@spec detach_default_logger() :: :ok | {:error, :not_found}
Removes the handler attach_default_logger/1 installed.
@spec operation_event() :: [atom()]
The event prefix for operation spans. The sibling's, deliberately.
@spec sign_in_event() :: [atom()]
The event prefix for sign-in spans.
@spec stream_batch_event() :: [atom()]
The event emitted for each batch of a streamed read.
@spec transaction_event() :: [atom()]
The event prefix for bracketed-transaction spans.
@spec transport() :: atom()
The value this driver puts in :transport.