{"id":13594940,"url":"https://github.com/gin66/tui-logger","last_synced_at":"2025-05-14T20:10:42.491Z","repository":{"id":32442583,"uuid":"133963972","full_name":"gin66/tui-logger","owner":"gin66","description":"Logger and Widget for rust's ratatui crate","archived":false,"fork":false,"pushed_at":"2025-04-22T18:19:16.000Z","size":14685,"stargazers_count":244,"open_issues_count":1,"forks_count":55,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-22T19:37:21.269Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gin66.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-05-18T14:18:14.000Z","updated_at":"2025-04-22T18:19:20.000Z","dependencies_parsed_at":"2023-01-14T21:14:24.675Z","dependency_job_id":"36e0c264-6056-4252-b84d-8ce817e23024","html_url":"https://github.com/gin66/tui-logger","commit_stats":{"total_commits":223,"total_committers":29,"mean_commits":7.689655172413793,"dds":"0.27802690582959644","last_synced_commit":"645be0ce6aa808cbe35224ffb8ac02c3da9f2fba"},"previous_names":[],"tags_count":71,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gin66%2Ftui-logger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gin66%2Ftui-logger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gin66%2Ftui-logger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gin66%2Ftui-logger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gin66","download_url":"https://codeload.github.com/gin66/tui-logger/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254219374,"owners_count":22034397,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T16:01:41.205Z","updated_at":"2025-05-14T20:10:42.485Z","avatar_url":"https://github.com/gin66.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"# tui-logger\n\n\u003c!-- cargo-rdme start --\u003e\n\n## Logger with smart widget for the `tui` and `ratatui` crate\n\n[![dependency status](https://deps.rs/repo/github/gin66/tui-logger/status.svg?service=github\u0026nocache=0_9_1)](https://deps.rs/repo/github/gin66/tui-logger)\n![Build examples](https://github.com/gin66/tui-logger/workflows/Build%20examples/badge.svg?service=github)\n\n\n### Demo of the widget\n\n![Demo](https://github.com/gin66/tui-logger/blob/master/doc/demo_v0.14.4.gif?raw=true)\n\n### Documentation\n\n[Documentation](https://docs.rs/tui-logger/latest/tui_logger/)\n\n### Important note for `tui`\n\nThe `tui` crate has been archived and `ratatui` has taken over.\nIn order to avoid supporting compatibility for an inactive crate,\nthe v0.9.x releases are the last to support `tui`. In case future bug fixes\nare needed, the branch `tui_legacy` has been created to track changes to 0.9.x releases.\n\nStarting with v0.10 `tui-logger` is `ratatui` only.\n\n### Features\n\n- [X] Logger implementation for the `log` crate\n- [X] Logger enable/disable detection via hash table (avoid string compare)\n- [X] Hot logger code only copies enabled log messages with timestamp into a circular buffer\n- [X] Widgets/move_message() retrieve captured log messages from hot circular buffer\n- [X] Lost message detection due to circular buffer\n- [X] Log filtering performed on log record target\n- [X] Simple Widgets to view logs and configure debuglevel per target\n- [X] Logging of enabled logs to file\n- [X] Scrollback in log history\n- [x] Title of target and log pane can be configured\n- [X] `slog` support, providing a Drain to integrate into your `slog` infrastructure\n- [X] `tracing` support\n- [X] Support to use custom formatter for log events\n- [ ] Allow configuration of target dependent loglevel specifically for file logging\n- [X] Avoid duplicating of module_path and filename in every log record\n- [ ] Simultaneous modification of all targets' display/hot logging loglevel by key command\n\n### Smart Widget\n\nSmart widget consists of two widgets. Left is the target selector widget and\non the right side the logging messages view scrolling up. The target selector widget\ncan be hidden/shown during runtime via key command.\nThe key command to be provided to the TuiLoggerWidget via transition() function.\n\nThe target selector widget looks like this:\n\n![widget](https://github.com/gin66/tui-logger/blob/master/doc/example.png?raw=true)\n\nIt controls:\n\n- Capturing of log messages by the logger\n- Selection of levels for display in the logging message view\n\nThe two columns have the following meaning:\n\n- Code EWIDT: E stands for Error, W for Warn, Info, Debug and Trace.\n  + Inverted characters (EWIDT) are enabled log levels in the view\n  + Normal characters show enabled capturing of a log level per target\n  + If any of EWIDT are not shown, then the respective log level is not captured\n- Target of the log events can be defined in the log e.g. `warn!(target: \"demo\", \"Log message\");`\n\n### Smart Widget Key Commands\n```rust\n|  KEY     | ACTION\n|----------|-----------------------------------------------------------|\n| h        | Toggles target selector widget hidden/visible\n| f        | Toggle focus on the selected target only\n| UP       | Select previous target in target selector widget\n| DOWN     | Select next target in target selector widget\n| LEFT     | Reduce SHOWN (!) log messages by one level\n| RIGHT    | Increase SHOWN (!) log messages by one level\n| -        | Reduce CAPTURED (!) log messages by one level\n| +        | Increase CAPTURED (!) log messages by one level\n| PAGEUP   | Enter Page Mode and scroll approx. half page up in log history.\n| PAGEDOWN | Only in page mode: scroll 10 events down in log history.\n| ESCAPE   | Exit page mode and go back to scrolling mode\n| SPACE    | Toggles hiding of targets, which have logfilter set to off\n```\n\nThe mapping of key to action has to be done in the application. The respective TuiWidgetEvent\nhas to be provided to TuiWidgetState::transition().\n\nRemark to the page mode: The timestamp of the event at event history's bottom line is used as\nreference. This means, changing the filters in the EWIDT/focus from the target selector window\nshould work as expected without jumps in the history. The page next/forward advances as\nper visibility of the events.\n\n### Basic usage to initialize logger-system:\n```rust\n#[macro_use]\nextern crate log;\n//use tui_logger;\n\nfn main() {\n    // Early initialization of the logger\n\n    // Set max_log_level to Trace\n    tui_logger::init_logger(log::LevelFilter::Trace).unwrap();\n\n    // Set default level for unknown targets to Trace\n    tui_logger::set_default_level(log::LevelFilter::Trace);\n\n    // code....\n}\n```\n\nFor use of the widget please check examples/demo.rs\n\n### Demo\n\nRun demo using termion:\n\n```rust\ncargo run --example demo --features termion\n```\n\nRun demo with crossterm:\n\n```rust\ncargo run --example demo --features crossterm\n```\n\nRun demo using termion and simple custom formatter in bottom right log widget:\n\n```rust\ncargo run --example demo --features termion,formatter\n```\n\n### `slog` support\n\n`tui-logger` provides a [`TuiSlogDrain`] which implements `slog::Drain` and will route all records\nit receives to the `tui-logger` widget.\n\nEnabled by feature \"slog-support\"\n\n### `tracing-subscriber` support\n\n`tui-logger` provides a [`TuiTracingSubscriberLayer`] which implements\n`tracing_subscriber::Layer` and will collect all events\nit receives to the `tui-logger` widget\n\nEnabled by feature \"tracing-support\"\n\n### Custom filtering\n```rust\n#[macro_use]\nextern crate log;\n//use tui_logger;\nuse env_logger;\n\nfn main() {\n    // Early initialization of the logger\n    let drain = tui_logger::Drain::new();\n    // instead of tui_logger::init_logger, we use `env_logger`\n    env_logger::Builder::default()\n        .format(move |buf, record|\n            // patch the env-logger entry through our drain to the tui-logger\n            Ok(drain.log(record))\n        ).init(); // make this the global logger\n    // code....\n}\n```\n\n### Custom formatting\n\nFor experts only ! Configure along the lines:\n```rust\nuse tui_logger::LogFormatter;\n\nlet formatter = MyLogFormatter();\n\nTuiLoggerWidget::default()\n.block(Block::bordered().title(\"Filtered TuiLoggerWidget\"))\n.formatter(formatter)\n.state(\u0026filter_state)\n.render(left, buf);\n```\nThe example demo can be invoked to use a custom formatter as example for the bottom right widget.\n\n\u003c!-- cargo-rdme end --\u003e\n\n### Internals\n\nFor logging there are two circular buffers in use:\n* \"hot\" buffer, which is written to during any logging macro invocation\n* main buffer, which holds events to be displayed by the widgets.\n\nThe size of the \"hot\" buffer is 1000 and can be modified by `set_hot_buffer_depth()`.\nThe size of the main buffer is 10000 and can be modified by `set_buffer_depth()`.\n\nReason for this scheme: The main buffer is locked for a while during widget updates.\nIn order to avoid blocking the log-macros, this scheme is in use.\n\nThe copy from \"hot\" buffer to main buffer is performed by a call to `move_events()`,\nwhich is done in a cyclic task, which repeats every 10 ms, or when the hot buffer is half full.\n\nIn versions \u003c0.13 log messages may have been lost, if the widget wasn't drawn.\n\n```mermaid\nflowchart LR\n    Logging[\"Logging Macros\"] --\u003e Capture[\"CAPTURE Filter\"] --\u003e HotBuffer[\"Hot Buffer (1000 entries)\"]\n    \n    MoveEvents[\"move_events()\"]\n    HotBuffer --\u003e MoveEvents\n    MoveEvents --\u003e MainBuffer[\"Main Buffer (10000 entries)\"]\n    \n    MainBuffer --- Show1[\"SHOW Filter\"] --- Widget1[\"Widget 1\"]\n    MainBuffer --- Show2[\"SHOW Filter\"] --- Widget2[\"Widget 2\"]\n    MainBuffer --- ShowN[\"SHOW Filter\"] --- Widget3[\"Widget N\"]\n    \n    Config1[\"set_hot_buffer_depth()\"] -.-\u003e HotBuffer\n    Config2[\"set_buffer_depth()\"] -.-\u003e MainBuffer\n    \n    subgraph Triggers[\"Triggers\"]\n        direction TB\n        T1[\"Every 10ms\"]\n        T2[\"Hot buffer 50% full\"]\n    end\n    \n    Triggers -.-\u003e MoveEvents\n    \n    note[\"Note: Main buffer locks during widget updates\"]\n    note -.-\u003e MainBuffer\n```\n\n### THANKS TO\n\n* [Florian Dehau](https://github.com/fdehau) for his great crate [tui-rs](https://github.com/fdehau/tui-rs)\n* [Antoine Büsch](https://github.com/abusch) for providing the patches to tui-rs v0.3.0 and v0.6.0\n* [Adam Sypniewski](https://github.com/ajsyp) for providing the patches to tui-rs v0.6.2\n* [James aka jklong](https://github.com/jklong) for providing the patch to tui-rs v0.7\n* [icy-ux](https://github.com/icy-ux) for adding slog support and example\n* [alvinhochun](https://github.com/alvinhochun) for updating to tui 0.10 and crossterm support\n* [brooksmtownsend](https://github.com/brooksmtownsend) Patch to remove verbose timestamp info\n* [Kibouo](https://github.com/Kibouo) Patch to change Rc/Refcell to thread-safe counterparts\n* [Afonso Bordado](https://github.com/afonso360) for providing the patch to tui-rs v0.17\n* [Benjamin Kampmann](https://github.com/gnunicorn) for providing patch to tui-rs v0.18\n* [Paul Sanders](https://github.com/pms1969) for providing patch in [issue #30](https://github.com/gin66/tui-logger/issues/30)\n* [Ákos Hadnagy](https://github.com/ahadnagy) for providing patch in [#31](https://github.com/gin66/tui-logger/issues/31) for tracing-subscriber support\n* [Orhun Parmaksız](https://github.com/orhun) for providing patches in [#33](https://github.com/gin66/tui-logger/issues/33), [#34](https://github.com/gin66/tui-logger/issues/34), [#37](https://github.com/gin66/tui-logger/issues/37) and [#46](https://github.com/gin66/tui-logger/issues/46)\n* [purephantom](https://github.com/purephantom) for providing patch in [#42](https://github.com/gin66/tui-logger/issues/42) for ratatui update\n* [Badr Bouslikhin](https://github.com/badrbouslikhin) for providing patch in [#47](https://github.com/gin66/tui-logger/issues/47) for ratatui update\n* [ganthern](https://github.com/ganthern) for providing patch in [#49](https://github.com/gin66/tui-logger/issues/49) for tui support removal\n* [Linda_pp](https://github.com/rhysd) for providing patch in [#51](https://github.com/gin66/tui-logger/issues/51) for Cell:set_symbol\n* [Josh McKinney](https://github.com/joshka) for providing patch in\n[#56](https://github.com/gin66/tui-logger/issues/56) for Copy on TuiWidgetEvent and\nTuiLoggerWidget\n* [nick42d](https://github.com/nick42d) for providing patch in\n[#63](https://github.com/gin66/tui-logger/issues/63) for semver checks, [#74](https://github.com/gin66/tui-logger/pull/74) and [#87](https://github.com/gin66/tui-logger/issues/87)\n* [Tom Groenwoldt](https://github.com/tomgroenwoldt) for providing patch in [#65](https://github.com/gin66/tui-logger/issues/65) for ratatui update\n* [Kevin](https://github.com/doesnotcompete) for providing patch in [#71](https://github.com/issues/71)\n* [urizennnn](https://github.com/urizennnn) for providing patch in [#72](https://github.com/issues/72)\n* [Earthgames](https://github.com/Earthgames) for providing patch in [#84](https://github.com/issues/84) to fix panic for unicode characters\n\n### Star History\n\n[![Star History Chart](https://api.star-history.com/svg?repos=gin66/tui-logger\u0026type=Date)](https://star-history.com/#gin66/tui-logger\u0026Date)\n\nLicense: MIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgin66%2Ftui-logger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgin66%2Ftui-logger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgin66%2Ftui-logger/lists"}