chaincodec_observability/
tracing_setup.rs1use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter};
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct LogConfig {
10 #[serde(default = "default_level")]
12 pub level: String,
13 #[serde(default)]
15 pub components: HashMap<String, String>,
16 #[serde(default)]
18 pub json: bool,
19}
20
21fn default_level() -> String {
22 "info".to_string()
23}
24
25impl Default for LogConfig {
26 fn default() -> Self {
27 Self {
28 level: "info".into(),
29 components: HashMap::new(),
30 json: false,
31 }
32 }
33}
34
35#[derive(Debug, Clone, Serialize, Deserialize, Default)]
37pub struct TracingConfig {
38 #[serde(skip_serializing_if = "Option::is_none")]
40 pub otlp_endpoint: Option<String>,
41 #[serde(default = "default_service_name")]
43 pub service_name: String,
44}
45
46fn default_service_name() -> String {
47 "chaincodec".into()
48}
49
50pub fn init_tracing(config: &LogConfig) {
53 let mut directives = config.level.clone();
55 for (component, level) in &config.components {
56 directives.push_str(&format!(",{}={}", component.replace('-', "_"), level));
57 }
58
59 let filter = EnvFilter::try_new(&directives)
60 .unwrap_or_else(|_| EnvFilter::new("info"));
61
62 if config.json {
63 tracing_subscriber::registry()
64 .with(filter)
65 .with(fmt::layer().json())
66 .init();
67 } else {
68 tracing_subscriber::registry()
69 .with(filter)
70 .with(fmt::layer())
71 .init();
72 }
73}