mirror of
https://github.com/gabime/spdlog.git
synced 2024-11-15 16:35:45 +08:00
266 lines
16 KiB
HTML
266 lines
16 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en-us">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>Spdlog by gabime</title>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<link rel="stylesheet" type="text/css" href="stylesheets/normalize.css" media="screen">
|
|
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,700' rel='stylesheet' type='text/css'>
|
|
<link rel="stylesheet" type="text/css" href="stylesheets/stylesheet.css" media="screen">
|
|
<link rel="stylesheet" type="text/css" href="stylesheets/github-light.css" media="screen">
|
|
</head>
|
|
<body>
|
|
<section class="page-header">
|
|
<h1 class="project-name">Spdlog</h1>
|
|
<h2 class="project-tagline">Super fast C++ logging library.</h2>
|
|
<a href="https://github.com/gabime/spdlog" class="btn">View on GitHub</a>
|
|
<a href="https://github.com/gabime/spdlog/zipball/master" class="btn">Download .zip</a>
|
|
<a href="https://github.com/gabime/spdlog/tarball/master" class="btn">Download .tar.gz</a>
|
|
</section>
|
|
|
|
<section class="main-content">
|
|
<h1>
|
|
<a id="spdlog" class="anchor" href="#spdlog" aria-hidden="true"><span class="octicon octicon-link"></span></a>spdlog</h1>
|
|
|
|
<p>Very fast, header only, C++ logging library.</p>
|
|
|
|
<h2>
|
|
<a id="install" class="anchor" href="#install" aria-hidden="true"><span class="octicon octicon-link"></span></a>Install</h2>
|
|
|
|
<p>Just copy the files to your build tree and use a C++11 compiler</p>
|
|
|
|
<h2>
|
|
<a id="tested-on" class="anchor" href="#tested-on" aria-hidden="true"><span class="octicon octicon-link"></span></a>Tested on:</h2>
|
|
|
|
<ul>
|
|
<li>gcc 4.8.1 and above</li>
|
|
<li>clang 3.5 (Linux and OSX)</li>
|
|
<li>visual studio 2013</li>
|
|
<li>mingw with g++ 4.9.x</li>
|
|
</ul>
|
|
|
|
<h2>
|
|
<a id="features" class="anchor" href="#features" aria-hidden="true"><span class="octicon octicon-link"></span></a>Features</h2>
|
|
|
|
<ul>
|
|
<li>Very fast - performance is the primary goal (see <a href="#benchmarks">benchmarks</a> below).</li>
|
|
<li>Headers only.</li>
|
|
<li>No dependencies - just copy and use.</li>
|
|
<li>Cross platform - Linux / Windows on 32/64 bits.</li>
|
|
<li>
|
|
<strong>new!</strong> Feature rich <a href="#usage-example">call style</a> using the excellent <a href="http://cppformat.github.io/">cppformat</a> library.</li>
|
|
<li>ostream call style is supported too.</li>
|
|
<li>Extremely fast asynchronous mode (optional) - using lockfree queues and other tricks to reach millions of calls/sec.</li>
|
|
<li>
|
|
<a href="https://github.com/gabime/spdlog/wiki/Custom-formatting">Custom</a> formatting.</li>
|
|
<li>Multi/Single threaded loggers.</li>
|
|
<li>Various log targets:
|
|
|
|
<ul>
|
|
<li>Rotating log files.</li>
|
|
<li>Daily log files.</li>
|
|
<li>Console logging.</li>
|
|
<li>Linux syslog.</li>
|
|
<li>Easily extendable with custom log targets (just implement a single function in the <a href="include/spdlog/sinks/sink.h">sink</a> interface).</li>
|
|
</ul>
|
|
</li>
|
|
<li>Severity based filtering - threshold levels can be modified in runtime as well as in compile time.</li>
|
|
</ul>
|
|
|
|
<h2>
|
|
<a id="benchmarks" class="anchor" href="#benchmarks" aria-hidden="true"><span class="octicon octicon-link"></span></a>Benchmarks</h2>
|
|
|
|
<p>Below are some <a href="bench">benchmarks</a> comparing popular log libraries under Ubuntu 64 bit, Intel i7-4770 CPU @ 3.40GHz </p>
|
|
|
|
<h4>
|
|
<a id="synchronous-mode" class="anchor" href="#synchronous-mode" aria-hidden="true"><span class="octicon octicon-link"></span></a>Synchronous mode</h4>
|
|
|
|
<p>Time needed to log 1,000,000 lines in synchronous mode (in seconds, the best of 3 runs):</p>
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>threads</th>
|
|
<th align="center">boost log</th>
|
|
<th align="center">glog</th>
|
|
<th align="right">easylogging</th>
|
|
<th align="right">spdlog</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>1</td>
|
|
<td align="center">4.169s</td>
|
|
<td align="center">1.066s</td>
|
|
<td align="right">0.975s</td>
|
|
<td align="right">0.302s</td>
|
|
</tr>
|
|
<tr>
|
|
<td>10</td>
|
|
<td align="center">16.029</td>
|
|
<td align="center">3.032s</td>
|
|
<td align="right">2.857s</td>
|
|
<td align="right">0.968s</td>
|
|
</tr>
|
|
<tr>
|
|
<td>100</td>
|
|
<td align="center">15.008</td>
|
|
<td align="center">1.139s</td>
|
|
<td align="right">4.512s</td>
|
|
<td align="right">0.497s</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<h4>
|
|
<a id="asynchronous-mode" class="anchor" href="#asynchronous-mode" aria-hidden="true"><span class="octicon octicon-link"></span></a>Asynchronous mode</h4>
|
|
|
|
<p>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):</p>
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left">threads</th>
|
|
<th align="center">g2log <sup>async logger</sup>
|
|
</th>
|
|
<th align="right">spdlog <sup>async mode</sup>
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left">1</td>
|
|
<td align="center">1.850s</td>
|
|
<td align="right">0.216s</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">10</td>
|
|
<td align="center">0.943s</td>
|
|
<td align="right">0.173s</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">100</td>
|
|
<td align="center">0.959s</td>
|
|
<td align="right">0.202s</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<h2>
|
|
<a id="usage-example" class="anchor" href="#usage-example" aria-hidden="true"><span class="octicon octicon-link"></span></a>Usage Example</h2>
|
|
|
|
<div class="highlight highlight-c++"><pre>#<span class="pl-k">include</span> <span class="pl-s"><span class="pl-pds"><</span>iostream<span class="pl-pds">></span></span>
|
|
#<span class="pl-k">include</span> <span class="pl-s"><span class="pl-pds">"</span>spdlog/spdlog.h<span class="pl-pds">"</span></span>
|
|
|
|
<span class="pl-k">int</span> <span class="pl-en">main</span>(<span class="pl-k">int</span>, <span class="pl-k">char</span>* [])
|
|
{
|
|
<span class="pl-k">namespace</span> <span class="pl-en">spd</span> <span class="pl-k">=</span> spdlog;
|
|
<span class="pl-k">try</span>
|
|
{
|
|
<span class="pl-c">//Create console, multithreaded logger</span>
|
|
<span class="pl-k">auto</span> console = <span class="pl-c1">spd::stdout_logger_mt</span>(<span class="pl-s"><span class="pl-pds">"</span>console<span class="pl-pds">"</span></span>);
|
|
console-><span class="pl-c1">info</span>(<span class="pl-s"><span class="pl-pds">"</span>Welcome to spdlog!<span class="pl-pds">"</span></span>) ;
|
|
console-><span class="pl-c1">info</span>(<span class="pl-s"><span class="pl-pds">"</span>An info message example {}..<span class="pl-pds">"</span></span>, <span class="pl-c1">1</span>);
|
|
console-><span class="pl-c1">info</span>() << <span class="pl-s"><span class="pl-pds">"</span>Streams are supported too <span class="pl-pds">"</span></span> << <span class="pl-c1">1</span>;
|
|
|
|
<span class="pl-c">//Formatting examples</span>
|
|
console-><span class="pl-c1">info</span>(<span class="pl-s"><span class="pl-pds">"</span>Easy padding in numbers like {:08d}<span class="pl-pds">"</span></span>, <span class="pl-c1">12</span>);
|
|
console-><span class="pl-c1">info</span>(<span class="pl-s"><span class="pl-pds">"</span>Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}<span class="pl-pds">"</span></span>, <span class="pl-c1">42</span>);
|
|
console-><span class="pl-c1">info</span>(<span class="pl-s"><span class="pl-pds">"</span>Support for floats {:03.2f}<span class="pl-pds">"</span></span>, <span class="pl-c1">1.23456</span>);
|
|
console-><span class="pl-c1">info</span>(<span class="pl-s"><span class="pl-pds">"</span>Positional args are {1} {0}..<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>too<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>supported<span class="pl-pds">"</span></span>);
|
|
|
|
console-><span class="pl-c1">info</span>(<span class="pl-s"><span class="pl-pds">"</span>{:<30}<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>left aligned<span class="pl-pds">"</span></span>);
|
|
console-><span class="pl-c1">info</span>(<span class="pl-s"><span class="pl-pds">"</span>{:>30}<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>right aligned<span class="pl-pds">"</span></span>);
|
|
console-><span class="pl-c1">info</span>(<span class="pl-s"><span class="pl-pds">"</span>{:^30}<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>centered<span class="pl-pds">"</span></span>);
|
|
|
|
<span class="pl-c">//</span>
|
|
<span class="pl-c">// Runtime log levels</span>
|
|
<span class="pl-c">//</span>
|
|
<span class="pl-c1">spd::set_level</span>(spd::level::info); <span class="pl-c">//Set global log level to info</span>
|
|
console-><span class="pl-c1">debug</span>(<span class="pl-s"><span class="pl-pds">"</span>This message shold not be displayed!<span class="pl-pds">"</span></span>);
|
|
console-><span class="pl-c1">set_level</span>(spd::level::debug); <span class="pl-c">// Set specific logger's log level</span>
|
|
console-><span class="pl-c1">debug</span>(<span class="pl-s"><span class="pl-pds">"</span>Now it should..<span class="pl-pds">"</span></span>);
|
|
|
|
<span class="pl-c">//</span>
|
|
<span class="pl-c">// Create a file rotating logger with 5mb size max and 3 rotated files</span>
|
|
<span class="pl-c">//</span>
|
|
<span class="pl-k">auto</span> file_logger = <span class="pl-c1">spd::rotating_logger_mt</span>(<span class="pl-s"><span class="pl-pds">"</span>file_logger<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>logs/mylogfile<span class="pl-pds">"</span></span>, <span class="pl-c1">1048576</span> * <span class="pl-c1">5</span>, <span class="pl-c1">3</span>);
|
|
<span class="pl-k">for</span>(<span class="pl-k">int</span> i = <span class="pl-c1">0</span>; i < <span class="pl-c1">10</span>; ++i)
|
|
file_logger-><span class="pl-c1">info</span>(<span class="pl-s"><span class="pl-pds">"</span>{} * {} equals {:>10}<span class="pl-pds">"</span></span>, i, i, i*i);
|
|
|
|
<span class="pl-c">//</span>
|
|
<span class="pl-c">// Create a daily logger - a new file is created every day on 2:30am</span>
|
|
<span class="pl-c">//</span>
|
|
<span class="pl-k">auto</span> daily_logger = <span class="pl-c1">spd::daily_logger_mt</span>(<span class="pl-s"><span class="pl-pds">"</span>daily_logger<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>logs/daily<span class="pl-pds">"</span></span>, <span class="pl-c1">2</span>, <span class="pl-c1">30</span>);
|
|
|
|
<span class="pl-c">// </span>
|
|
<span class="pl-c">// Customize msg format for all messages</span>
|
|
<span class="pl-c">//</span>
|
|
<span class="pl-c1">spd::set_pattern</span>(<span class="pl-s"><span class="pl-pds">"</span>*** [<span class="pl-ii">%</span>H:<span class="pl-ii">%</span>M:<span class="pl-c1">%S</span> <span class="pl-ii">%</span>z] [thread <span class="pl-ii">%</span>t] <span class="pl-ii">%</span>v ***<span class="pl-pds">"</span></span>);
|
|
file_logger-><span class="pl-c1">info</span>(<span class="pl-s"><span class="pl-pds">"</span>This is another message with custom format<span class="pl-pds">"</span></span>);
|
|
|
|
<span class="pl-c1">spd::get</span>(<span class="pl-s"><span class="pl-pds">"</span>console<span class="pl-pds">"</span></span>)-><span class="pl-c1">info</span>(<span class="pl-s"><span class="pl-pds">"</span>loggers can be retrieved from a global registry using the spdlog::get(logger_name) function<span class="pl-pds">"</span></span>);
|
|
|
|
<span class="pl-c">//</span>
|
|
<span class="pl-c">// Compile time debug or trace macros.</span>
|
|
<span class="pl-c">// Enabled #ifdef SPDLOG_DEBUG_ON or #ifdef SPDLOG_TRACE_ON</span>
|
|
<span class="pl-c">//</span>
|
|
<span class="pl-c1">SPDLOG_TRACE</span>(console, <span class="pl-s"><span class="pl-pds">"</span>Enabled only #ifdef SPDLOG_TRACE_ON..{} ,{}<span class="pl-pds">"</span></span>, <span class="pl-c1">1</span>, <span class="pl-c1">3.23</span>);
|
|
<span class="pl-c1">SPDLOG_DEBUG</span>(console, <span class="pl-s"><span class="pl-pds">"</span>Enabled only #ifdef SPDLOG_DEBUG_ON.. {} ,{}<span class="pl-pds">"</span></span>, <span class="pl-c1">1</span>, <span class="pl-c1">3.23</span>);
|
|
|
|
<span class="pl-c">//</span>
|
|
<span class="pl-c">// Asynchronous logging is very fast..</span>
|
|
<span class="pl-c">// Just call spdlog::set_async_mode(q_size) and all created loggers from now on will be asynchronous..</span>
|
|
<span class="pl-c">//</span>
|
|
<span class="pl-c1">size_t</span> q_size = <span class="pl-c1">1048576</span>; <span class="pl-c">//queue size must be power of 2</span>
|
|
<span class="pl-c1">spdlog::set_async_mode</span>(q_size);
|
|
<span class="pl-k">auto</span> async_file= <span class="pl-c1">spd::daily_logger_st</span>(<span class="pl-s"><span class="pl-pds">"</span>async_file_logger<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>logs/async_log.txt<span class="pl-pds">"</span></span>);
|
|
async_file-><span class="pl-c1">info</span>() << <span class="pl-s"><span class="pl-pds">"</span>This is async log..<span class="pl-pds">"</span></span> << <span class="pl-s"><span class="pl-pds">"</span>Should be very fast!<span class="pl-pds">"</span></span>;
|
|
|
|
<span class="pl-c">// </span>
|
|
<span class="pl-c">// syslog example. linux only..</span>
|
|
<span class="pl-c">//</span>
|
|
#<span class="pl-k">ifdef</span> __linux__
|
|
std::string ident = <span class="pl-s"><span class="pl-pds">"</span>spdlog-example<span class="pl-pds">"</span></span>;
|
|
<span class="pl-k">auto</span> syslog_logger = <span class="pl-c1">spd::syslog_logger</span>(<span class="pl-s"><span class="pl-pds">"</span>syslog<span class="pl-pds">"</span></span>, ident, LOG_PID);
|
|
syslog_logger-><span class="pl-c1">warn</span>(<span class="pl-s"><span class="pl-pds">"</span>This is warning that will end up in syslog. This is Linux only!<span class="pl-pds">"</span></span>);
|
|
#<span class="pl-k">endif</span>
|
|
}
|
|
<span class="pl-k">catch</span> (<span class="pl-k">const</span> spd::spdlog_ex& ex)
|
|
{
|
|
std::cout << <span class="pl-s"><span class="pl-pds">"</span>Log failed: <span class="pl-pds">"</span></span> << ex.<span class="pl-c1">what</span>() << std::endl;
|
|
}
|
|
}
|
|
|
|
|
|
<span class="pl-c">// Example of user defined class with operator<<</span>
|
|
<span class="pl-k">class</span> <span class="pl-en">some_class</span> {};
|
|
std::ostream& <span class="pl-k">operator</span><<(std::ostream& os, <span class="pl-k">const</span> some_class& c) { <span class="pl-k">return</span> os << <span class="pl-s"><span class="pl-pds">"</span>some_class<span class="pl-pds">"</span></span>; }
|
|
|
|
<span class="pl-k">void</span> <span class="pl-en">custom_class_example</span>()
|
|
{
|
|
some_class c;
|
|
<span class="pl-c1">spdlog::get</span>(<span class="pl-s"><span class="pl-pds">"</span>console<span class="pl-pds">"</span></span>)-><span class="pl-c1">info</span>(<span class="pl-s"><span class="pl-pds">"</span>custom class with operator<<: {}..<span class="pl-pds">"</span></span>, c);
|
|
<span class="pl-c1">spdlog::get</span>(<span class="pl-s"><span class="pl-pds">"</span>console<span class="pl-pds">"</span></span>)-><span class="pl-c1">info</span>() << <span class="pl-s"><span class="pl-pds">"</span>custom class with operator<<: <span class="pl-pds">"</span></span> << c << <span class="pl-s"><span class="pl-pds">"</span>..<span class="pl-pds">"</span></span>;
|
|
}</pre></div>
|
|
|
|
<h2>
|
|
<a id="tweaking" class="anchor" href="#tweaking" aria-hidden="true"><span class="octicon octicon-link"></span></a>Tweaking</h2>
|
|
|
|
<p>spdlog can be tweaked to improve performance even more.</p>
|
|
|
|
<p>Edit <a href="include/spdlog/tweakme.h">this</a> file to disable at compile time unneeded features.</p>
|
|
|
|
<footer class="site-footer">
|
|
<span class="site-footer-owner"><a href="https://github.com/gabime/spdlog">Spdlog</a> is maintained by <a href="https://github.com/gabime">gabime</a>.</span>
|
|
|
|
<span class="site-footer-credits">This page was generated by <a href="https://pages.github.com">GitHub Pages</a> using the <a href="https://github.com/jasonlong/cayman-theme">Cayman theme</a> by <a href="https://twitter.com/jasonlong">Jason Long</a>.</span>
|
|
</footer>
|
|
|
|
</section>
|
|
|
|
|
|
</body>
|
|
</html>
|
|
|