| Crates.io | tracing-opentelemetry-instrumentation-sdk |
| lib.rs | tracing-opentelemetry-instrumentation-sdk |
| version | 0.30.0 |
| created_at | 2023-06-28 23:07:01.567876+00 |
| updated_at | 2025-08-25 16:14:28.361818+00 |
| description | A set of helpers to build OpenTelemetry instrumentation based on `tracing` crate. |
| homepage | https://github.com/davidB/tracing-opentelemetry-instrumentation-sdk/tree/main/tracing-opentelemetry-instrumentation-sdk |
| repository | https://github.com/davidB/tracing-opentelemetry-instrumentation-sdk |
| max_upload_size | |
| id | 902829 |
| size | 35,095 |
Provide a set of helpers to build OpenTelemetry instrumentation based on tracing crate, and following the OpenTelemetry Trace Semantic Conventions.
PS: Contributions are welcome (bug report, improvements, features, ...)
Instrumentation on the caller side of a call is composed of steps:
Empty)Instrumentation on the callee side of a call is composed of steps:
Empty)The crates provide helper (or inspiration) to extract/inject context info, start & update span and retrieve context or trace_id during processing (eg to inject trace_id into log, error message,...).
let trace_id = tracing_opentelemetry_instrumentation_sdk::find_current_trace_id();
//json!({ "error" : "xxxxxx", "trace_id": trace_id})
The helpers could be used as is or into middleware build on it (eg: axum-tracing-opentelemetry, tonic-tracing-opentelemetry are middlewares build on top of the helpers provide for http (feature & crate))
tracing-opentelemetry extends tracing to interoperate with OpenTelemetry. But with some constraints:
SpanBuilder) from inside the tracing span.Context (and trace_id) is created on NEW span or inherited from parent span. The parent context can be overwritten after creation, but until then the trace_id is the one from NEW, So tracing's log could report none or not-yet set trace_id on event NEW and the following until update.otel.name, otel.kind, ...tracing's Span should be defined at creation time. So some field are created with value tracing::field::Empty to then being updated.otel::tracing (and level trace), to have a common way to enable / to disableUntil every crates are instrumented
Use tracing::instrumented (no propagation & no update on response)
// basic handmade span far to be compliant with
//[opentelemetry-specification/.../database.md](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.22.0/specification/trace/semantic_conventions/database.md)
fn make_otel_span(db_operation: &str) -> tracing::Span {
// NO parsing of statement to extract information, not recommended by Specification and time-consuming
// warning: providing the statement could leek information
tracing_opentelemetry_instrumentation_sdk::otel_trace_span!(
"DB request",
db.system = "postgresql",
// db.statement = stmt,
db.operation = db_operation,
otel.name = db_operation, // should be <db.operation> <db.name>.<db.sql.table>,
otel.kind = "CLIENT",
otel.status_code = tracing::field::Empty,
)
}
// Insert or update
sqlx::query!(
"INSERT INTO ...",
id,
sub_key,
result,
)
.execute(&*self.pool)
.instrument(make_otel_span("INSERT"))
.await
.map_err(...)?;
init-tracing-opentelemetry to initialize tracing & OpenTelemetryaxum-tracing-opentelemetry middlewares for axum based on tracing-opentelemetry-instrumentation-sdktonic-tracing-opentelemetry middlewares for tonic based on tracing-opentelemetry-instrumentation-sdk