tonic_debug/lib.rs
1//! # tonic-debug
2//!
3//! A debugging and diagnostics middleware for [tonic](https://github.com/hyperium/tonic)
4//! gRPC servers.
5//!
6//! ## Overview
7//!
8//! Debugging gRPC services built with tonic can be challenging — messages are
9//! binary-encoded protobufs, connection issues are opaque, and the standard
10//! logging often lacks the detail needed to quickly diagnose problems.
11//!
12//! `tonic-debug` solves this by providing:
13//!
14//! - **Human-readable protobuf inspection** — decodes protobuf wire format
15//! without needing `.proto` schemas, showing field numbers, types, and values.
16//! - **Connection lifecycle observability** — tracks connection events (connect,
17//! disconnect, errors) with active/total counters via tower/hyper integration.
18//! - **Structured logging via `tracing`** — all output goes through the
19//! `tracing` crate with structured fields for easy filtering and aggregation.
20//! - **Optional OpenTelemetry export** — enable the `opentelemetry` feature to
21//! forward spans and attributes to your OTel collector.
22//!
23//! ## Quick Start
24//!
25//! ```rust,no_run
26//! use tonic_debug::DebugLayer;
27//!
28//! // Add the debug layer to your tonic server
29//! // tonic::transport::Server::builder()
30//! // .layer(DebugLayer::new())
31//! // .add_service(my_service)
32//! // .serve(addr)
33//! // .await?;
34//! ```
35//!
36//! ## Configuration
37//!
38//! ```rust
39//! use tonic_debug::{DebugLayer, DebugConfig};
40//!
41//! let layer = DebugLayer::with_config(DebugConfig {
42//! log_headers: true,
43//! log_bodies: true,
44//! log_response_frames: true,
45//! max_body_bytes: 8192,
46//! hex_dump: false,
47//! });
48//! ```
49//!
50//! ## Connection Tracking
51//!
52//! ```rust
53//! use tonic_debug::ConnectionMetrics;
54//!
55//! let metrics = ConnectionMetrics::new();
56//! // Use metrics.active_connections(), metrics.total_connections(), etc.
57//! ```
58//!
59//! ## Feature Flags
60//!
61//! | Feature | Description |
62//! |----------------|--------------------------------------------------|
63//! | `opentelemetry`| Adds OpenTelemetry span attributes and export |
64
65pub mod body;
66pub mod connection;
67pub mod inspect;
68pub mod layer;
69#[cfg(feature = "opentelemetry")]
70pub mod otel;
71pub mod service;
72
73// Re-export primary types for ergonomic usage.
74pub use connection::{ConnectionGuard, ConnectionMetrics, ConnectionTrackerLayer};
75pub use layer::{DebugConfig, DebugLayer};
76pub use service::DebugService;
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81
82 #[test]
83 fn test_debug_layer_default() {
84 let layer = DebugLayer::new();
85 // Should compile and create without panicking.
86 let _ = layer;
87 }
88
89 #[test]
90 fn test_debug_layer_builder() {
91 let layer = DebugLayer::new()
92 .log_headers(false)
93 .log_bodies(true)
94 .log_response_frames(false)
95 .max_body_bytes(1024)
96 .hex_dump(true);
97 let _ = layer;
98 }
99
100 #[test]
101 fn test_debug_config_default() {
102 let config = DebugConfig::default();
103 assert!(config.log_headers);
104 assert!(config.log_bodies);
105 assert!(config.log_response_frames);
106 assert_eq!(config.max_body_bytes, 4096);
107 assert!(!config.hex_dump);
108 }
109
110 #[test]
111 fn test_connection_metrics_default() {
112 let metrics = ConnectionMetrics::new();
113 assert_eq!(metrics.active_connections(), 0);
114 assert_eq!(metrics.total_connections(), 0);
115 assert_eq!(metrics.connection_errors(), 0);
116 }
117}