quicklog

Fast single-threaded logging framework, almost 200x faster than tracing and delog for large structs.

Supports standard logging macros like trace!, debug!, info!, warn! and error!.

Flushing is deferred until flush!() macro is called.

Objectives

While tracing is a popular library for event tracing and are really good at what they do, quicklog is optimized for low callsite latency, paying the cost of formatting and I/O on a separate thread, away from the hot path.

Installation

Install using Cargo

bash cargo add quicklog

Add to Cargo.toml

```toml

Cargo.toml

[dependencies] quicklog = "0.1.15"

...

```

Usage

Quick Start

```rust use quicklog::{info, init, flush};

fn main() { // initialise required resources, called near application entry point init!();

// adds item to logging queue
info!("hello world");

let some_var = 10;
// variables are passed by copy
info!("value of some_var: {}", some_var);

// flushes everything in queue
flush!();

} ```

Utilising Serialize

In order to avoid cloning a large struct, you can implement the Serialize trait.

This allows you to copy specific parts of your struct onto a circular byte buffer and avoid copying the rest by encoding providing a function to decode your struct from a byte buffer.

For a complete example, refer to ~/quicklog/benches/logger_benchmark.rs.

```rust use quicklog::serialize::{Serialize, Store};

struct SomeStruct { num: i64 }

impl Serialize for SomeStruct { fn encode(&self, writebuf: &'static mut [u8]) -> Store { /* some impl */ } fn buffersize_required(&self) -> usize { /* some impl */ } }

fn main() { let s = SomeStruct { num: 1000000 }; info!("some struct: {}", ^s); } ```

Utilising different flushing mechanisms

```rust use quicklogflush::stdoutflusher::StdoutFlusher; use quicklog::{info, init, flush, withflushintofile, withflush};

fn main() { init!();

// flush into stdout
with_flush!(StdoutFlusher);

// item goes into logging queue
info!("hello world");

// flushed into stdout
flush!()

// flush into a file path specified
with_flush_into_file!("logs/my_log.log");

info!("shave yaks");

// flushed into file
flush!();

} ```

Benchmark

Measurements are made on a 2020 16 core M1 Macbook Air with 16 GB RAM.

Logging a struct with a vector of 10 large structs

| Logger | Lower Bound | Estimate | Upper Bound | | -------- | ------------- | ------------- | ------------- | | quicklog | 103.76 ns | 104.14 ns | 104.53 ns | | tracing | 22.336 µs | 22.423 µs | 22.506 µs | | delog | 21.528 µs | 21.589 µs | 21.646 µs |

Logging a single struct with 100 array elements

| Logger | Lower Bound | Estimate | Upper Bound | | -------- | ------------- | ------------- | ------------- | | quicklog | 61.399 ns | 62.436 ns | 63.507 ns | | tracing | 2.6501 µs | 2.6572 µs | 2.6646 µs | | delog | 2.7610 µs | 2.7683 µs | 2.7761 µs |

Logging a small struct with primitives

| Logger | Lower Bound | Estimate | Upper Bound | | -------- | ------------- | ------------- | ------------- | | quicklog | 28.561 ns | 28.619 ns | 28.680 ns | | tracing | 627.79 µs | 629.91 µs | 632.06 µs | | delog | 719.54 µs | 721.19 µs | 722.96 µs |

Contribution & Support

We are open to contributions and requests!

Please post your bug reports or feature requests on Github Issues.

Roadmap

Authors and acknowledgment

Zack Ng, Tien Dat Nguyen, Michiel van Slobbe, Dheeraj Oswal

Crates

References

License

Copyright 2023 Grasshopper Asia

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.