A highly configurable logging framework for Rust

Overview

log4rs

docs crates.io License: MIT OR Apache-2.0 CI Minimum rustc version

log4rs is a highly configurable logging framework modeled after Java's Logback and log4j libraries.

Warning

If you are using the file rotation in your configuration there is a known substantial performance issue so listen up! By default the gzip feature is enabled and when rolling files it will zip log archives automatically. This is a problem when the log archives are large as the zip happens in the main thread and will halt the process while the zip is completed. Be advised that the gzip feature will be removed from default features as of 1.0.

The methods to mitigate this are as follows.

  1. Use the background_rotation feature which spawns an os thread to do the compression.
  2. Disable the gzip feature with --no-default-features.
  3. Ensure the archives are small enough that the compression time is acceptable.

For more information see the PR that added background_rotation.

Quick Start

log4rs.yaml:

refresh_rate: 30 seconds
appenders:
  stdout:
    kind: console
  requests:
    kind: file
    path: "log/requests.log"
    encoder:
      pattern: "{d} - {m}{n}"
root:
  level: warn
  appenders:
    - stdout
loggers:
  app::backend::db:
    level: info
  app::requests:
    level: info
    appenders:
      - requests
    additive: false

lib.rs:

use log::{error, info, warn};
use log4rs;

fn main() {
    log4rs::init_file("config/log4rs.yaml", Default::default()).unwrap();

    info!("booting up");

    // ...
}

Rust Version Requirements

Since version 0.10.0 the minimum version for rust is 1.38.0 and is verified via CI. 1.38.0 is required for windows due to the backtrace crate. 1.34.0 may work for unix environments although it is not officially supported.

Building for Dev

  • Run the tests: cargo test --all-features
  • Run the tests for windows with cross: cross test --target x86_64-pc-windows-gn
  • Run the tests for all individual features: ./test.sh
  • Run the tests for all individual features for windows with cross: ./test.sh win

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you shall be dual licensed as above, without any additional terms or conditions.

