[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