All Projects → odygrd → Quill

odygrd / Quill

Licence: mit
Asynchronous Low Latency C++ Logging Library

Programming Languages

cpp
1120 projects
cpp17
186 projects
cpp14
131 projects

Projects that are alternatives of or similar to Quill

G3log
G3log is an asynchronous, "crash safe", logger that is easy to use with default logging sinks or you can add your own. G3log is made with plain C++14 (C++11 support up to release 1.3.2) with no external libraries (except gtest used for unit tests). G3log is made to be cross-platform, currently running on OSX, Windows and several Linux distros. See Readme below for details of usage.
Stars: ✭ 677 (+60.43%)
Mutual labels:  async, asynchronous, logging, logger
Electron Timber
Pretty logger for Electron apps
Stars: ✭ 337 (-20.14%)
Mutual labels:  logging, logger, logging-library
Reckless
Reckless logging. Low-latency, high-throughput, asynchronous logging library for C++.
Stars: ✭ 358 (-15.17%)
Mutual labels:  asynchronous, logging, logging-library
Tslog
📝 tslog - Expressive TypeScript Logger for Node.js.
Stars: ✭ 321 (-23.93%)
Mutual labels:  logging, logger, logging-library
Izumi
Productivity-oriented collection of lightweight fancy stuff for Scala toolchain
Stars: ✭ 423 (+0.24%)
Mutual labels:  logging, logger, logging-library
Nanolog
Nanolog is an extremely performant nanosecond scale logging system for C++ that exposes a simple printf-like API.
Stars: ✭ 1,710 (+305.21%)
Mutual labels:  logging, logging-library, low-latency
Timber Elixir
🌲 Great Elixir logging made easy
Stars: ✭ 226 (-46.45%)
Mutual labels:  logging, logger, logging-library
Cocoadebug
iOS Debugging Tool 🚀
Stars: ✭ 3,769 (+793.13%)
Mutual labels:  logging, logger, logging-library
Async Sema
Semaphore using `async` and `await`
Stars: ✭ 326 (-22.75%)
Mutual labels:  async, asynchronous
Php Watcher
Monitor for any changes in your php application and automatically restart it (suitable for async apps).
Stars: ✭ 303 (-28.2%)
Mutual labels:  async, asynchronous
Caterpillar
Caterpillar is the ultimate logging system for Deno, Node.js, and Web Browsers. Log levels are implemented to the RFC standard. Log entries can be filtered and piped to various streams, including coloured output to the terminal, the browser's console, and debug files. You can even write your own transforms.
Stars: ✭ 330 (-21.8%)
Mutual labels:  logging, logger
Analog
PHP logging library that is highly extendable and simple to use.
Stars: ✭ 314 (-25.59%)
Mutual labels:  logging, logger
Daiquiri
Python library to easily setup basic logging functionality
Stars: ✭ 308 (-27.01%)
Mutual labels:  logging, logging-library
Exceptionless.net
Exceptionless clients for the .NET platform
Stars: ✭ 362 (-14.22%)
Mutual labels:  logging, logging-library
Scribe
The fastest logging library in the world. Built from scratch in Scala and programmatically configurable.
Stars: ✭ 304 (-27.96%)
Mutual labels:  logging, logging-library
Predis Async
Asynchronous PHP client library for Redis built on top of ReactPHP
Stars: ✭ 354 (-16.11%)
Mutual labels:  async, asynchronous
Tinylog
tinylog is a lightweight logging framework for Java, Kotlin, Scala, and Android
Stars: ✭ 360 (-14.69%)
Mutual labels:  logger, logging-library
Laravel Logger
An out the box activity logger for your Laravel or Lumen application. Laravel logger is an activity event logger for your laravel application. It comes out the box with ready to use with dashboard to view your activity. Laravel logger can be added as a middleware or called through a trait. This package is easily configurable and customizable. Supports Laravel 5.3, 5.4, 5.5, 5.6, 5.7, 5.8, 6, and 7+
Stars: ✭ 366 (-13.27%)
Mutual labels:  logging, logger
Xcglogger
A debug log framework for use in Swift projects. Allows you to log details to the console (and optionally a file), just like you would have with NSLog() or print(), but with additional information, such as the date, function name, filename and line number.
Stars: ✭ 3,710 (+779.15%)
Mutual labels:  logging, logging-library
Transmittable Thread Local
📌 TransmittableThreadLocal (TTL), the missing Java™ std lib(simple & 0-dependency) for framework/middleware, provide an enhanced InheritableThreadLocal that transmits values between threads even using thread pooling components.
Stars: ✭ 4,678 (+1008.53%)
Mutual labels:  async, asynchronous
Quill logo

Quill

Asynchronous Low Latency C++ Logging Library


