tower-http-opentelemetry 0.0.1

Tower middleware to emit conventional OpenTelemetry spans and metrics for HTTP and gRPC requests
Documentation
# tower-http-opentelemetry

[![home](https://img.shields.io/badge/git-repository-blue?logo=git&logoColor=f5f5f5)](https://codeberg.org/skreutz/tower-http-opentelemetry)
<!-- TODO: Enable badges when released on crates.io. -->
<!-- [![crates.io version](https://img.shields.io/crates/v/tower-http-opentelemetry)](https://crates.io/crates/tower-http-opentelemetry) -->
<!-- [![docs.rs](https://img.shields.io/docsrs/tower-http-opentelemetry?label=docs.rs)](https://docs.rs/tower-http-opentelemetry) -->
<!-- ![crates.io license](https://img.shields.io/crates/l/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][]

<!-- TODO: Check compatibility with, and add examples for more HTTP frameworks: hyper, actix-web, and rocket. -->

## 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).
<!-- TODO: Check semver compatibility automatically? -->

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

<!-- Links -->

[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