[TOC]
spdlog使用(1.8.2)
参考文档:
https://blog.csdn.net/fengbingchun/article/details/78347105 https://blog.csdn.net/libaineu2004/article/details/104096206 https://github.com/gabime/spdlog/tree/v1.x
spdlog简介
spdlog是一个开源的、快速的、仅有头文件的C++11 日志库,code地址在:https://github.com/gabime/spdlog
。
它提供了向流、标准输出、文件、系统日志、调试器等目标输出日志的能力。它支持的平台包括Windows、Linux、Mac、Android。
spdlog特性:
- 非常快,性能是它的主要目标;
- 仅包括头文件;
- 日志的格式化处理使用开源的fmt库(
https://github.com/fmtlib/fmt
); - 可选的printf语法支持;
- 非常快的异步模式(可选),支持异步写日志;
- 自定义格式;
- 条件日志;
- 多线程/单线程日志;
- 各种日志目标:可对日志文件进行循环输出;可每日生成日志文件;支持控制台日志输出(支持颜色);系统日志;Windows debugger;较容易扩展自定义日志目标;
- 支持日志输出级别:阈值级别既可以在运行时也可以在编译时修改。
spdlog 日志输出格式
设置输出行号
[%Y-%m-%d %H:%M:%S.%e] [%n] [%^---%L---%$] [%l] [thread %t] [%@,%!]: %v
[%@,%!]
为代码行号。
注意: 只有这种SPDLOG_DEBUG
宏方式,才会输出行号
#include "spdlog/spdlog.h"
int main() {
spdlog::set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%n] [%^---%L---%$] [%l] [thread %t] [%@,%!]: %v");
spdlog::info("Welcome to spdlog!");
spdlog::error("Some error message with arg: {}", 1);
// Compile time log levels
// define SPDLOG_ACTIVE_LEVEL to desired level
SPDLOG_TRACE(console, "Some trace message with param {}", 42);
SPDLOG_DEBUG("Some debug message");
}
编译:
colcon build --merge-install --cmake-args -DCMAKE_CXX_FLAGS:=-DSPDLOG_ACTIVE_LEVEL=1
输出:
[2021-01-19 11:59:09.185] [] [---I---] [info] [thread 20481] [,]: Welcome to spdlog!
[2021-01-19 11:59:09.185] [] [---E---] [error] [thread 20481] [,]: Some error message with arg: 1
[2021-01-19 11:59:09.185] [] [---D---] [debug] [thread 20481] [/data/Project/GitLab/LCPP/src/L/LSpdlog/src/demo/demo-1/src/main.cpp:24,main]: Some debug message
使用示例
SPDLOG_DEBUG
编译时,设置日志级别
设置日志级别的宏定义: spdlog/common.h
#define SPDLOG_LEVEL_TRACE 0
#define SPDLOG_LEVEL_DEBUG 1
#define SPDLOG_LEVEL_INFO 2
#define SPDLOG_LEVEL_WARN 3
#define SPDLOG_LEVEL_ERROR 4
#define SPDLOG_LEVEL_CRITICAL 5
#define SPDLOG_LEVEL_OFF 6
#if !defined(SPDLOG_ACTIVE_LEVEL)
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_INFO
#endif
cmake时设置日志级别:
colcon build --merge-install --cmake-args -DCMAKE_CXX_FLAGS:=-DSPDLOG_ACTIVE_LEVEL=1
简单示例,只需要头文件
LCPP/src/L/LSpdlog/src/demo/demo-1/src/main.cpp
#include "spdlog/spdlog.h"
int main() {
spdlog::info("Welcome to spdlog!");
spdlog::error("Some error message with arg: {}", 1);
spdlog::warn("Easy padding in numbers like {:08d}", 12);
spdlog::critical("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42);
spdlog::info("Support for floats {:03.2f}", 1.23456);
spdlog::info("Positional args are {1} {0}..", "too", "supported");
spdlog::info("{:<30}", "left aligned");
spdlog::set_level(spdlog::level::debug); // Set global log level to debug
spdlog::debug("This message should be displayed..");
// change log pattern
spdlog::set_pattern("[%H:%M:%S %z] [%n] [%^---%L---%$] [thread %t] %v");
// Compile time log levels
// define SPDLOG_ACTIVE_LEVEL to desired level
SPDLOG_TRACE("Some trace message with param {}", 42);
SPDLOG_DEBUG("Some debug message");
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project("spdlog-demo-1"
VERSION "1.0.0")
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
include_directories(${CMAKE_INSTALL_PREFIX}/include)
add_executable(spdlog_demo_1
src/main.cpp
)
编译:
colcon build --merge-install --cmake-args -DCMAKE_CXX_FLAGS:=-DSPDLOG_ACTIVE_LEVEL=1
输出:
[2021-01-18 17:09:34.030] [info] Welcome to spdlog!
[2021-01-18 17:09:34.030] [error] Some error message with arg: 1
[2021-01-18 17:09:34.030] [warning] Easy padding in numbers like 00000012
[2021-01-18 17:09:34.030] [critical] Support for int: 42; hex: 2a; oct: 52; bin: 101010
[2021-01-18 17:09:34.030] [info] Support for floats 1.23
[2021-01-18 17:09:34.030] [info] Positional args are supported too..
[2021-01-18 17:09:34.030] [info] left aligned
[2021-01-18 17:09:34.030] [debug] This message should be displayed..
[17:09:34 +08:00] [] [---D---] [thread 1992] Some debug message
Create stdout/stderr logger object
LCPP/src/L/LSpdlog/src/demo/demo-1/src/stdout_stderr_logger.cpp
#include "spdlog/spdlog.h"
#include "spdlog/sinks/stdout_color_sinks.h"
int main() {
// create color multi threaded logger
auto console = spdlog::stdout_color_mt("console");
auto err_logger = spdlog::stderr_color_mt("stderr");
spdlog::get("console")->info(
"loggers can be retrieved from a global registry using the spdlog::get(logger_name)");
spdlog::get("stderr")->info(
"loggers can be retrieved from a global registry using the spdlog::get(logger_name)");
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project("spdlog-demo-1"
VERSION "1.0.0")
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
include_directories(${CMAKE_INSTALL_PREFIX}/include)
add_executable(spdlog_stdout_err_1
src/stdout_stderr_logger.cpp
)
编译:
cd LCPP/src/L/LSpdlog
colcon build --merge-install --cmake-args -DCMAKE_CXX_FLAGS:=-DSPDLOG_ACTIVE_LEVEL=1
输出:
[2021-01-18 17:20:44.188] [console] [info] loggers can be retrieved from a global registry using the spdlog::get(logger_name)
[2021-01-18 17:20:44.188] [stderr] [info] loggers can be retrieved from a global registry using the spdlog::get(logger_name)
Basic file logger
LCPP/src/L/LSpdlog/src/demo/demo-1/src/basic_file_logger.cpp
#include <iostream>
#include "spdlog/spdlog.h"
#include "spdlog/sinks/basic_file_sink.h"
int main() {
try {
auto logger = spdlog::basic_logger_mt("basic_logger",
"logs/basic-log.txt");
logger->info("info message");
} catch (const spdlog::spdlog_ex &ex) {
std::cout << "Log init failed: " << ex.what() << std::endl;
}
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project("spdlog-demo-1"
VERSION "1.0.0")
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
include_directories(${CMAKE_INSTALL_PREFIX}/include)
add_executable(spdlog_basic_file_logger_1
src/basic_file_logger.cpp
)
编译:
cd LCPP/src/L/LSpdlog
colcon build --merge-install --cmake-args -DCMAKE_CXX_FLAGS:=-DSPDLOG_ACTIVE_LEVEL=1
输出logs/basic-log.txt
(自动创建目录和文件)
[2021-01-18 17:26:30.003] [basic_logger] [info] info message
Rotating Files logger
LCPP/src/L/LSpdlog/src/demo/demo-1/src/rotating_files_logger.cpp
#include <iostream>
#include "spdlog/spdlog.h"
#include "spdlog/sinks/rotating_file_sink.h"
int main() {
try {
auto max_size = 1048576 * 5;
auto max_files = 3;
auto logger = spdlog::rotating_logger_mt("some_logger_name",
"logs/rotating.txt", max_size, max_files);
logger->info("info message");
} catch (const spdlog::spdlog_ex &ex) {
std::cout << "Log init failed: " << ex.what() << std::endl;
}
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project("spdlog-demo-1"
VERSION "1.0.0")
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
include_directories(${CMAKE_INSTALL_PREFIX}/include)
add_executable(spdlog_rotating_files_logger_1
src/rotating_files_logger.cpp
)
编译:
cd LCPP/src/L/LSpdlog
colcon build --merge-install --cmake-args -DCMAKE_CXX_FLAGS:=-DSPDLOG_ACTIVE_LEVEL=1
输出logs/rotating.txt
(自动创建目录和文件)
[2021-01-18 17:35:48.014] [some_logger_name] [info] info message
Daily files logger
LCPP/src/L/LSpdlog/src/demo/demo-1/src/daily_files_logger.cpp
#include <iostream>
#include "spdlog/spdlog.h"
#include "spdlog/sinks/daily_file_sink.h"
int main() {
try {
auto hour = 2;
auto minute = 30;
auto logger = spdlog::daily_logger_mt("daily_logger",
"logs/daily.txt", hour, minute);
logger->info("info message");
} catch (const spdlog::spdlog_ex &ex) {
std::cout << "Log init failed: " << ex.what() << std::endl;
}
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project("spdlog-demo-1"
VERSION "1.0.0")
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
include_directories(${CMAKE_INSTALL_PREFIX}/include)
add_executable(spdlog_daily_files_logger_1
src/daily_files_logger.cpp
)
编译:
cd LCPP/src/L/LSpdlog
colcon build --merge-install --cmake-args -DCMAKE_CXX_FLAGS:=-DSPDLOG_ACTIVE_LEVEL=1
输出logs/daily_2021-01-18.txt
(自动创建目录和文件)
[2021-01-18 17:43:15.119] [daily_logger] [info] info message
Backtrace support
Loggers can store in a ring buffer all messages (including debug/trace) and display later on demand. When needed, call dump_backtrace() to see them.
LCPP/src/L/LSpdlog/src/demo/demo-1/src/backtrace_support_logger.cpp
#include <iostream>
#include "spdlog/spdlog.h"
#include "spdlog/sinks/daily_file_sink.h"
int main() {
try {
// Store the latest 32 messages in a buffer. Older messages will be dropped.
// spdlog::enable_backtrace(32);
auto hour = 2;
auto minute = 30;
auto logger = spdlog::daily_logger_mt("daily_logger",
"logs/daily.txt", hour, minute);
// or my_logger->enable_backtrace(32)..
logger->enable_backtrace(32);
for(int i = 0; i < 100; i++) {
logger->info("info message {}", i);
}
// e.g. if some error happened:
// log them now! show the last 32 messages
// spdlog::dump_backtrace();
// or my_logger->dump_backtrace(32)..
logger->dump_backtrace();
} catch (const spdlog::spdlog_ex &ex) {
std::cout << "Log init failed: " << ex.what() << std::endl;
}
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project("spdlog-demo-1"
VERSION "1.0.0")
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
include_directories(${CMAKE_INSTALL_PREFIX}/include)
add_executable(spdlog_backtrace_logger_1
src/backtrace_support_logger.cpp
)
编译:
cd LCPP/src/L/LSpdlog
colcon build --merge-install --cmake-args -DCMAKE_CXX_FLAGS:=-DSPDLOG_ACTIVE_LEVEL=1
输出logs/daily_2021-01-18.txt
(自动创建目录和文件)
...
[2021-01-18 17:52:02.643] [daily_logger] [info] info message 98
[2021-01-18 17:52:02.643] [daily_logger] [info] info message 99
[2021-01-18 17:52:02.643] [daily_logger] [info] ****************** Backtrace Start ******************
[2021-01-18 17:52:02.642] [daily_logger] [info] info message 68
[2021-01-18 17:52:02.642] [daily_logger] [info] info message 69
...
[2021-01-18 17:52:02.643] [daily_logger] [info] info message 98
[2021-01-18 17:52:02.643] [daily_logger] [info] info message 99
[2021-01-18 17:52:02.643] [daily_logger] [info] ****************** Backtrace End ********************
Periodic flush
// periodically flush all *registered* loggers every 3 seconds:
// warning: only use if all your loggers are thread safe ("_mt" loggers)
spdlog::flush_every(std::chrono::seconds(3));
Stopwatch support
LCPP/src/L/LSpdlog/src/demo/demo-1/src/stopwatch_use_logger.cpp
#include "spdlog/spdlog.h"
#include "spdlog/stopwatch.h"
int main() {
spdlog::stopwatch sw;
spdlog::info("Elapsed {}", sw);
spdlog::info("Elapsed {:.3}", sw);
spdlog::info("Elapsed {:.3}", sw.elapsed().count());
sw.reset();
for(int i=0; i<50000;i++){}
spdlog::info("Elapsed {}", sw);
spdlog::info("Elapsed {:.8}", sw);
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project("spdlog-demo-1"
VERSION "1.0.0")
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
include_directories(${CMAKE_INSTALL_PREFIX}/include)
add_executable(spdlog_stopwatch_use_logger_1
src/stopwatch_use_logger.cpp
)
编译:
cd LCPP/src/L/LSpdlog
colcon build --merge-install --cmake-args -DCMAKE_CXX_FLAGS:=-DSPDLOG_ACTIVE_LEVEL=1
输出:
[2021-01-18 18:32:07.301] [info] Elapsed 0.000180432
[2021-01-18 18:32:07.301] [info] Elapsed 0.000379
[2021-01-18 18:32:07.301] [info] Elapsed 0.000409
[2021-01-18 18:32:07.301] [info] Elapsed 0.000324345
[2021-01-18 18:32:07.301] [info] Elapsed 0.00034647400
Log binary data in hex
many types of std::container<char>
types can be used.
ranges are supported too.
format flags:
{:X} - print in uppercase.
{:s} - don't separate each byte with space.
{:p} - don't print the position on each line start.
{:n} - don't split the output to lines.
{:a} - show ASCII if :n is not set.
LCPP/src/L/LSpdlog/src/demo/demo-1/src/log_binary_data_logger.cpp
#include "spdlog/spdlog.h"
#include "spdlog/fmt/bin_to_hex.h"
#include "spdlog/sinks/stdout_color_sinks.h"
int main() {
auto console = spdlog::stdout_color_mt("console");
std::array<char, 80> buf;
console->info("Binary example: {}", spdlog::to_hex(buf));
console->info("Another binary example: {:n}", spdlog::to_hex(std::begin(buf), std::begin(buf)+10));
// more example
console->info("upppercase: {:X}", spdlog::to_hex(buf));
console->info("uppercase, no delimiters: {:Xs}", spdlog::to_hex(buf));
console->info("uppercase, on delimiters, no position info: {:Xsp}", spdlog::to_hex(buf));
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project("spdlog-demo-1"
VERSION "1.0.0")
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
include_directories(${CMAKE_INSTALL_PREFIX}/include)
add_executable(spdlog_log_binary_data_logger_1
src/log_binary_data_logger.cpp
)
编译:
cd LCPP/src/L/LSpdlog
colcon build --merge-install --cmake-args -DCMAKE_CXX_FLAGS:=-DSPDLOG_ACTIVE_LEVEL=1
输出:
[2021-01-19 09:38:51.587] [console] [info] Binary example:
0000: 70 cc 0a 70 ff 7f 00 00 07 00 00 00 00 00 00 00 63 6f 6e 73 6f 6c 65 00 01 00 00 00 00 00 00 00
0020: 90 cc 0a 70 ff 7f 00 00 0f 34 40 00 00 00 00 00 02 00 00 00 00 00 00 00 fd f9 45 00 00 00 00 00
0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[2021-01-19 09:38:51.587] [console] [info] Another binary example: 70 cc 0a 70 ff 7f 00 00 07 00
[2021-01-19 09:38:51.587] [console] [info] upppercase:
0000: 70 CC 0A 70 FF 7F 00 00 07 00 00 00 00 00 00 00 63 6F 6E 73 6F 6C 65 00 01 00 00 00 00 00 00 00
0020: 90 CC 0A 70 FF 7F 00 00 0F 34 40 00 00 00 00 00 02 00 00 00 00 00 00 00 FD F9 45 00 00 00 00 00
0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[2021-01-19 09:38:51.587] [console] [info] uppercase, no delimiters:
0000: 70CC0A70FF7F00000700000000000000636F6E736F6C65000100000000000000
0020: 90CC0A70FF7F00000F344000000000000200000000000000FDF9450000000000
0040: 00000000000000000000000000000000
[2021-01-19 09:38:51.587] [console] [info] uppercase, on delimiters, no position info:
70CC0A70FF7F00000700000000000000636F6E736F6C65000100000000000000
90CC0A70FF7F00000F344000000000000200000000000000FDF9450000000000
00000000000000000000000000000000
Logger with multi sinks - each with different format and log level
create logger with 2 targets with different log levels and formats. the console will show only warnings or errors, while the file will log all.
LCPP/src/L/LSpdlog/src/demo/demo-1/src/multi_sinks_logger.cpp
#include <memory>
#include "spdlog/spdlog.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/sinks/basic_file_sink.h"
int main() {
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
console_sink->set_level(spdlog::level::warn);
console_sink->set_pattern("[multi_sink_example] [%^%l%$] %v");
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("logs/multisink.txt", true);
file_sink->set_level(spdlog::level::trace);
spdlog::logger logger("multi_sink", {console_sink, file_sink});
logger.set_level(spdlog::level::debug);
logger.warn("this should appear in both console and file");
logger.info("this message should not appear in the console, only in the file");
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project("spdlog-demo-1"
VERSION "1.0.0")
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
include_directories(${CMAKE_INSTALL_PREFIX}/include)
add_executable(spdlog_multi_sinks_logger
src/multi_sinks_logger.cpp
)
编译:
cd LCPP/src/L/LSpdlog
colcon build --merge-install --cmake-args -DCMAKE_CXX_FLAGS:=-DSPDLOG_ACTIVE_LEVEL=1
console输出:
[multi_sink_example] [warning] this should appear in both console and file
文件logs/multisink.txt
输出:
[2021-01-19 09:50:40.946] [multi_sink] [warning] this should appear in both console and file
[2021-01-19 09:50:40.947] [multi_sink] [info] this message should not appear in the console, only in the file
Asynchronous logging
LCPP/src/L/LSpdlog/src/demo/demo-1/src/asynchronous_logger.cpp
#include "spdlog/spdlog.h"
#include "spdlog/async.h"
#include "spdlog/sinks/basic_file_sink.h"
int main() {
// default thread pool settings can be modified *before* creating the async logger:
// spdlog::init_thread_pool(8192, 1); // queue with 8k items and 1 backing thread.
spdlog::init_thread_pool(100, 1);
auto async_file = spdlog::basic_logger_mt<spdlog::async_factory>("async_file_logger", "logs/async_log.txt");
// alternatively:
// auto async_file = spdlog::create_async<spdlog::sinks::basic_file_sink_mt>("async_file_logger", "logs/async_log.txt");
for(int i=0; i<1000; i++) {
async_file->info("info message: {}", i);
}
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project("spdlog-demo-1"
VERSION "1.0.0")
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
include_directories(${CMAKE_INSTALL_PREFIX}/include)
add_executable(spdlog_asynchronous_logger
src/asynchronous_logger.cpp
)
target_link_libraries(spdlog_asynchronous_logger
pthread
)
编译:
cd LCPP/src/L/LSpdlog
colcon build --merge-install --cmake-args -DCMAKE_CXX_FLAGS:=-DSPDLOG_ACTIVE_LEVEL=1
文件logs/async_log.txt
...
[2021-01-19 10:11:45.784] [async_file_logger] [info] info message: 997
[2021-01-19 10:11:45.784] [async_file_logger] [info] info message: 998
[2021-01-19 10:11:45.784] [async_file_logger] [info] info message: 999
Asynchronous logger with multi sinks
LCPP/src/L/LSpdlog/src/demo/demo-1/src/asynchronous_multi_sinks_logger.cpp
#include "spdlog/spdlog.h"
#include "spdlog/async.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/sinks/rotating_file_sink.h"
int main() {
// default thread pool settings can be modified *before* creating the async logger:
spdlog::init_thread_pool(8192, 1); // queue with 8k items and 1 backing thread.
auto stdout_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
auto rotating_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(
"logs/mylog.txt", 1024 * 1024 * 10, 3);
std::vector<spdlog::sink_ptr> sinks { stdout_sink, rotating_sink };
auto logger = std::make_shared<spdlog::async_logger>("loggername",
sinks.begin(), sinks.end(), spdlog::thread_pool(),
spdlog::async_overflow_policy::block);
spdlog::register_logger(logger);
for (int i = 0; i < 1000; i++) {
logger->info("info message: {}", i);
}
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project("spdlog-demo-1"
VERSION "1.0.0")
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
include_directories(${CMAKE_INSTALL_PREFIX}/include)
add_executable(spdlog_asynchronous_multi_sinks_logger
src/asynchronous_multi_sinks_logger.cpp
)
target_link_libraries(spdlog_asynchronous_multi_sinks_logger
pthread
)
编译:
cd LCPP/src/L/LSpdlog
colcon build --merge-install --cmake-args -DCMAKE_CXX_FLAGS:=-DSPDLOG_ACTIVE_LEVEL=1
console输出:
...
[2021-01-19 10:22:43.931] [loggername] [info] info message: 997
[2021-01-19 10:22:43.931] [loggername] [info] info message: 998
[2021-01-19 10:22:43.931] [loggername] [info] info message: 999
文件logs/mylog.txt
...
[2021-01-19 10:22:43.931] [loggername] [info] info message: 997
[2021-01-19 10:22:43.931] [loggername] [info] info message: 998
[2021-01-19 10:22:43.931] [loggername] [info] info message: 999
User defined types
LCPP/src/L/LSpdlog/src/demo/demo-1/src/user_defined_types_logger.cpp
#include "spdlog/spdlog.h"
// user defined types logging by implementing operator<<
#include "spdlog/fmt/ostr.h" // must be included
struct my_type {
int i;
template<typename OStream>
friend OStream &operator<<(OStream &os, const my_type &c)
{
return os<< "[my_type i=" << c.i << "]";
}
};
int main() {
spdlog::info("user defined type: {}", my_type{14});
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project("spdlog-demo-1"
VERSION "1.0.0")
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
include_directories(${CMAKE_INSTALL_PREFIX}/include)
add_executable(spdlog_user_defined_types_logger
src/user_defined_types_logger.cpp
)
编译:
cd LCPP/src/L/LSpdlog
colcon build --merge-install --cmake-args -DCMAKE_CXX_FLAGS:=-DSPDLOG_ACTIVE_LEVEL=1
输出:
[2021-01-19 10:34:17.685] [info] user defined type: [my_type i=14]
Use defined flags in the log pattern
LCPP/src/L/LSpdlog/src/demo/demo-1/src/user_defined_flags_pattern_logger.cpp
#include "spdlog/spdlog.h"
// Log patterns can contain custom flags.
// the following example will add new flag '%*' - which will be bound to a <my_formatter_flag> instance.
#include "spdlog/pattern_formatter.h"
class my_formatter_flag : public spdlog::custom_flag_formatter
{
public:
void format(const spdlog::details::log_msg &, const std::tm &, spdlog::memory_buf_t &dest) override
{
std::string some_txt = "custom-flag";
dest.append(some_txt.data(), some_txt.data()+some_txt.size());
}
std::unique_ptr<custom_flag_formatter> clone() const override
{
return spdlog::details::make_unique<my_formatter_flag>();
}
};
int main() {
auto formatter = std::make_unique<spdlog::pattern_formatter>();
formatter->add_flag<my_formatter_flag>('*').set_pattern("[%n] [%*] [%^%l%$] %v");
spdlog::set_formatter(std::move(formatter));
spdlog::info("info message");
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project("spdlog-demo-1"
VERSION "1.0.0")
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
include_directories(${CMAKE_INSTALL_PREFIX}/include)
add_executable(spdlog_user_defined_flags_pattern_logger
src/user_defined_flags_pattern_logger.cpp
)
编译:
cd LCPP/src/L/LSpdlog
colcon build --merge-install --cmake-args -DCMAKE_CXX_FLAGS:=-DSPDLOG_ACTIVE_LEVEL=1
输出:
[] [custom-flag] [info] info message
Custom error handler
LCPP/src/L/LSpdlog/src/demo/demo-1/src/custom_error_handler_logger.cpp
下面是输出日志方式是错误的: spdlog::info("some invalid message to trigger an error {}{}{}{}", 3);
,格式要求4个参数,但只传入了1个。
不设置错误处理函数
#include "spdlog/spdlog.h"
int main() {
spdlog::info("some invalid message to trigger an error {}{}{}{}", 3);
spdlog::info("some error");
}
设置错误处理函数
#include "spdlog/spdlog.h"
int main() {
// can be set globally or per logger(logger->set_error_handler(..))
spdlog::set_error_handler([](const std::string &msg) {
spdlog::error("*** LOGGER ERROR ***: {}", msg);
});
spdlog::info("some invalid message to trigger an error {}{}{}{}", 3);
spdlog::info("some error");
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project("spdlog-demo-1"
VERSION "1.0.0")
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
include_directories(${CMAKE_INSTALL_PREFIX}/include)
add_executable(spdlog_custom_error_handler_logger
src/custom_error_handler_logger.cpp
)
编译:
cd LCPP/src/L/LSpdlog
colcon build --merge-install --cmake-args -DCMAKE_CXX_FLAGS:=-DSPDLOG_ACTIVE_LEVEL=1
不设置错误处理函数,输出:
[*** LOG ERROR #0001 ***] [2021-01-19 11:01:13] [] {argument not found}
[2021-01-19 11:01:13.563] [error] some error
设置错误处理函数,输出:
[2021-01-19 10:59:30.903] [error] *** LOGGER ERROR ***: argument not found
[2021-01-19 10:59:30.903] [error] some error
syslog
LCPP/src/L/LSpdlog/src/demo/demo-1/src/syslog_logger.cpp
#include "spdlog/spdlog.h"
#include "spdlog/sinks/syslog_sink.h"
int main() {
std::string ident = "spdlog-example";
auto syslog_logger = spdlog::syslog_logger_mt("syslog", ident, LOG_PID);
syslog_logger->warn("This is warning that will end up in syslog.");
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project("spdlog-demo-1"
VERSION "1.0.0")
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
include_directories(${CMAKE_INSTALL_PREFIX}/include)
add_executable(spdlog_syslog_logger
src/syslog_logger.cpp
)
编译:
cd LCPP/src/L/LSpdlog
colcon build --merge-install --cmake-args -DCMAKE_CXX_FLAGS:=-DSPDLOG_ACTIVE_LEVEL=1
日志会输出到/var/log/syslog
Jan 19 11:25:42 desk-47 spdlog-example[2271]: This is warning that will end up in syslog.
Android example
#include "spdlog/sinks/android_sink.h"
void android_example()
{
std::string tag = "spdlog-android";
auto android_logger = spdlog::android_logger_mt("android", tag);
android_logger->critical("Use \"adb shell logcat\" to view this message.");
}
Load log levels from env variable or from argv
从环境变量加载日志级别:
LCPP/src/L/LSpdlog/src/demo/demo-1/src/load_log_level_env_logger.cpp
#include "spdlog/spdlog.h"
#include "spdlog/cfg/env.h"
#include "spdlog/sinks/stdout_color_sinks.h"
int main() {
auto mylogger = spdlog::stdout_color_mt("mylogger");
spdlog::cfg::load_env_levels();
spdlog::trace("trace message");
spdlog::debug("debug message");
spdlog::info("info message");
spdlog::warn("warn message");
spdlog::error("error message");
mylogger->trace("trace message");
mylogger->debug("debug message");
mylogger->info("info message");
mylogger->warn("warn message");
mylogger->error("error message");
}
从参数中加载日志级别:
LCPP/src/L/LSpdlog/src/demo/demo-1/src/load_log_level_argv_logger.cpp
#include "spdlog/spdlog.h"
#include "spdlog/cfg/argv.h"
int main(int argc, char *argv[]) {
spdlog::cfg::load_argv_levels(argc, argv);
spdlog::trace("trace message");
spdlog::debug("debug message");
spdlog::info("info message");
spdlog::warn("warn message");
spdlog::error("error message");
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project("spdlog-demo-1"
VERSION "1.0.0")
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
include_directories(${CMAKE_INSTALL_PREFIX}/include)
add_executable(spdlog_load_log_level_env_logger
src/load_log_level_env_logger.cpp
)
add_executable(spdlog_load_log_level_argv_logger
src/load_log_level_env_logger.cpp
)
env测试:
SPDLOG_LEVEL=trace,mylogger=debug ./spdlog_load_log_level_env_logger
或
export SPDLOG_LEVEL=debug,mylogger=debug
./spdlog_load_log_level_env_logger
输出:
[2021-01-19 11:45:41.660] [trace] trace message
[2021-01-19 11:45:41.660] [debug] debug message
[2021-01-19 11:45:41.660] [info] info message
[2021-01-19 11:45:41.660] [warning] warn message
[2021-01-19 11:45:41.660] [error] error message
[2021-01-19 11:45:41.660] [mylogger] [debug] debug message
[2021-01-19 11:45:41.660] [mylogger] [info] info message
[2021-01-19 11:45:41.660] [mylogger] [warning] warn message
[2021-01-19 11:45:41.660] [mylogger] [error] error message
argv测试:
./spdlog_load_log_level_argv_logger SPDLOG_LEVEL=trace,mylogger=warn
输出:
[2021-01-19 11:49:29.575] [trace] trace message
[2021-01-19 11:49:29.575] [debug] debug message
[2021-01-19 11:49:29.575] [info] info message
[2021-01-19 11:49:29.575] [warning] warn message
[2021-01-19 11:49:29.575] [error] error message
[2021-01-19 11:49:29.575] [mylogger] [warning] warn message
[2021-01-19 11:49:29.575] [mylogger] [error] error message
qnx 使用spdlog
获取spdlog的库
Linux x86
cd GitLab/LCPP/src/L/LSpdlog/
mkdir spdlog
wget https://github.com/gabime/spdlog/archive/v1.8.2.tar.gz
tar -zxvf v1.8.2.tar.gz
mv spdlog-1.8.2/include .
rm -rf spdlog-1.8.2
qnx 上设置spdlog库
cd /data/Project/qnx
wget https://github.com/gabime/spdlog/archive/v1.8.2.tar.gz
tar -zxvf v1.8.2.tar.gz
mv spdlog-1.8.2/include/* zoro/install/include/
rm -rf spdlog-1.8.2/
简单示例
项目结构:
cd LCPP/src/L/LSpdlog/src/demo
tree qnx_demo/
输出:
qnx_demo/
├── CMakeLists.txt
└── src
└── main.cpp
1 directory, 2 files
main.cpp
#include "spdlog/spdlog.h"
int main() {
spdlog::set_pattern(
"[%Y-%m-%d %H:%M:%S.%e] [%n] [%^---%L---%$] [%l] [thread %t] [%@,%!]: %v");
spdlog::info("Welcome to spdlog!");
spdlog::error("Some error message with arg: {}", 1);
spdlog::warn("Easy padding in numbers like {:08d}", 12);
spdlog::critical(
"Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42);
spdlog::info("Support for floats {:03.2f}", 1.23456);
spdlog::info("Positional args are {1} {0}..", "too", "supported");
spdlog::info("{:<30}", "left aligned");
spdlog::set_level(spdlog::level::debug); // Set global log level to debug
spdlog::debug("This message should be displayed..");
// change log pattern
// spdlog::set_pattern("[%H:%M:%S %z] [%n] [%^---%L---%$] [thread %t] %v");
spdlog::set_pattern(
"[%Y-%m-%d %H:%M:%S.%e] [%n] [%^---%L---%$] [%l] [thread %t] [%@,%!]: %v");
// Compile time log levels
// define SPDLOG_ACTIVE_LEVEL to desired level
SPDLOG_TRACE("Some trace message with param {}", 42);
SPDLOG_DEBUG("Some debug message");
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project("spdlog-demo-1"
VERSION "1.0.0")
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
include_directories(${CMAKE_FIND_ROOT_PATH}/include)
# ------------------------------------------------
add_executable(spdlog_demo_1
src/main.cpp
)
Linux编译
cd LCPP/src/L/LSpdlog/src/demo/qnx_demo
mkdir build && cd build
cmake .. \
-DCMAKE_FIND_ROOT_PATH=/data/Project/GitLab/LCPP/src/L/LSpdlog/spdlog
make -j`nproc`
qnx 编译
cd LCPP/src/L/LSpdlog/src/demo/qnx_demo
mkdir build && cd build
source ~/qnx700/qnxsdp-env.sh
CC_ROOT=/data/Project/qnx/zoro \
cmake .. \
-DCMAKE_TOOLCHAIN_FILE=$HOME/qnx700/x86_64_toolchain.cmake
make -j`nproc`
拷贝到qnx运行环境测试:
scp -P 2222 spdlog_demo_1 root@10.130.17.154:/root/wl