# tower-http-opentelemetry
[](https://codeberg.org/skreutz/tower-http-opentelemetry)
[Tower][] middleware to emit conventional [OpenTelemetry][] spans and metrics for HTTP and gRPC requests.
**WARNING**: This project is currently only a proof of concept.
The middleware creates and enters an HTTP span, and records terminated connections.
See `ROADMAP.md` for details.
## Features
The emitted telemetry conforms to the [OpenTelemetry semantic conventions][semconv] 1.44.0.
The middleware works with any [Tower][]-compatible HTTP and gRPC framework, for clients and servers, including:
* [axum][]
* [reqwest][] (by means of [tower-reqwest][])
* [tonic][]
## Examples
The `examples/` directory contains example HTTP and gRPC applications.
Continue reading for a demonstration.
Optionally enter the [Nix][]-powered development shell to install all necessary tools:
```sh
nix develop
```
Run an OpenTelemetry-compatible collector, for example:
* [otel-desktop-viewer][], a graphical explorer
* [otel-tui][], an interactive terminal explorer
* [otel-cli][], a scriptable command-line tool
```sh
# GUI (web-based)
otel-desktop-viewer --host 127.0.0.1
# TUI
otel-tui --host 127.0.0.1
# CLI (OpenTelemetry events and spans only, no logs or metrics)
otel-cli server json --verbose --stdout
```
### HTTP example
The following commands run an [axum][]-powered HTTP server, and a [reqwest][]-powered HTTP client:
```sh
cargo run -p example-axum
cargo run -p example-reqwest
```
The second command should produce three traces, each with four spans:
1. The client's `query` function
1. The client's telemetry middleware span named `GET`
1. The server's telemetry middleware span named `GET /`
1. The server's request handler `home`
The first trace should indicate success, while the second and third trace should indicate connection terminated errors.
Alternatively, query the server using [otel-cli][] and [curl][] for more control:
```sh
export OTEL_EXPORTER_OTLP_ENDPOINT="http://127.0.0.1:4318"
otel-cli exec --name manual_query --fail -- \
curl \
--verbose \
--no-progress-meter \
--header "traceparent: {{traceparent}}" \
http://127.0.0.1:8080/
```
### gRPC example
The following commands run a [tonic][]-powered gRPC server and client:
```sh
cargo run --bin example-tonic-server
cargo run --bin example-tonic-client
```
## Maintenance
This project is actively maintained.
Releases adhere to [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html).
Furthermore, this project strives to follow the [SemVer Compatibility guidelines of The Cargo Book](https://doc.rust-lang.org/cargo/reference/semver.html).
The minimum supported Rust version (MSRV) is the latest stable release.
A minor release may increase the MSRV with no further ado.
The Nix flake is experimental.
## License
This work is dual-licensed under [MIT](LICENSE-MIT) or [Apache License, Version 2.0](LICENSE-APACHE-2.0).
## Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project shall be dual-licensed under [MIT](LICENSE-MIT) or [Apache License, Version 2.0](LICENSE-APACHE-2.0), without any additional terms or conditions.
## Contact
Feel free to [contact](https://www.skreutz.com/contact/) me via email if you want to discuss this project.
## See also
This project was inspired by [tower-http's tracing middleware](https://docs.rs/tower-http/latest/tower_http/trace/index.html).
Feel free to check out the following alternatives to this project:
* [tower-otel][] provides a Tower layer for HTTP and gRPC clients and servers
* [axum-tracing-opentelemetry][] provides a Tower layer specifically for axum-powered HTTP servers, and optionally a Prometheus-compatible metrics endpoint
* [opentelemetry-instrumentation-tower][] provides a Tower layer for HTTP servers
[OpenTelemetry]: https://opentelemetry.io/
[Tower]: https://github.com/tower-rs/tower
[axum-tracing-opentelemetry]: https://github.com/davidB/tracing-opentelemetry-instrumentation-sdk
[axum]: https://github.com/tokio-rs/axum
[curl]: https://curl.se/
[opentelemetry-instrumentation-tower]: https://github.com/open-telemetry/opentelemetry-rust-contrib/tree/main/opentelemetry-instrumentation-tower
[otel-cli]: https://github.com/equinix-labs/otel-cli
[otel-desktop-viewer]: https://github.com/CtrlSpice/otel-desktop-viewer
[otel-tui]: https://github.com/ymtdzzz/otel-tui
[reqwest]: https://github.com/seanmonstar/reqwest
[semconv]: https://opentelemetry.io/docs/specs/semconv/
[tonic]: https://github.com/grpc/grpc-rust
[tower-otel]: https://github.com/mattiapenati/tower-otel
[tower-reqwest]: https://github.com/alekseysidorov/tower-http-client
[Nix]: https://github.com/NixOS/nix