1 unstable release
Uses new Rust 2024
| new 0.1.0 | Mar 11, 2026 |
|---|
#23 in #tonic
55KB
1K
SLoC
tonic-debug
A debugging and diagnostics middleware for tonic gRPC servers.
Problem
Debugging gRPC services built with tonic is hard:
- Messages are binary-encoded protobufs — not human-readable
- Connection issues between clients and servers are opaque
- Standard logging lacks the detail needed to quickly diagnose problems
Solution
tonic-debug is a Tower middleware that slots into your tonic server and provides:
- Human-readable protobuf inspection — decodes protobuf wire format without needing
.protoschemas, showing field numbers, wire types, and values - Connection lifecycle observability — tracks connection events (connect, disconnect, errors) with active/total counters via tower/hyper integration
- Structured logging via
tracing— all output goes through thetracingcrate with structured fields for easy filtering and aggregation - Optional OpenTelemetry export — enable the
opentelemetryfeature flag to forward spans and attributes to your OTel collector
Quick Start
Add tonic-debug to your Cargo.toml:
[dependencies]
tonic-debug = "0.1"
Then add the DebugLayer to your tonic server:
use tonic_debug::DebugLayer;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize tracing (e.g. with tracing-subscriber)
tracing_subscriber::fmt()
.with_env_filter("tonic_debug=debug")
.init();
tonic::transport::Server::builder()
.layer(DebugLayer::new())
.add_service(/* your gRPC service */)
.serve("0.0.0.0:50051".parse()?)
.await?;
Ok(())
}
Configuration
Fine-tune what gets logged using the builder API or DebugConfig:
use tonic_debug::{DebugLayer, DebugConfig};
// Builder API
let layer = DebugLayer::new()
.log_headers(true)
.log_bodies(true)
.log_response_frames(true)
.max_body_bytes(8192)
.hex_dump(false);
// Or use DebugConfig directly
let layer = DebugLayer::with_config(DebugConfig {
log_headers: true,
log_bodies: true,
log_response_frames: true,
max_body_bytes: 8192,
hex_dump: false,
});
| Option | Default | Description |
|---|---|---|
log_headers |
true |
Log request/response headers and custom metadata |
log_bodies |
true |
Log protobuf message contents |
log_response_frames |
true |
Log individual response body frames as they stream |
max_body_bytes |
4096 |
Maximum bytes to capture for body inspection |
hex_dump |
false |
Include hex dump of raw bytes in output |
Connection Tracking
Track client connection lifecycle with ConnectionTrackerLayer:
use tonic_debug::{ConnectionTrackerLayer, ConnectionMetrics};
let metrics = ConnectionMetrics::new();
let connection_layer = ConnectionTrackerLayer::with_metrics(metrics.clone());
// Query metrics at any time
println!("Active: {}", metrics.active_connections());
println!("Total: {}", metrics.total_connections());
println!("Errors: {}", metrics.connection_errors());
Protobuf Inspection
The crate decodes raw protobuf wire format without schemas, producing output like:
gRPC frame (compressed=false, 15 bytes)
field 1 (varint): 42
field 2 (length-delimited): "hello world"
You can also use the inspection utilities directly:
use tonic_debug::inspect;
let data = &[0x08, 0x96, 0x01]; // field 1, varint 150
if let Some(fields) = inspect::decode_protobuf(data) {
for field in &fields {
println!("{}", field);
}
}
Feature Flags
| Feature | Description |
|---|---|
opentelemetry |
Adds OpenTelemetry semantic convention attributes and |
span enrichment via tracing-opentelemetry |
Enable with:
[dependencies]
tonic-debug = { version = "0.1", features = ["opentelemetry"] }
Log Levels
tonic-debug uses the following tracing levels:
| Level | What gets logged |
|---|---|
INFO |
Request/response summary, connection events |
WARN |
Non-OK gRPC status codes |
ERROR |
Connection errors, response body errors |
DEBUG |
Headers, custom metadata, response frames, protobuf fields |
TRACE |
Stream completion summaries |
🏛️ License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
🧩 Contribution
This is a free and open project and lives from contributions of the community.
See our Contribution Guide
Dependencies
~9–13MB
~157K SLoC