tui_logger/
lib.rs

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