homebrew vcpkg conan
brew install quill vcpkg install quill quill/[>=1.2.3]

Introduction

Quill is a cross-platform low latency logging library based on C++14.

The main goals of the library are:

  • Simplicity A small example code snippet should be enough to get started and use most of features.
  • Performance Ultra low latency. No formatting on the hot-path, asynchronous only mode. No hot-path allocations for fundamental types, enums and strings (including std::string and std::string_view). Any other custom or user defined type gets copy constructed with the formatting done on a backend worker thread.
  • Convenience Ease application monitoring/debugging. Latency is equal to latencies of binary loggers, but the produced log is in human readable form.

Features

  • Log anything - Blazing fast. See Benchmarks.
  • Format outside of the hot-path in a backend logging thread. For non-built-in types ostream::operator<<() is called on a copy of the object by the backend logging thread. Unsafe to copy non-trivial user defined are detected in compile time. Those types can be tagged as safe-to-copy to avoid formatting them on the hot path. See User Defined Types.
  • Custom formatters. Logs can be formatted based on a user specified pattern. See Formatters.
  • Support for log stack traces. Store log messages in a ring buffer and display later on a higher severity log statement or on demand. See Backtrace Logging.
  • Various logging targets. See Handlers.
    • Console logging with colours support.
    • File Logging
    • Rotating log files
    • Time rotating log files
    • Custom Handlers
  • Filters for filtering log messages. See Filters.
  • guaranteed non-blocking or non-guaranteed logging. In non-guaranteed mode there is no heap allocation of a new queue but log messages can be dropped. See FAQ.
  • Support for wide character logging and wide character filenames (Windows only).
  • Log statements in timestamp order even when produced by different threads. This makes debugging easier in multi-threaded applications.
  • Log levels can be completely stripped out at compile time reducing if branches.
  • Clean warning-free codebase even on high warning levels.
  • Crash safe behaviour with a build-in signal handler.
  • Type safe python style API with compile type checks and built-in support for logging STL types/containers by using the excellent {fmt} library.

Performance

Log Numbers

The following message is logged 100'000 times per thread LOG_INFO(logger, "Logging int: {}, int: {}, double: {}", i, j, d).

1 Thread

Library 50th 75th 90th 95th 99th 99.9th Worst
Quill, Dual Queue Enabled, Bounded Queue 20 22 25 27 34 67 118
Quill, Dual Queue Enabled, Unbounded Queue 20 24 28 30 36 69 134
Quill, Dual Queue Disabled, Unbounded Queue 23 31 35 37 52 75 134
PlatformLab NanoLog 19 22 23 25 28 64 128
MS BinLog 46 47 48 49 82 129 353
Reckless 69 70 74 80 106 133 5908477
Iyengar NanoLog 112 122 134 147 207 337 597293
spdlog 288 312 328 345 670 914 4794
g3log 2434 2886 2992 3055 3178 3338 5579

4 Threads

Library 50th 75th 90th 95th 99th 99.9th Worst
Quill, Dual Queue Enabled, Bounded Queue 19 22 26 30 46 67 343
Quill, Dual Queue Enabled, Unbounded Queue 20 22 26 30 46 66 242
Quill, Dual Queue Disabled, Unbounded Queue 21 28 33 38 64 79 4207
PlatformLab NanoLog 18 21 23 24 42 58 223
MS BinLog 45 46 48 49 75 125 271
Reckless 93 117 125 129 163 358 30186464
Iyengar NanoLog 115 156 191 214 299 441 1142546
spdlog 335 537 714 796 1081 1534 27378
g3log 2834 2929 3032 3132 5081 5994 26563

Log Numbers and Large Strings

The following message is logged 100'000 times per thread LOG_INFO(logger, "Logging int: {}, int: {}, string: {}", i, j, large_string). The large string is over 35 characters to avoid short string optimisation of std::string

1 Thread

Library 50th 75th 90th 95th 99th 99.9th Worst
Quill, Dual Queue Enabled, Bounded Queue 26 31 37 40 48 73 136
Quill, Dual Queue Enabled, Unbounded Queue 28 33 39 42 59 79 138
Quill, Dual Queue Disabled, Unbounded Queue 195 211 224 232 251 283 325
PlatformLab NanoLog 29 34 39 54 57 77 178
MS BinLog 51 53 56 58 75 131 343
Reckless 94 96 102 117 155 176 6924627
Iyengar NanoLog 111 119 127 131 172 319 9553
spdlog 231 253 269 282 587 806 1055
g3log 1122 1142 1368 2293 2516 2698 4051

4 Threads

