tui_logger/lib.rs
1//! # Logger with smart widget for the `tui` and `ratatui` crate
2//!
3//! [](https://deps.rs/repo/github/gin66/tui-logger)
4//! 
5//!
6//!
7//! ## Demo of the widget
8//!
9//! 
10//!
11//! ## Documentation
12//!
13//! [Documentation](https://docs.rs/tui-logger/latest/tui_logger/)
14//!
15//! I have stumbled over an excellent AI-generated description of `tui-logger`, which provides surprisingly deep and (mostly) correct implementation details.
16//! It would have costed me many days to write an equally good description with so many details and diagrams.
17//! This docu can be found [here](https://deepwiki.com/gin66/tui-logger).
18//!
19//! ## Important note for `tui`
20//!
21//! The `tui` crate has been archived and `ratatui` has taken over.
22//! In order to avoid supporting compatibility for an inactive crate,
23//! the v0.9.x releases are the last to support `tui`. In case future bug fixes
24//! are needed, the branch `tui_legacy` has been created to track changes to 0.9.x releases.
25//!
26//! Starting with v0.10 `tui-logger` is `ratatui` only.
27//!
28//! ## Features
29//!
30//! - [X] Logger implementation for the `log` crate
31//! - [X] Logger enable/disable detection via hash table (avoid string compare)
32//! - [X] Hot logger code only copies enabled log messages with timestamp into a circular buffer
33//! - [X] Widgets/move_message() retrieve captured log messages from hot circular buffer
34//! - [X] Lost message detection due to circular buffer
35//! - [X] Log filtering performed on log record target
36//! - [X] Simple Widgets to view logs and configure debuglevel per target
37//! - [X] Logging of enabled logs to file
38//! - [X] Scrollback in log history
39//! - [x] Title of target and log pane can be configured
40//! - [X] `slog` support, providing a Drain to integrate into your `slog` infrastructure
41//! - [X] `tracing` support
42//! - [X] Support to use custom formatter for log events
43//! - [X] Configurable by environment variables
44//! - [ ] Allow configuration of target dependent loglevel specifically for file logging
45//! - [X] Avoid duplicating of module_path and filename in every log record
46//! - [ ] Simultaneous modification of all targets' display/hot logging loglevel by key command
47//!
48//! ## Smart Widget
49//!
50//! Smart widget consists of two widgets. Left is the target selector widget and
51//! on the right side the logging messages view scrolling up. The target selector widget
52//! can be hidden/shown during runtime via key command.
53//! The key command to be provided to the TuiLoggerWidget via transition() function.
54//!
55//! The target selector widget looks like this:
56//!
57//! 
58//!
59//! It controls:
60//!
61//! - Capturing of log messages by the logger
62//! - Selection of levels for display in the logging message view
63//!
64//! The two columns have the following meaning:
65//!
66//! - Code EWIDT: E stands for Error, W for Warn, Info, Debug and Trace.
67//! + Inverted characters (EWIDT) are enabled log levels in the view
68//! + Normal characters show enabled capturing of a log level per target
69//! + If any of EWIDT are not shown, then the respective log level is not captured
70//! - Target of the log events can be defined in the log e.g. `warn!(target: "demo", "Log message");`
71//!
72//! ## Smart Widget Key Commands
73//! ```ignore
74//! | KEY | ACTION
75//! |----------|-----------------------------------------------------------|
76//! | h | Toggles target selector widget hidden/visible
77//! | f | Toggle focus on the selected target only
78//! | UP | Select previous target in target selector widget
79//! | DOWN | Select next target in target selector widget
80//! | LEFT | Reduce SHOWN (!) log messages by one level
81//! | RIGHT | Increase SHOWN (!) log messages by one level
82//! | - | Reduce CAPTURED (!) log messages by one level
83//! | + | Increase CAPTURED (!) log messages by one level
84//! | PAGEUP | Enter Page Mode and scroll approx. half page up in log history.
85//! | PAGEDOWN | Only in page mode: scroll 10 events down in log history.
86//! | ESCAPE | Exit page mode and go back to scrolling mode
87//! | SPACE | Toggles hiding of targets, which have logfilter set to off
88//! ```
89//!
90//! The mapping of key to action has to be done in the application. The respective TuiWidgetEvent
91//! has to be provided to TuiWidgetState::transition().
92//!
93//! Remark to the page mode: The timestamp of the event at event history's bottom line is used as
94//! reference. This means, changing the filters in the EWIDT/focus from the target selector window
95//! should work as expected without jumps in the history. The page next/forward advances as
96//! per visibility of the events.
97//!
98//! ## Basic usage to initialize logger-system:
99//! ```rust
100//! #[macro_use]
101//! extern crate log;
102//! //use tui_logger;
103//!
104//! fn main() {
105//! // Early initialization of the logger
106//!
107//! // Set max_log_level to Trace
108//! tui_logger::init_logger(log::LevelFilter::Trace).unwrap();
109//!
110//! // Set default level for unknown targets to Trace
111//! tui_logger::set_default_level(log::LevelFilter::Trace);
112//!
113//! // code....
114//! }
115//! ```
116//!
117//! For use of the widget please check examples/demo.rs
118//!
119//! ## Demo
120//!
121//! Run demo using termion:
122//!
123//! ```ignore
124//! cargo run --example demo --features termion
125//! ```
126//!
127//! Run demo with crossterm:
128//!
129//! ```ignore
130//! cargo run --example demo --features crossterm
131//! ```
132//!
133//! Run demo using termion and simple custom formatter in bottom right log widget:
134//!
135//! ```ignore
136//! cargo run --example demo --features termion,formatter
137//! ```
138//!
139//! ## Configuration by environment variables
140//!
141//! `tui.logger` uses `env-filter` crate to support configuration by a string or an environment variable.
142//! This is an opt-in by call to one of these two functions.
143//! ```rust
144//! pub fn set_env_filter_from_string(filterstring: &str) {}
145//! pub fn set_env_filter_from_env(env_name: Option<&str>) {}
146//! ```
147//! Default environment variable name is `RUST_LOG`.
148//!
149//! ## `slog` support
150//!
151//! `tui-logger` provides a [`TuiSlogDrain`] which implements `slog::Drain` and will route all records
152//! it receives to the `tui-logger` widget.
153//!
154//! Enabled by feature "slog-support"
155//!
156//! ## `tracing-subscriber` support
157//!
158//! `tui-logger` provides a [`TuiTracingSubscriberLayer`] which implements
159//! `tracing_subscriber::Layer` and will collect all events
160//! it receives to the `tui-logger` widget
161//!
162//! Enabled by feature "tracing-support"
163//!
164//! ## Custom filtering
165//! ```rust
166//! #[macro_use]
167//! extern crate log;
168//! //use tui_logger;
169//! use env_logger;
170//!
171//! fn main() {
172//! // Early initialization of the logger
173//! let drain = tui_logger::Drain::new();
174//! // instead of tui_logger::init_logger, we use `env_logger`
175//! env_logger::Builder::default()
176//! .format(move |buf, record|
177//! // patch the env-logger entry through our drain to the tui-logger
178//! Ok(drain.log(record))
179//! ).init(); // make this the global logger
180//! // code....
181//! }
182//! ```
183//!
184//! ## Custom formatting
185//!
186//! For experts only ! Configure along the lines:
187//! ```ignore
188//! use tui_logger::LogFormatter;
189//!
190//! let formatter = MyLogFormatter();
191//!
192//! TuiLoggerWidget::default()
193//! .block(Block::bordered().title("Filtered TuiLoggerWidget"))
194//! .formatter(formatter)
195//! .state(&filter_state)
196//! .render(left, buf);
197//! ```
198//! The example demo can be invoked to use a custom formatter as example for the bottom right widget.
199//!
200// Enable docsrs doc_cfg - to display non-default feature documentation.
201#![cfg_attr(docsrs, feature(doc_cfg))]
202#[macro_use]
203extern crate lazy_static;
204
205pub use env_filter;
206
207mod circular;
208pub use crate::circular::CircularBuffer;
209
210#[cfg(feature = "slog-support")]
211#[cfg_attr(docsrs, doc(cfg(feature = "slog-support")))]
212mod slog;
213#[cfg(feature = "slog-support")]
214#[cfg_attr(docsrs, doc(cfg(feature = "slog-support")))]
215pub use crate::slog::TuiSlogDrain;
216
217#[cfg(feature = "tracing-support")]
218#[cfg_attr(docsrs, doc(cfg(feature = "tracing-support")))]
219mod tracing_subscriber;
220#[cfg(feature = "tracing-support")]
221#[cfg_attr(docsrs, doc(cfg(feature = "tracing-support")))]
222pub use crate::tracing_subscriber::TuiTracingSubscriberLayer;
223#[doc(no_inline)]
224pub use log::LevelFilter;
225
226mod widget;
227pub use widget::inner::TuiWidgetEvent;
228pub use widget::inner::TuiWidgetState;
229pub use widget::logformatter::LogFormatter;
230pub use widget::smart::TuiLoggerSmartWidget;
231pub use widget::standard::TuiLoggerWidget;
232pub use widget::target::TuiLoggerTargetWidget;
233
234mod config;
235pub use config::LevelConfig;
236
237mod file;
238pub use file::TuiLoggerFile;
239
240mod logger;
241pub use crate::logger::api::*;
242pub use crate::logger::ExtLogRecord;
243pub use crate::logger::TuiLoggerLevelOutput;
244use crate::logger::*;