1#![deny(warnings)]
2#![warn(unused_extern_crates)]
3#![allow(non_snake_case)]
4use std::fmt::Display;
5use std::str::FromStr;
6
7use num_enum::{IntoPrimitive, TryFromPrimitive};
8use serde::Deserialize;
9use tracing_forest::printer::TestCapturePrinter;
10use tracing_forest::tag::NoTag;
11use tracing_forest::util::*;
12use tracing_forest::Tag;
13use tracing_subscriber::filter::Directive;
14use tracing_subscriber::prelude::*;
15
16pub mod macros;
17pub mod pipeline;
18
19pub use {tracing, tracing_forest, tracing_subscriber};
20
21#[derive(Clone, Copy, Eq, PartialEq, Debug)]
22pub enum LoggerType {
23 TracingForest,
24 OpenTelemetry,
25}
26
27impl LoggerType {
28 pub fn status_code_field(self) -> &'static str {
29 match self {
30 LoggerType::TracingForest => "status_code",
31 LoggerType::OpenTelemetry => "http.response.status_code",
32 }
33 }
34}
35
36pub fn test_init() {
38 let filter = EnvFilter::builder()
39 .with_default_directive(LevelFilter::INFO.into())
41 .from_env_lossy()
42 .add_directive(
44 "escargot=ERROR"
45 .parse()
46 .expect("failed to generate log filter"),
47 )
48 .add_directive("hyper=INFO".parse().expect("failed to generate log filter"));
50
51 let _ = tracing_subscriber::Registry::default()
53 .with(ForestLayer::new(TestCapturePrinter::new(), NoTag).with_filter(filter))
54 .try_init();
55}
56
57pub fn event_tagger(_event: &Event) -> Option<Tag> {
59 None
60}
61
62#[derive(Debug, Clone, Copy, IntoPrimitive, TryFromPrimitive)]
63#[repr(u64)]
64pub enum EventTag {
65 AdminDebug,
66 AdminError,
67 AdminWarn,
68 AdminInfo,
69 RequestError,
70 RequestWarn,
71 RequestInfo,
72 RequestTrace,
73 SecurityCritical,
74 SecurityDebug,
75 SecurityInfo,
76 SecurityAccess,
77 SecurityError,
78 FilterError,
79 FilterWarn,
80 FilterInfo,
81 FilterTrace,
82 PerfTrace,
83}
84
85impl EventTag {
86 pub fn pretty(self) -> &'static str {
87 match self {
88 EventTag::AdminDebug => "admin.debug",
89 EventTag::AdminError => "admin.error",
90 EventTag::AdminWarn => "admin.warn",
91 EventTag::AdminInfo => "admin.info",
92 EventTag::RequestError => "request.error",
93 EventTag::RequestWarn => "request.warn",
94 EventTag::RequestInfo => "request.info",
95 EventTag::RequestTrace => "request.trace",
96 EventTag::SecurityCritical => "security.critical",
97 EventTag::SecurityDebug => "security.debug",
98 EventTag::SecurityInfo => "security.info",
99 EventTag::SecurityAccess => "security.access",
100 EventTag::SecurityError => "security.error",
101 EventTag::FilterError => "filter.error",
102 EventTag::FilterWarn => "filter.warn",
103 EventTag::FilterInfo => "filter.info",
104 EventTag::FilterTrace => "filter.trace",
105 EventTag::PerfTrace => "perf.trace",
106 }
107 }
108
109 pub fn emoji(self) -> &'static str {
110 use EventTag::*;
111 match self {
112 AdminDebug | SecurityDebug => "đ",
113 AdminError | FilterError | RequestError | SecurityError => "đ¨",
114 AdminWarn | FilterWarn | RequestWarn => "â ī¸",
115 AdminInfo | FilterInfo | RequestInfo | SecurityInfo => "âšī¸",
116 RequestTrace | FilterTrace | PerfTrace => "đ",
117 SecurityCritical => "đ",
118 SecurityAccess => "đ",
119 }
120 }
121}
122
123#[derive(Clone, Copy, Deserialize, Debug, Default)]
124pub enum LogLevel {
125 #[default]
126 #[serde(rename = "info")]
127 Info,
128 #[serde(rename = "debug")]
129 Debug,
130 #[serde(rename = "trace")]
131 Trace,
132}
133
134impl FromStr for LogLevel {
135 type Err = &'static str;
136
137 fn from_str(s: &str) -> Result<Self, Self::Err> {
138 match s.to_ascii_lowercase().as_str() {
139 "info" => Ok(LogLevel::Info),
140 "debug" => Ok(LogLevel::Debug),
141 "trace" => Ok(LogLevel::Trace),
142 _ => Err("Must be one of info, debug, trace"),
143 }
144 }
145}
146
147impl Display for LogLevel {
148 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
149 f.write_str(match self {
150 LogLevel::Info => "info",
151 LogLevel::Debug => "debug",
152 LogLevel::Trace => "trace",
153 })
154 }
155}
156
157impl From<LogLevel> for Directive {
158 fn from(value: LogLevel) -> Self {
159 match value {
160 LogLevel::Info => Directive::from(Level::INFO),
161 LogLevel::Debug => Directive::from(Level::DEBUG),
162 LogLevel::Trace => Directive::from(Level::TRACE),
163 }
164 }
165}