Skip to main content

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}