tracing_betterstack/
lib.rs1mod client;
2mod dispatch;
3mod export;
4mod layer;
5
6pub use client::{BetterstackClient, BetterstackClientTrait, BetterstackError};
7pub use export::{ExportConfig, LogDestination};
8pub use layer::{layer, BetterstackLayer};
9
10#[cfg(test)]
11mod tests {
12 use super::*;
13 use std::{env, time::Duration};
14 use tracing_subscriber::{
15 fmt::{self, format::FmtSpan},
16 layer::SubscriberExt,
17 util::SubscriberInitExt,
18 };
19
20 fn init_env() -> Result<(String, String), Box<dyn std::error::Error>> {
21 dotenv::dotenv().ok();
22
23 let token =
24 env::var("BETTERSTACK_SOURCE_TOKEN").map_err(|_| "BETTERSTACK_SOURCE_TOKEN not set")?;
25 let url =
26 env::var("BETTERSTACK_INGEST_URL").map_err(|_| "BETTERSTACK_INGEST_URL not set")?;
27
28 Ok((token, url))
29 }
30
31 fn init_subscriber(token: String, url: String) -> impl tracing::Subscriber {
32 tracing_subscriber::registry()
33 .with(tracing_subscriber::filter::filter_fn(|metadata| {
34 metadata.target().starts_with("tracing_betterstack")
35 }))
36 .with(layer().with_client(token, url, ExportConfig::default()))
37 .with(fmt::Layer::new().with_span_events(FmtSpan::CLOSE))
38 }
39
40 #[test]
41 fn test_export_config() {
42 let config = ExportConfig::default()
43 .with_batch_size(50)
44 .with_interval(Duration::from_secs(10));
45
46 assert_eq!(config.batch_size, 50);
47 assert_eq!(config.interval, Duration::from_secs(10));
48 }
49
50 #[tokio::test]
51 async fn test_basic_initialization() {
52 let (token, url) = match init_env() {
53 Ok(env_vars) => env_vars,
54 Err(e) => {
55 eprintln!("Skipping test: {}", e);
56 return;
57 }
58 };
59
60 let subscriber = init_subscriber(token, url);
61
62 let _guard = subscriber.set_default();
63 tracing::info!(target: "tracing_betterstack::test", "Test log message");
64 tokio::time::sleep(Duration::from_millis(200)).await;
65 }
66
67 #[tokio::test]
68 async fn test_custom_formatting() {
69 let (token, url) = match init_env() {
70 Ok(env_vars) => env_vars,
71 Err(e) => {
72 eprintln!("Skipping test: {}", e);
73 return;
74 }
75 };
76
77 let subscriber = init_subscriber(token, url);
78 let _guard = subscriber.set_default();
79
80 let span = tracing::info_span!(
81 target: "tracing_betterstack::test",
82 "test_span",
83 field = "value"
84 );
85
86 let _span_guard = span.enter();
87 tracing::info!(target: "tracing_betterstack::test", "Test log message with custom format");
88 tokio::time::sleep(Duration::from_millis(200)).await;
89 }
90
91 #[tokio::test]
92 async fn test_batch_behavior() {
93 let (token, url) = match init_env() {
94 Ok(env_vars) => env_vars,
95 Err(e) => {
96 eprintln!("Skipping test: {}", e);
97 return;
98 }
99 };
100
101 let subscriber = init_subscriber(token, url);
102 let _guard = subscriber.set_default();
103
104 tracing::info!(target: "tracing_betterstack::test", "Batch test message 1");
105 tracing::info!(target: "tracing_betterstack::test", "Batch test message 2");
106
107 tokio::time::sleep(Duration::from_millis(600)).await;
108 }
109
110 #[tokio::test]
111 async fn test_interval_flush() {
112 let (token, url) = match init_env() {
113 Ok(env_vars) => env_vars,
114 Err(e) => {
115 eprintln!("Skipping test: {}", e);
116 return;
117 }
118 };
119
120 let subscriber = init_subscriber(token, url);
121 let _guard = subscriber.set_default();
122
123 tracing::info!(target: "tracing_betterstack::test", "Interval flush test message");
124
125 tokio::time::sleep(Duration::from_millis(300)).await;
126 }
127}