Library 50th 75th 90th 95th 99th 99.9th Worst
Quill, Dual Queue Enabled, Bounded Queue 27 32 38 45 59 82 440
Quill, Dual Queue Enabled, Unbounded Queue 26 32 38 46 60 106 3866
Quill, Dual Queue Disabled, Unbounded Queue 203 226 243 252 269 300 4278
PlatformLab NanoLog 29 34 47 55 59 69 289
MS BinLog 51 54 58 62 96 133 375
Reckless 115 134 157 172 216 377 30721857
Iyengar NanoLog 111 121 137 175 231 811 32100
spdlog 266 309 593 672 911 1329 13600
g3log 1816 2207 2389 2497 3457 4211 8365

The benchmarks are done on Linux (Ubuntu/RHEL) with GCC 8.1.

Each thread is pinned on a different cpu. Unfortunately the cores are not isolated. Running the backend logger thread in the same CPU as the caller hot-path threads, slows down the log message processing on the backend logging thread and will cause the SPSC queue to fill faster and re-allocate.

Continuously Logging messages in a loop makes the consumer (backend logging thread) unable to follow up and the queue will have to re-allocate or block for most logging libraries expect very high throughput binary loggers like PlatformLab Nanolog. Therefore, a different approach was followed that suits more to a real time application:

  1. 20 messages are logged in a loop.
  2. calculate/store the average latency for those messages.
  3. wait between 1-2 ms.
  4. repeat for n iterations.

I run each logger benchmark four times and the above latencies are the second best result.

The benchmark code and results can be found here.

Supported Platforms And Compilers

Quill requires a C++14 compiler. Minimum required versions of supported compilers are shown in the below table.

Compiler Notes
GCC version >= 5.0
Clang version >= 5.0
MSVC++ version >= 14.3
Platform Notes
Linux Ubuntu, RHEL, Centos, Fedora
Windows Windows 10 - version 1607, Windows Server 2016
macOS Tested with Xcode 9.4

Basic usage

#include "quill/Quill.h"

int main()
{
  quill::enable_console_colours();
  quill::start();

  quill::Logger* logger = quill::get_logger();
  logger->set_log_level(quill::LogLevel::TraceL3);

  // enable a backtrace that will get flushed when we log CRITICAL
  logger->init_backtrace(2, quill::LogLevel::Critical);

  LOG_BACKTRACE(logger, "Backtrace log {}", 1);
  LOG_BACKTRACE(logger, "Backtrace log {}", 2);

  LOG_INFO(logger, "Welcome to Quill!");
  LOG_ERROR(logger, "An error message. error code {}", 123);
  LOG_WARNING(logger, "A warning message.");
  LOG_CRITICAL(logger, "A critical error.");
  LOG_DEBUG(logger, "Debugging foo {}", 1234);
  LOG_TRACE_L1(logger, "{:>30}", "right aligned");
  LOG_TRACE_L2(logger, "Positional arguments are {1} {0} ", "too", "supported");
  LOG_TRACE_L3(logger, "Support for floats {:03.2f}", 1.23456);
}

Output

Screenshot-2020-08-14-at-01-09-43.png

CMake-Integration

External

Building and Installing Quill as Static Library
git clone https://github.com/odygrd/quill.git
mkdir cmake_build
cd cmake_build
make install

Note: To install in custom directory invoke cmake with -DCMAKE_INSTALL_PREFIX=/quill/install-dir/

Building and Installing Quill as Static Library With External libfmt
cmake -DCMAKE_PREFIX_PATH=/my/fmt/fmt-config.cmake-directory/ -DQUILL_FMT_EXTERNAL=ON -DCMAKE_INSTALL_PREFIX=/quill/install-dir/'

Then use the library from a CMake project, you can locate it directly with find_package()

Directory Structure
my_project/
├── CMakeLists.txt
├── main.cpp
CMakeLists.txt
# Set only if needed - quill was installed under a custom non-standard directory
set(CMAKE_PREFIX_PATH /test_quill/usr/local/)

find_package(quill REQUIRED)

# Linking your project against quill
add_executable(example main.cpp)
target_link_libraries(example PRIVATE quill::quill)
main.cpp

See basic usage

Embedded

To embed the library directly, copy the source folder to your project and call add_subdirectory() in your CMakeLists.txt file

Directory Structure
my_project/
├── quill/            (source folder)
├── CMakeLists.txt
├── main.cpp
CMakeLists.txt
cmake_minimum_required(VERSION 3.1.0)
project(my_project)

set(CMAKE_CXX_STANDARD 14)

add_subdirectory(quill)

add_executable(my_project main.cpp)
target_link_libraries(my_project PRIVATE quill::quill)
main.cpp

See basic usage

Documentation

Advanced usage and additional documentation can be found in the wiki pages.

The examples folder is also a good source of documentation.

License

Quill is licensed under the MIT License

Quill depends on third party libraries with separate copyright notices and license terms. Your use of the source code for these subcomponents is subject to the terms and conditions of the following licenses.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].