Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
An asynchronous single-threaded logger where formatting and I/O are deferred at callsite.
Overview
Quicklog is provides a framework for logging where it allows for deferred
deferred formatting and deferred I/O of logging, which should in turn provide
more performant logging with low callsite latency.
Deferred Formatting
Why?
Formatting a struct into a String requires the overhead of serialization.
Deferring the serialization of a struct can be avoided by cloning / copying
the struct at a point in time, and saving that onto a queue.
Later at the flush site, this struct is serialized into a string when I/O is going to be performed.
Deferred I/O
Why?
Deferring the I/O of formatting would allow for low callsite latency and allow a user to implement their own flush site, possibly on a separate thread
Usage
init!() macro needs to be called to initialize the logger before we can
start logging, probably near the entry point of your application.
Example Usage
# use thread;
# use ;
Macros
Shorthand Macros
Quicklog allows a number of macros with 5 different levels of verbosity. These
wrap around [log!] with the corresponding levels.
- [
trace!] - [
debug!] - [
info!] - [
warn!] - [
error!]
Internally, these shorthands call [try_log!] with their respective levels.
Setup Macros
Quicklog allows a user specified [Clock] or [Flush] to be implemented by
the user. This can be passed in through these macros, as long as the
underlying struct implements the correct traits
- [
with_clock!]: Specify the Clock Quicklog uses - [
with_flush!]: Specify the Flusher Quicklog uses - [
with_flush_into_file]: Specify path to flush log lines into
Macro prefix for partial serialization
To speed things up, if you are logging a large struct, there could be some small things
you might not want to log. This functionality can be done through implementing the
Serialize trait, where you can implement how to copy which parts of the struct.
This could additionally be helpful if you already have the struct inside a buffer in byte form, as you could simply pass the buffer directly into the decode fn, eliminiating any need to copy.
struct SomeStruct {
num: i64
}
impl Serialize for SomeStruct {
fn encode(&self, write_buf: &'static mut [u8]) -> Store { /* some impl */ }
fn buffer_size_required(&self) -> usize { /* some impl */ }
}
fn main() {
let s = SomeStruct { num: 1_000_000 };
info!("some struct: {}", ^s);
}
Macro prefix for eager evaluation
There are two prefixes you can use for variables, % and ?. This works the same
way as tracing, where % eagerly evaluates an object that implements Display
and ? eagerly evaluates an object that implements Debug.
# use ;
#
Structured fields
Structured fields in log lines can be specified using field_name = field_value
syntax. field_name can be a literal or a bunch of idents. This can also
be used in combination with % and ? prefix on args to eagerly evaluate
expressions into format strings.
# use ;
#
Environment variables
There are two environment variables you can set:
QUICKLOG_MAX_LOGGER_CAPACITY
- sets the size of the spsc ring buffer used for logging
QUICKLOG_MAX_SERIALIZE_BUFFER_CAPACITY
- sets the size of the byte buffer used for static serialization
- this can be increased when you run into issues out of memory in debug when conducting load testing
Components
quicklog-clock
[Clock] is the trait for a clock that can be used with [Quicklog]. Clocks can
be swapped out at runtime with a different implementation.
This swap should be done at the init stage of your application to ensure that timings are consistent.
Example
struct SomeClock;
impl Clock for SomeClock { /* impl methods */ }
fn main() {
init!();
with_clock!(SomeClock::new());
// logger now uses SomeClock for timestamping
info!("Hello, world!");
flush!();
}
quicklog-flush
[Flush] is the trait that defines how the log messages would be flushed.
These logs can be printed through using the pre-defined StdoutFlusher or
saved to a file through the pre-defined FileFlusher to a specified
location through the string passed in.
Example
# use ;
# use StdoutFlusher;