Comments
  • Add methods for modifying logging level of Root

    Add methods for modifying logging level of Root

    Adds set_level methods to Root and Config objects. This provides the ability to modify the logging level of Root even after Root and Config have been built.

    We are using this modification to change the logging level of a Config that is loaded from a .yaml file based on a verbosity flag that is passed in on the command line.

    Signed-off-by: Logan Seeley [email protected]

    opened by ltseeley 16
  • Add support for gettid() to PatternEncoder

    Add support for gettid() to PatternEncoder

    Add {i} and {tid} to allow logging in particular the Linux thread ID as returned by gettid(). This is very useful for system-wide debugging und monitoring with consistent thread/task IDs.

    Fixes: #231

    opened by cloneable 13
  • Operators should own the logs by default. Not developers. Is this done in this solution ? How?

    Operators should own the logs by default. Not developers. Is this done in this solution ? How?

    One of the main features of a logging framework like log4j 2 is it's separation of concerns:

    A developer using log4j may (and should not) bother, ever, with where the logs are, in what format it is, and how to initialize logging.

    In principle, people using the application (operators) should be able to choose where the logs will go, and which messages will be shown, where.

    Also, operators shouldn't need to "learn" how to configure logs for application A , B , C . There should be a common standard among them.

    To force the task of choosing where logs will go to the developer is a hazardous antipattern that have caused a lot of issues on my professional experience with java, unless you develop code utterly alone and don't use third party modules at all:

    • Developer of module A decides that he wants to configure logs to send to the file Y, at debug level, not rolling,ever. With dates in format YYYY-MM-DD HH:mm:ss, and a message like "ERROR 2020-11-10 10:00:00 [[[ SOME ISSUE HAPPENED ]]]"

    • Developer of module B decides that he wants to configure logs to send files only to the console, at error level. showing messages like ---SOME ISSUE HAPPENED --- ERROR 10-11-2020 14:00:00 <<yep, different timezone

    This will make, from the standpoint of an operator, for logs to behave erratically, some messages going some to Y, other to console, with different formats, and impossible for the operator to make head of tail of the mess the logs are.

    So when an operator is diagnosing issues, they simply can't know where the evidences are in a consistent manner.

    The pattern used in log4j2 for java is something like this:

    
    package x;
    
    public class Y {
    
    	// The LogManager.getLogger() is "miraculous": it deducts that the logger name is "x.Y" (the full qualified class name)
    	// and it sees that if the logging system is not initialized yet, it does initialize it looking for all configuration options at some standard
    	// location (usually a log4j2.xml placed somewhere in the classpath, but it can be defined by an environment variable or an initialization
    	// option from the command line)
    	Logger otherLog = LogManager.getLogger(); 
    
    	public void someMethod() {
    
    		// otherLog == log
    		Logger log = LogManager.getLogger(); 
    
    		// in java : log2 == log : they refer to the same object. Sharing the same features.
    		Logger log2 = LogManager.getLogger();
    
    		// same here: log3 == log : calling getLogger("x.Y") will use the same logger as the others, because the qualified name is the same.
    		Logger log3 = LogManager.getLogger("x.Y");
    
    		// all this messages will be sent to the exact same locations, with whatever set format, because all these loggers are the same.
    		log.info("test"); 
    		otherLog.info("test");
    		log2.info("test");
    		log3.info("test");
    	}
    }
    
    enhancement disposition close 
    opened by abmpicoli2 12
  • add a time roller

    add a time roller

    There is a need when you have some thing to log which should be keep for some days, but you can not estimate the size it will be (for example user online duration). If you use the size roller, the size may be small and log will be removed. A time roller would be nice to handle this thing.

    WIP 
    opened by SSebo 12
  • Deleteing the active log file stops logging

    Deleteing the active log file stops logging

    I have a cron job that zips up all my log files periodically (several programs with both text and binary logs). That moves the entire contents of the log directory, zips them up, then deletes them. Sadly log4rs does not cope with having an open file deleted, and that's the end of that, no more logging. Note that creating a new file with the same name does not fix the problem - log4rs has already given up.

    Having written a custom binary log format in C++ for this, I have been through the process myself. When the open file is deleted you have an invalid handle, but you must close that handle. Otherwise you still have an active-but-invalid handle (it will leak!). Then obviously just open a new file and log away.

    I believe any test app will demonstrate this problem if you remove the log file while it's being used.

    opened by DigiTester 12
  • Terminal coloration

    Terminal coloration

    Hello there!

    I have realised log4rs does not provide terminal coloration by default. Would you be interested in the feature?

    For comparison, loggers such as log4js and winston provides terminal coloration by default.

    If you like the idea but don't have the time for it, I would gladly work on it. :)

    opened by Nemikolh 11
  • Add tty_only option to console appender

    Add tty_only option to console appender

    The use-case is when you only want console output when running a program in console.

    resolves #210

    Also remove someones .DS_Store file which was probably a mistake.

    opened by rudolphfroger 10
  • Configuration parameter to make the log file path relative to the binary

    Configuration parameter to make the log file path relative to the binary

    Currently the log file path from the config file seems to be relative to the current directory. It would be great to have an option (or something like a $EXE_PATH variable to use in the path string) to make this relative to the executable instead.

    enhancement help wanted disposition close 
    opened by afck 10
  • Highlight doesn't reset style for trace/trace color is unreadable

    Highlight doesn't reset style for trace/trace color is unreadable

    #167 added a color for trace, but didn't add a match arm to reset the style. This results in all text after a highlighted trace being black. Also of note is that in a dark terminal, the trace highlight is unreadable. I would suggest putting no coloring on it at all if it's going to be black or white.

    opened by judemille 9
  • android build bug(after commit 0d0a6dd88047337a9b33292c24addfabac5352d5)

    android build bug(after commit 0d0a6dd88047337a9b33292c24addfabac5352d5)

    Hi, after commit 0d0a6dd88047337a9b33292c24addfabac5352d5, there are some build errors on android platform. errors:

       Compiling palaver v0.2.8
    error[E0432]: unresolved import `nix::sys::memfd`
       --> /root/.cargo/registry/src/github.com-1ecc6299db9ec823/palaver-0.2.8/src/file.rs:185:8
        |
    185 |             use nix::sys::memfd;
        |                 ^^^^^^^^^^^^^^^ no `memfd` in `sys`
    
    error[E0425]: cannot find function `shm_open` in module `mman`
       --> /root/.cargo/registry/src/github.com-1ecc6299db9ec823/palaver-0.2.8/src/file.rs:213:9
        |
    213 |         mman::shm_open(
        |               ^^^^^^^^ not found in `mman`
    
    error[E0425]: cannot find function `shm_unlink` in module `mman`
       --> /root/.cargo/registry/src/github.com-1ecc6299db9ec823/palaver-0.2.8/src/file.rs:226:10
        |
    226 |             mman::shm_unlink(name).unwrap();
        |                   ^^^^^^^^^^ not found in `mman`
    
    Some errors have detailed explanations: E0425, E0432.
    For more information about an error, try `rustc --explain E0425`.
    error: could not compile `palaver` due to 3 previous errors
    

    and

       Compiling procinfo v0.4.2
    error[E0308]: mismatched types
       --> /root/.cargo/registry/src/github.com-1ecc6299db9ec823/procinfo-0.4.2/src/pid/status.rs:189:1
        |
    189 | named!(parse_umask<mode_t>,     delimited!(tag!("Umask:\t"),     parse_u32_octal,    line_ending));
        | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u16`, found `u32`
        |
        = note: this error originates in the macro `delimited` (in Nightly builds, run with -Z macro-backtrace for more info)
    
    For more information about this error, try `rustc --explain E0308`.
    error: could not compile `procinfo` due to previous error
    
    opened by caoruijuan13 8
  • Consider replacing Regex with simpler scanner

    Consider replacing Regex with simpler scanner

    I was checking a binary with cargo bloat and to my surprise I noticed that log4rs pulled in regex which turned out to be 4x as large as log4rs itself. So I was curious what log4rs is using regex for. I could only find one line with a reg exp matcher that's not even that complex.

    $ grep -rni regex .
    ./Cargo.toml:21:file_appender = ["parking_lot", "simple_writer", "pattern_encoder", "regex"]
    ./Cargo.toml:22:rolling_file_appender = ["parking_lot", "simple_writer", "pattern_encoder", "regex"]
    ./Cargo.toml:70:regex = { version = "1", optional = true }
    ./src/append/mod.rs:29:        let matcher = regex::Regex::new(r#"\$ENV\{([\w][\w|\d|\.|_]*)\}"#).unwrap();
    

    So I'm wondering if you have more plans for regex crate or if you would be willing to replace this one use with a handwritten scanner?

    enhancement 
    opened by cloneable 8
  • add trigger kind

    add trigger kind "time" in rolling_file

    I add the trigger kind "time" in rolling_file. It can be set with limit like 5second, 10minute, 1day, 3weeks...It may be able to solve the Issue #235. I referred to #139 and thank for @SSebo

    opened by Dirreke 1
  • Documentation of log config files

    Documentation of log config files

    Please pardon my ignorance, I've been looking around but haven't been able to find anywhere that lists what is expected to be in a config file to load the configuration. I've found a few example but nothing that explains what all the options are. Does this exist and I just missed it? In the documentation it says, "...The file module documentation covers the exact configuration syntax, but an example in the YAML format is provided below...". I've tried looking but I haven't been able to find it. Would appreciate if someone can point me in the right direction.

    question 
    opened by c-git 5
  • Trigger is invoked after log, causing date based triggers to log one line in the wrong file

    Trigger is invoked after log, causing date based triggers to log one line in the wrong file

    I have a Date based trigger, so when the date changes it will return true and the logs are rotated. However due to the fact that the rolling file appender writes to the log first, and then check the policy, the first log line each day is written in the old log, before it is rotated.

    I think it would be bettter, if the policy was checked at the top of the append function, before the log is written.

    bug open pr 
    opened by snaggen 9
  • Support truncating from the left, width padding/truncation incorrect with some unicode input

    Support truncating from the left, width padding/truncation incorrect with some unicode input

    Left truncation is the default in the inspiration for this crate (Log4j). It usually produces more relevant results, e.g. for filenames, logger names, etc.

    Both styles of truncation should be supported, with right truncation (current implementation) as the default for backward compatibility.

    Log4j uses a minus sign on the length (negative length) to flip the truncation. So it might look like this for log4rs: {f:>-15.15} (left truncate or left pad the filename field to exactly 15 chars)

    bug enhancement open pr 
    opened by moh-eulith 11
Releases(v1.1.1)
Owner
null
Logging implementation for Rust

log A Rust library providing a lightweight logging facade. log documentation A logging facade provides a single logging API that abstracts over the ac

The Rust Programming Language 1.6k Dec 29, 2022
Structured, contextual, extensible, composable logging for Rust

Getting started Introduction FAQ Crate list slog-rs - The Logging for Rust Introduction (please read) slog is an ecosystem of reusable components for

slog-rs 1.4k Jan 3, 2023
Task-based logging for rust

task_log task_log is a task-based logger. Installing Just add task_log = 0.1.4 to your Cargo.toml's dependency section. Example Let's get right to the

Matt Gleich 2 Feb 28, 2022
💬 A couple of functions to make logging in Rust easier.

Rust logging ⛔ ?? A couple of functions to make logging in Rust easier. Installation ?? Just add the code of code.rs to your project. You can copy/pas

Skwal 2 Apr 7, 2022
A logging library for eBPF programs.

aya-log - a logging library for eBPF programs Overview aya-log is a logging library for eBPF programs written using aya. Think of it as the log crate

null 18 Oct 13, 2022
A highly customizable Changelog Generator that follows Conventional Commit specifications ⛰️

git-cliff can generate changelog files from the Git history by utilizing conventional commits as well as regex-powered custom parsers. The changelog template can be customized with a configuration file to match the desired format.

Orhun Parmaksız 5k Dec 30, 2022
A pretty, easy-to-use logger for Rust.

pretty-env-logger A simple logger built on top of env_logger. It is configured via an environment variable and writes to standard error with nice colo

Sean McArthur 390 Dec 29, 2022
Application level tracing for Rust.

Website | Chat | Documentation (master branch) Overview tracing is a framework for instrumenting Rust programs to collect structured, event-based diag

Tokio 3.3k Jan 3, 2023
A Rust logger with various features.

Moe Logger (>ω<) Another logger based on pretty-env-logger and env_logger. Allow writing log to file with features like formatting, file rotation. Usa

Rui Li 4 Sep 24, 2021
godot-logger is an easy-to-use logger for godot-rust projects.

godot-logger is an easy-to-use logger for godot-rust projects. It prints logs to Godot's output console and supports module-specific log levels.

Jan David 10 Nov 17, 2022
Another Key Logger Yet. Rust.

Another Key Logger Yet. Rust. For my very first experience of working with Rust, I decided to manage the keyboard, this time by logging and writing th

(Not) Kearash 0 May 3, 2022
A pretty, sensible logger for Rust - ideal for running examples and tests on a crate of choice

sensible-env-logger A pretty, sensible logger for Rust - ideal for running examples and tests on a crate of choice. This is a thin wrapper around pret

Ritvik Nag 3 Aug 9, 2022
A rust library for creating and managing logs of arbitrary binary data

A rust library for creating and managing logs of arbitrary binary data. Presently it's used to collect sensor data. But it should generally be helpful in cases where you need to store timeseries data, in a nearly (but not strictly) append-only fashion.

Yusuf Simonson 1 May 9, 2022
A cool log library built using rust-lang

RustLog A cool log library built using rust-lang Installation: Cargo.toml rustlog = { git = "https://github.com/krishpranav/rustlog" } log = "0.4.17"

Krisna Pranav 2 Jul 21, 2022
Easy c̵̰͠r̵̛̠ö̴̪s̶̩̒s̵̭̀-t̶̲͝h̶̯̚r̵̺͐e̷̖̽ḁ̴̍d̶̖̔ ȓ̵͙ė̶͎ḟ̴͙e̸̖͛r̶̖͗ë̶̱́ṉ̵̒ĉ̷̥e̷͚̍ s̷̹͌h̷̲̉a̵̭͋r̷̫̊ḭ̵̊n̷̬͂g̵̦̃ f̶̻̊ơ̵̜ṟ̸̈́ R̵̞̋ù̵̺s̷̖̅ţ̸͗!̸̼͋

Rust S̵̓i̸̓n̵̉ I̴n̴f̶e̸r̵n̷a̴l mutability! Howdy, friendly Rust developer! Ever had a value get m̵̯̅ð̶͊v̴̮̾ê̴̼͘d away right under your nose just when

null 294 Dec 23, 2022
defmt is a highly efficient logging framework that targets resource-constrained devices, like microcontrollers

defmt defmt ("de format", short for "deferred formatting") is a highly efficient logging framework that targets resource-constrained devices, like mic

Knurling 476 Jan 2, 2023
Highly modular & configurable hash & crypto library

Octavo Highly modular & configurable hash & crypto library written in pure Rust. Installation [dependencies] octavo = { git = "https://github.com/libO

Octavo Developers 139 Dec 29, 2022
A highly scalable MySQL Proxy framework written in Rust

mysql-proxy-rs An implementation of a MySQL proxy server built on top of tokio-core. Overview This crate provides a MySQL proxy server that you can ex

AgilData 175 Dec 19, 2022
Engine / framework for creating highly customizable and user modable action RPG's

Rust RPG Toolkit PLEASE NOTE: this in early and very heavy development. API is subject to constant change, as it has newly transitioned from being a g

Ole A. Sjo Fasting 58 Dec 5, 2022
Bytewax is an open source Python framework for building highly scalable dataflows.

Bytewax Bytewax is an open source Python framework for building highly scalable dataflows. Bytewax uses PyO3 to provide Python bindings to the Timely

Bytewax 289 Jan 6, 2023