README.md 5.8 KB
Newer Older
gabime's avatar
gabime committed
1 2
# spdlog

3
Very fast, header only, C++ logging library. [![Build Status](https://travis-ci.org/gabime/spdlog.svg?branch=master)](https://travis-ci.org/gabime/spdlog)
gabime's avatar
gabime committed
4 5

## Install
Gabi Melman's avatar
Gabi Melman committed
6
Just copy the source [folder](https://github.com/gabime/spdlog/tree/master/include/spdlog) to your build tree and use a C++11 compiler
gabime's avatar
gabime committed
7

Gabi Melman's avatar
Gabi Melman committed
8 9
## Platforms
 * Linux (gcc 4.8.1+, clang 3.5+)
Gabi Melman's avatar
Gabi Melman committed
10
 * Windows (visual studio 2013+, cygwin/mingw with g++ 4.9.1+)
Gabi Melman's avatar
Gabi Melman committed
11
 * Mac OSX (clang 3.5+)
12

gabime's avatar
gabime committed
13
##Features
ruipacheco's avatar
ruipacheco committed
14
* Very fast - performance is the primary goal (see [benchmarks](#benchmarks) below).
Gabi Melman's avatar
Gabi Melman committed
15
* Headers only.
Gabi Melman's avatar
Gabi Melman committed
16
* No dependencies - just copy and use.
Gabi Melman's avatar
Gabi Melman committed
17
* Feature rich [call style](#usage-example) using the excellent [cppformat](http://cppformat.github.io/) library.
Gabi Melman's avatar
Gabi Melman committed
18
* ostream call style is supported too.
Gabi Melman's avatar
Gabi Melman committed
19
* Extremely fast asynchronous mode (optional) - using lockfree queues and other tricks to reach millions of calls/sec.
Gabi Melman's avatar
Gabi Melman committed
20
* [Custom](https://github.com/gabime/spdlog/wiki/3.-Custom-formatting) formatting.
Gabi Melman's avatar
Gabi Melman committed
21 22 23 24 25 26 27
* Multi/Single threaded loggers.
* Various log targets:
    * Rotating log files.
    * Daily log files.
    * Console logging.
    * Linux syslog.
    * Easily extendable with custom log targets  (just implement a single function in the [sink](include/spdlog/sinks/sink.h) interface).
Gabi Melman's avatar
Gabi Melman committed
28
* Severity based filtering - threshold levels can be modified in runtime as well as in compile time.
Gabi Melman's avatar
Gabi Melman committed
29 30 31



Gabi Melman's avatar
Gabi Melman committed
32
## Benchmarks
Gabi Melman's avatar
Gabi Melman committed
33

34
Below are some [benchmarks](bench) comparing popular log libraries under Ubuntu 64 bit, Intel i7-4770 CPU @ 3.40GHz
Gabi Melman's avatar
Gabi Melman committed
35

Gabi Melman's avatar
Gabi Melman committed
36
#### Synchronous mode
Gabi Melman's avatar
Gabi Melman committed
37
Time needed to log 1,000,000 lines in synchronous mode (in seconds, the best of 3 runs):
Gabi Melman's avatar
Gabi Melman committed
38

Gabi Melman's avatar
Gabi Melman committed
39
|threads|boost log 1.54|glog   |easylogging |spdlog|
40
|-------|:-------:|:-----:|----------:|------:|
Gabi Melman's avatar
Gabi Melman committed
41
|1|       4.169s  |1.066s |0.975s     |0.302s|
Gabi Melman's avatar
Gabi Melman committed
42 43
|10|     6.180s   |3.032s |2.857s     |0.968s|
|100|     5.981s  |1.139s |4.512s     |0.497s|
44 45


46
#### Asynchronous mode
Gabi Melman's avatar
Gabi Melman committed
47
Time needed to log 1,000,000 lines in asynchronous mode, i.e. the time it takes to put them in the async queue (in seconds, the best of 3 runs):
Gabi Melman's avatar
Gabi Melman committed
48

Gabi Melman's avatar
Gabi Melman committed
49
|threads|g2log <sup>async logger</sup>   |spdlog <sup>async mode</sup>|
Gabi Melman's avatar
Gabi Melman committed
50 51 52
|:-------|:-----:|-------------------------:|
|1|       1.850s |0.216s |
|10|      0.943s  |0.173s|
Gabi Melman's avatar
Gabi Melman committed
53
|100|      0.959s |0.202s|
54 55


Gabi Melman's avatar
Gabi Melman committed
56

Gabi Melman's avatar
Gabi Melman committed
57

gabime's avatar
gabime committed
58
## Usage Example
Gabi Melman's avatar
Gabi Melman committed
59
```c++
gabime's avatar
gabime committed
60 61 62 63 64 65 66 67
#include <iostream>
#include "spdlog/spdlog.h"

int main(int, char* [])
{
    namespace spd = spdlog;
    try
    {
Gabi Melman's avatar
Gabi Melman committed
68
        //Create console, multithreaded logger
gabi's avatar
gabi committed
69
        auto console = spd::stdout_logger_mt("console");
gabime's avatar
gabime committed
70
        console->info("Welcome to spdlog!") ;
Gabi Melman's avatar
Gabi Melman committed
71 72
        console->info("An info message example {}..", 1);
        console->info() << "Streams are supported too  " << 1;
73

Gabi Melman's avatar
Gabi Melman committed
74
        //Formatting examples
Gabi Melman's avatar
Gabi Melman committed
75
        console->info("Easy padding in numbers like {:08d}", 12);
Gabi Melman's avatar
Gabi Melman committed
76
        console->info("Support for int: {0:d};  hex: {0:x};  oct: {0:o}; bin: {0:b}", 42);
Gabi Melman's avatar
Gabi Melman committed
77 78 79
        console->info("Support for floats {:03.2f}", 1.23456);
        console->info("Positional args are {1} {0}..", "too", "supported");

Gabi Melman's avatar
Gabi Melman committed
80 81 82
        console->info("{:<30}", "left aligned");
        console->info("{:>30}", "right aligned");
        console->info("{:^30}", "centered");
83

Gabi Melman's avatar
Gabi Melman committed
84 85
        //
        // Runtime log levels
Gabi Melman's avatar
Gabi Melman committed
86
        //
Gabi Melman's avatar
Gabi Melman committed
87 88
        spd::set_level(spd::level::info); //Set global log level to info
        console->debug("This message shold not be displayed!");
Gabi Melman's avatar
Gabi Melman committed
89 90
        console->set_level(spd::level::debug); // Set specific logger's log level
        console->debug("Now it should..");
91

Gabi Melman's avatar
Gabi Melman committed
92
        //
Gabi Melman's avatar
Gabi Melman committed
93
        // Create a file rotating logger with 5mb size max and 3 rotated files
Gabi Melman's avatar
Gabi Melman committed
94
        //
Gabi Melman's avatar
Gabi Melman committed
95
        auto file_logger = spd::rotating_logger_mt("file_logger", "logs/mylogfile", 1048576 * 5, 3);
Gabi Melman's avatar
Gabi Melman committed
96 97
        for(int i = 0; i < 10; ++i)
		      file_logger->info("{} * {} equals {:>10}", i, i, i*i);
Gabi Melman's avatar
Gabi Melman committed
98

99 100 101 102
        //
        // Create a daily logger - a new file is created every day on 2:30am
        //
        auto daily_logger = spd::daily_logger_mt("daily_logger", "logs/daily", 2, 30);
103 104

        //
Gabi Melman's avatar
Gabi Melman committed
105
        // Customize msg format for all messages
Gabi Melman's avatar
Gabi Melman committed
106
        //
Gabi Melman's avatar
Gabi Melman committed
107 108 109 110 111
        spd::set_pattern("*** [%H:%M:%S %z] [thread %t] %v ***");
        file_logger->info("This is another message with custom format");

        spd::get("console")->info("loggers can be retrieved from a global registry using the spdlog::get(logger_name) function");

Gabi Melman's avatar
Gabi Melman committed
112 113 114 115
        //
        // Compile time debug or trace macros.
        // Enabled #ifdef SPDLOG_DEBUG_ON or #ifdef SPDLOG_TRACE_ON
        //
gabi's avatar
gabi committed
116 117
        SPDLOG_TRACE(console, "Enabled only #ifdef SPDLOG_TRACE_ON..{} ,{}", 1, 3.23);
        SPDLOG_DEBUG(console, "Enabled only #ifdef SPDLOG_DEBUG_ON.. {} ,{}", 1, 3.23);
118

Gabi Melman's avatar
Gabi Melman committed
119
        //
Gabi Melman's avatar
Gabi Melman committed
120 121
        // Asynchronous logging is very fast..
        // Just call spdlog::set_async_mode(q_size) and all created loggers from now on will be asynchronous..
Gabi Melman's avatar
Gabi Melman committed
122
        //
Gabi Melman's avatar
Gabi Melman committed
123 124
        size_t q_size = 1048576; //queue size must be power of 2
        spdlog::set_async_mode(q_size);
Gabi Melman's avatar
Gabi Melman committed
125 126
        auto async_file= spd::daily_logger_st("async_file_logger", "logs/async_log.txt");
        async_file->info() << "This is async log.." << "Should be very fast!";
127 128

        //
gabime's avatar
gabime committed
129
        // syslog example. linux only..
Gabi Melman's avatar
Gabi Melman committed
130
        //
gabime's avatar
gabime committed
131
        #ifdef __linux__
gabime's avatar
gabime committed
132 133
        std::string ident = "spdlog-example";
        auto syslog_logger = spd::syslog_logger("syslog", ident, LOG_PID);
134
        syslog_logger->warn("This is warning that will end up in syslog. This is Linux only!");
gabime's avatar
gabime committed
135
        #endif
gabime's avatar
gabime committed
136 137 138 139 140 141
    }
    catch (const spd::spdlog_ex& ex)
    {
        std::cout << "Log failed: " << ex.what() << std::endl;
    }
}
142 143 144 145 146 147 148 149 150 151 152 153


// Example of user defined class with operator<<
class some_class {};
std::ostream& operator<<(std::ostream& os, const some_class& c) { return os << "some_class"; }

void custom_class_example()
{
    some_class c;
    spdlog::get("console")->info("custom class with operator<<: {}..", c);
    spdlog::get("console")->info() << "custom class with operator<<: " << c << "..";
}
gabime's avatar
gabime committed
154
```
Gabi Melman's avatar
Gabi Melman committed
155

Gabi Melman's avatar
Gabi Melman committed
156
## Documentation
Gabi Melman's avatar
Gabi Melman committed
157
Documentation can be found in the [wiki](https://github.com/gabime/spdlog/wiki/1.-QuickStart) pages.