• Stars
    star
    217
  • Rank 182,446 (Top 4 %)
  • Language
    Rust
  • License
    MIT License
  • Created over 6 years ago
  • Updated 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Logger and Widget for rust's ratatui crate

Logger with smart widget for the tui and ratatui crate

Build Status dependency status Build examples

Demo of the widget

Demo

Documentation

Documentation

Features

  • Logger implementation for the log crate
  • Logger enable/disable detection via hash table (avoid string compare)
  • Hot logger code only copies enabled log messages with timestamp into a circular buffer
  • Widgets/move_message() retrieve captured log messages from hot circular buffer
  • Lost message detection due to circular buffer
  • Log filtering performed on log record target
  • Simple Widgets to view logs and configure debuglevel per target
  • Logging of enabled logs to file
  • Scrollback in log history
  • Title of target and log pane can be configured
  • slog support, providing a Drain to integrate into your slog infrastructure
  • tracing support
  • Allow configuration of target dependent loglevel specifically for file logging
  • Avoid duplicating of target, module and filename in every log record
  • Simultaneous modification of all targets' display/hot logging loglevel by key command

Smart Widget

Smart widget consists of two widgets. Left is the target selector widget and on the right side the logging messages view scrolling up. The target selector widget can be hidden/shown during runtime via key command. The key command to be provided to the TuiLoggerWidget via transition() function.

The target selector widget looks like this:

widget

It controls:

  • Capturing of log messages by the logger
  • Selection of levels for display in the logging message view

The two columns have the following meaning:

  • Code EWIDT: E stands for Error, W for Warn, Info, Debug and Trace.
    • Inverted characters (EWIDT) are enabled log levels in the view
    • Normal characters show enabled capturing of a log level per target
    • If any of EWIDT are not shown, then the respective log level is not captured
  • Target of the log events can be defined in the log e.g. warn!(target: "demo", "Log message");

Smart Widget Key Commands

|  KEY     | ACTION
|----------|-----------------------------------------------------------|
| h        | Toggles target selector widget hidden/visible
| f        | Toggle focus on the selected target only
| UP       | Select previous target in target selector widget
| DOWN     | Select next target in target selector widget
| LEFT     | Reduce SHOWN (!) log messages by one level
| RIGHT    | Increase SHOWN (!) log messages by one level
| -        | Reduce CAPTURED (!) log messages by one level
| +        | Increase CAPTURED (!) log messages by one level
| PAGEUP   | Enter Page Mode and scroll approx. half page up in log history.
| PAGEDOWN | Only in page mode: scroll 10 events down in log history.
| ESCAPE   | Exit page mode and go back to scrolling mode
| SPACE    | Toggles hiding of targets, which have logfilter set to off

The mapping of key to action has to be done in the application. The respective TuiWidgetEvent has to be provided to TuiWidgetState::transition().

Remark to the page mode: The timestamp of the event at event history's bottom line is used as reference. This means, changing the filters in the EWIDT/focus from the target selector window should work as expected without jumps in the history. The page next/forward advances as per visibility of the events.

Basic usage to initialize logger-system:

#[macro_use]
extern crate log;
//use tui_logger;

fn main() {
    // Early initialization of the logger

    // Set max_log_level to Trace
    tui_logger::init_logger(log::LevelFilter::Trace).unwrap();

    // Set default level for unknown targets to Trace
    tui_logger::set_default_level(log::LevelFilter::Trace);

    // code....
}

For use of the widget please check examples/demo.rs

Demo

The demo does not support another terminal backend besides termion. During build the termion feature of tui needs to be enabled

Run demo with tui and termion:

cargo run --example demo --no-default-features -F tui-rs,examples-tui-termion

or simply:

cargo run --example demo

Run demo with tui and crossterm:

cargo run --example demo --no-default-features -F tui-rs,examples-tui-crossterm

Run demo with ratatui and termion:

cargo run --example demo --no-default-features -F ratatui-support,examples-ratatui-termion

Run demo with ratatui and crossterm:

cargo run --example demo --no-default-features -F ratatui-support,examples-ratatui-crossterm

slog support

tui-logger provides a TuiSlogDrain which implements slog::Drain and will route all records it receives to the tui-logger widget.

Enabled by feature "slog-support"

tracing-subscriber support

tui-logger provides a TuiTracingSubscriberLayer which implements tracing_subscriber::Layer and will collect all events it receives to the tui-logger widget

Enabled by feature "tracing-support"

ratatui support

Enabled by feature "ratatui-support" + disable default-features of tui-logger

Custom filtering

#[macro_use]
extern crate log;
//use tui_logger;
use env_logger;

fn main() {
    // Early initialization of the logger
    let drain = tui_logger::Drain::new();
    // instead of tui_logger::init_logger, we use `env_logger`
    env_logger::Builder::default()
        .format(move |buf, record|
            // patch the env-logger entry through our drain to the tui-logger
            Ok(drain.log(record))
        ).init(); // make this the global logger
    // code....
}

Applications using tui-logger

THANKS TO