{"id":35256332,"url":"https://github.com/chensoft/logkit","last_synced_at":"2026-05-20T09:37:46.709Z","repository":{"id":218864450,"uuid":"741927613","full_name":"chensoft/logkit","owner":"chensoft","description":"Super fast, structured, scalable logging library for Rust","archived":false,"fork":false,"pushed_at":"2025-06-07T07:07:46.000Z","size":103,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"dev","last_synced_at":"2025-11-19T21:13:14.493Z","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/chensoft.png","metadata":{"files":{"readme":"README.md","changelog":"HISTORY.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}},"created_at":"2024-01-11T11:59:45.000Z","updated_at":"2024-07-13T12:43:26.000Z","dependencies_parsed_at":"2024-02-05T12:25:58.019Z","dependency_job_id":"67bc8199-f408-451e-89e8-53e17f996b24","html_url":"https://github.com/chensoft/logkit","commit_stats":null,"previous_names":["chensoft/logkit"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/chensoft/logkit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chensoft%2Flogkit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chensoft%2Flogkit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chensoft%2Flogkit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chensoft%2Flogkit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chensoft","download_url":"https://codeload.github.com/chensoft/logkit/tar.gz/refs/heads/dev","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chensoft%2Flogkit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28124757,"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","status":"online","status_checked_at":"2025-12-30T02:00:05.476Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":"2025-12-30T08:02:12.109Z","updated_at":"2025-12-30T08:04:53.993Z","avatar_url":"https://github.com/chensoft.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"Logkit\n==========================\n\nSuper fast, structured, scalable logging library for Rust\n\n[![Crates.io][crates-badge]][crates-url]\n[![MIT licensed][license-badge]][license-url]\n[![Documentation][document-badge]][document-url]\n[![Build Status][linux-badge]][linux-url]\n[![Build Status][macos-badge]][macos-url]\n[![Build Status][windows-badge]][windows-url]\n\n[crates-badge]: https://img.shields.io/crates/v/logkit.svg\n[crates-url]: https://crates.io/crates/logkit\n[license-badge]: https://img.shields.io/badge/license-MIT-blue.svg\n[license-url]: https://github.com/chensoft/logkit?tab=MIT-1-ov-file\n[document-badge]: https://docs.rs/logkit/badge.svg\n[document-url]: https://docs.rs/logkit\n[linux-badge]: https://github.com/chensoft/logkit/actions/workflows/linux.yml/badge.svg\n[linux-url]: https://github.com/chensoft/logkit/actions/workflows/linux.yml\n[macos-badge]: https://github.com/chensoft/logkit/actions/workflows/macos.yml/badge.svg\n[macos-url]: https://github.com/chensoft/logkit/actions/workflows/macos.yml\n[windows-badge]: https://github.com/chensoft/logkit/actions/workflows/windows.yml/badge.svg\n[windows-url]: https://github.com/chensoft/logkit/actions/workflows/windows.yml\n\n## Hello World\n\n```rust\n#[macro_use] extern crate logkit;\n\nfn main() {\n    let mut logger = logkit::Logger::new(Some(\u0026logkit::StdoutTarget));\n    logger.mount(logkit::TimePlugin::from_millis());\n    logger.mount(logkit::LevelPlugin);\n    logger.mount(logkit::SourcePlugin::new());\n    logkit::set_default_logger(logger);\n\n    trace!(\"hello, this is a trace log\");\n    debug!(\"hello, this is a debug log\");\n    info!(version = \"0.1.0\", commit = \"3291cc60\"; \"this is a log with two string fields\");\n    warn!(address = \"127.0.0.1\", port = 3000; \"this is a log with a string and a numeric field\");\n    error!(\"this is a log with a 'println' style string {}:{}\", \"127.0.0.1\", 3000.0);\n}\n```\n\nOutput sample:\n\n```json\n{\"time\":\"2024-06-30T14:43:33.236+08:00\",\"level\":\"trace\",\"msg\":\"hello, this is a trace log\",\"src\":\"examples/hello_world.rs:10\"}\n{\"time\":\"2024-06-30T14:43:33.236+08:00\",\"level\":\"debug\",\"msg\":\"hello, this is a debug log\",\"src\":\"examples/hello_world.rs:11\"}\n{\"time\":\"2024-06-30T14:43:33.236+08:00\",\"level\":\"info\",\"msg\":\"this is a log with two string fields\",\"version\":\"0.1.0\",\"commit\":\"3291cc60\",\"src\":\"examples/hello_world.rs:12\"}\n{\"time\":\"2024-06-30T14:43:33.236+08:00\",\"level\":\"warn\",\"msg\":\"this is a log with a string and a numeric field\",\"address\":\"127.0.0.1\",\"port\":3000,\"src\":\"examples/hello_world.rs:13\"}\n{\"time\":\"2024-06-30T14:43:33.236+08:00\",\"level\":\"error\",\"msg\":\"this is a log with a 'println' style string 127.0.0.1:3000\",\"src\":\"examples/hello_world.rs:14\"}\n```\n\n## Basic Syntax\n\nFive convenient macros are available for use: `trace`, `debug`, `info`, `warn`, and `error`.\nThese support the following log formats, and you can define custom macros if necessary.\n\n```rust\n#[macro_use] extern crate logkit;\n\ntrace!(); // outputs just a linebreak\ntrace!(\"plain message\");\ntrace!(\"println-like message {} {}!\", \"Hello\", \"World\");\ntrace!(name = \"Alice\", age = 20); // outputs only fields, no message\ntrace!(name = \"Alice\", age = 20; \"separate fields and messages with semicolon\");\ntrace!(name = \"Alice\", age = 20; \"println-like message {} {}! with fields\", \"Hello\", \"World\");\n```\n\n## Default Logger\n\nFor convenience, we have defined a default logger that outputs messages to stderr.\n\n```rust\n#[macro_use] extern crate logkit;\n\nassert_eq!(logkit::default_logger().level(), logkit::LEVEL_TRACE);\ntrace!(\"hello, this is a trace log\");\ndebug!(\"hello, this is a debug log\");\n```\n\n## Custom Logger\n\n```rust\nfn main() {\n    let mut logger = logkit::Logger::new(None);\n    logger.mount(logkit::LevelPlugin); // you can add your own plugin\n    logger.route(logkit::StderrTarget); // and add your custom target\n\n    // replace the default logger\n    logkit::set_default_logger(logger);\n    // or use it directly like built-in macros\n}\n```\n\n## Custom Level\n\nThere are five built-in log levels: `TRACE`, `DEBUG`, `INFO`, `WARN` and `ERROR`. You can define your\nown levels, as the type is simply an alias for i32, not an enum.\n\n```rust\npub const LEVEL_CUSTOM : logkit::Level = 10; // use any number distinct from the built-ins\n\n#[macro_export]\nmacro_rules! custom {\n    ($($arg:tt)*) =\u003e {{\n        logkit::record!(logkit::default_logger(), LEVEL_CUSTOM, $($arg)*)\n    }};\n}\n\ncustom!(\"this is a custom log level\");\n```\n\n## Custom Encoding\n\nWe support all scalar types and many std collections, if you want to encode your own type into\njson, you can implement the Encode trait.\n\n```rust\npub struct CustomStruct {\n    pub key1: i32,\n    pub key2: bool,\n    pub key3: String,\n}\n\nimpl logkit::Encode for CustomStruct {\n    #[inline]\n    fn encode(\u0026self, buf: \u0026mut Vec\u003cu8\u003e) {\n        // format your struct into buf\n        unimplemented!()\n    }\n}\n```\n\n## Logging Plugin\n\nPlugins, also known as middleware, add hooks for `pre` and `post` steps. When a logger spawns a\nrecord, the `pre` method is called before any fields are added to it. When the record is ready\nto flush, the `post` method is invoked before outputting to targets. You can add any fields\nto the record. If you decide not to continue handling the record, simply return `false` in\n`pre` or `post`. The record will not be processed further if `false` is returned.\n\n```rust\n#[macro_use] extern crate logkit;\n\n// custom plugin to add 'pid' to record\npub struct PidPlugin { pub pid: u32 }\n\nimpl logkit::Plugin for PidPlugin {\n    #[inline]\n    fn post(\u0026self, record: \u0026mut logkit::Record) -\u003e bool {\n        record.append(\"pid\", \u0026self.pid);\n        true\n    }\n}\n\nfn main() {\n    let mut logger = logkit::Logger::new(Some(\u0026logkit::StderrTarget));\n    logger.mount(PidPlugin { pid: std::process::id() });\n    logkit::set_default_logger(logger);\n\n    info!(\"you will see this log with a process id\");\n}\n```\n\n```rust\n#[macro_use] extern crate logkit;\n\n// custom plugin to filter all levels below 'info'\npub struct LimitPlugin;\n\nimpl logkit::Plugin for LimitPlugin {\n    #[inline]\n    fn pre(\u0026self, record: \u0026mut logkit::Record) -\u003e bool {\n        record.level() \u003e= logkit::LEVEL_INFO\n    }\n}\n\nfn main() {\n    let mut logger = logkit::Logger::new(Some(\u0026logkit::StderrTarget));\n    logger.mount(LimitPlugin);\n    logkit::set_default_logger(logger);\n\n    debug!(\"this log is ignored\");\n    info!(\"you can see this log\");\n}\n```\n\n## Output Target\n\nUpon completion, a record is routed to various targets, which define the methods of outputting\ncontent. A record can be directed to multiple targets, and each target is simply required to\nimplement the `Target` trait.\n\n```rust\n#[macro_use] extern crate logkit;\n\npub struct CustomTarget;\n\nimpl logkit::Target for CustomTarget {\n    #[inline]\n    fn write(\u0026self, buf: \u0026[u8]) {\n        use std::io::Write;\n        let _ = std::io::stdout().write_all(buf);\n    }\n}\n\nfn main() {\n    let mut logger = logkit::Logger::new(Some(\u0026logkit::StderrTarget));\n    logger.route(CustomTarget);\n    logkit::set_default_logger(logger);\n\n    info!(\"record will be output to both stderr and stdout now\");\n}\n```\n\n## Benchmark\n\n- MacBook Air, Apple M2 24G, Sonoma 14.2.1\n\n| Name              |              Time               |\n|:------------------|:-------------------------------:|\n| empty_log         | [22.526 ns 22.541 ns 22.560 ns] |\n| level_off         | [1.6941 ns 1.6989 ns 1.7050 ns] |\n| msg_only          | [63.166 ns 63.172 ns 63.177 ns] |\n| msg_format        | [63.238 ns 63.373 ns 63.548 ns] |\n| fields_only       | [96.944 ns 96.974 ns 97.005 ns] |\n| fields_msg        | [147.03 ns 147.26 ns 147.56 ns] |\n| fields_msg_format | [146.44 ns 146.51 ns 146.58 ns] |\n| fields_ten_fields | [395.31 ns 395.35 ns 395.40 ns] |\n\n- AWS c5.2xlarge, 8C 16G, Ubuntu 22.04\n\n| Name              |              Time               |\n|:------------------|:-------------------------------:|\n| empty_log         | [50.761 ns 50.764 ns 50.768 ns] |\n| level_off         | [4.1800 ns 4.1804 ns 4.1810 ns] |\n| msg_only          | [121.12 ns 121.14 ns 121.16 ns] |\n| msg_format        | [121.18 ns 121.20 ns 121.23 ns] |\n| fields_only       | [177.70 ns 177.74 ns 177.77 ns] |\n| fields_msg        | [264.25 ns 264.33 ns 264.45 ns] |\n| fields_msg_format | [261.80 ns 261.89 ns 261.98 ns] |\n| fields_ten_fields | [654.11 ns 654.31 ns 654.51 ns] |","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchensoft%2Flogkit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchensoft%2Flogkit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchensoft%2Flogkit/lists"}