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 traceid during processing (eg to inject traceid into log, error message,...).
rust
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:
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 traceid 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)
```txt
// basic handmade span far to be compliant with
//opentelemetry-specification/.../database.md
fn makeotelspan(dboperation: &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::tracespan!(
target: tracingopentelemetryinstrumentationsdk::TRACINGTARGET,
"DB request",
db.system = "postgresql",
// db.statement = stmt,
db.operation = dboperation,
otel.name = dboperation, // should be
// 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
] & [OpenTelemetry]axum-tracing-opentelemetry
] middlewares for axum based on [tracing-opentelemetry-instrumentation-sdk
]tonic-tracing-opentelemetry
] middlewares for tonic based on [tracing-opentelemetry-instrumentation-sdk
]