conan - 安装并使用Spdlog
介绍
Very fast, header-only/compiled, C++ logging library.
安装spdlog
Header-only version
复制include文件夹到项目中,并使用C++11。
Compiled version (recommended - much faster compile times)
$ git clone https://github.com/gabime/spdlog.git
$ cd spdlog && mkdir build && cd build
$ cmake .. && make -j
在CMake项目中使用spdlog
# CMakeLists.txt
# Copyright(c) 2019 spdlog authors Distributed under the MIT License (http://opensource.org/licenses/MIT)
cmake_minimum_required(VERSION 3.11)
project(spdlog_examples CXX)
if(NOT TARGET spdlog)
# Stand-alone build
find_package(spdlog REQUIRED)
endif()
# ---------------------------------------------------------------------------------------
# Example of using pre-compiled library
# ---------------------------------------------------------------------------------------
add_executable(example example.cpp)
target_link_libraries(example PRIVATE spdlog::spdlog $<$<BOOL:${MINGW}>:ws2_32>)
# ---------------------------------------------------------------------------------------
# Example of using header-only library
# ---------------------------------------------------------------------------------------
if(SPDLOG_BUILD_EXAMPLE_HO)
add_executable(example_header_only example.cpp)
target_link_libraries(example_header_only PRIVATE spdlog::spdlog_header_only)
endif()
使用Conan安装spdlog
创建一个cmake项目,创建文件main.cpp
#include "spdlog/spdlog.h"
int main(int, char *[])
{
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("{:>8} aligned, {:<8} aligned", "right", "left");
spdlog::shutdown();
return 0;
}
编写一个最简的CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(spdlogDemo CXX)
add_executable(${PROJECT_NAME} src/main.cpp)
由于项目引用了第三方库spdlog,需要再在CMakeLists.txt中配置依赖,这里使用conan安装spdlog。详情可以参考conan.io
首先创建一个conanfile.txt
[requires]
spdlog/1.12.0
[generators]
CMakeDeps
CMakeToolchain
然后使用conan安装依赖
cd project_folder
conan install . --output-folder=build --build=missing
之后在cmake的过程中使用conan的工具链,该工具链的配置conan_toolchain.cmake会在上一步骤中自动生成。
cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release
cmake --build . --config=Release
此时构建会出问题的,这毋庸置疑,因为还没有将可执行程序链接到spdlog库以及头文件路径也没有设置。
对CMakeLists.txt作出一些修改:
cmake_minimum_required(VERSION 3.15)
project(spdlogDemo CXX)
find_package(spdlog REQUIRED) # 1 查找spdlog
add_executable(${PROJECT_NAME} src/main.cpp)
target_link_libraries(${PROJECT_NAME} spdlog::spdlog) # 2 链接spdlog
需要注意的是,链接的目标spdlog::spdlog
可以在cmake过程日志中查看到,如下:
编译成功后查看运行结果
将spdlog进行单例封装
logger.h
#ifndef MLOGGER_H
#define MLOGGER_H
#include "spdlog/spdlog.h"
class Logger {
private:
Logger();
Logger(Logger&)=delete;
Logger(Logger&&)=delete;
~Logger();
public:
static Logger & instance();
bool initialize();
void debug(const std::string& str);
void info(const std::string& str);
void trace(const std::string& str);
void error(const std::string& str);
void warn(const std::string& str);
void critical(const std::string& str);
private:
std::shared_ptr<spdlog::logger> logger_;
};
#define AppLog Logger::instance();
#endif
logger.cpp
#include "logger.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <unistd.h>
#ifdef _WIN32
# include <spdlog/sinks/wincolor_sink.h>
# else
# include <spdlog/sinks/ansicolor_sink.h>
#endif
#include "spdlog/async.h"
#include "spdlog/sinks/rotating_file_sink.h"
Logger::Logger(){}
Logger::~Logger(){}
Logger & Logger::instance(){
static Logger m_instance;
return m_instance;
}
bool Logger::initialize()
{
// 一个线程,队列10000个字节
spdlog::init_thread_pool(10000, 1);
/* file sink */
auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>("log/all.log", 1024 * 1024 * 10, 10);
file_sink->set_level(spdlog::level::trace);
file_sink->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%=8l] [%=8t] %v");
// https://blog.csdn.net/shizheng163/article/details/79418190
/* console sink */
#ifdef _WIN32
auto console_sink = std::make_shared<spdlog::sinks::wincolor_stdout_sink_mt>();
#else
auto console_sink = std::make_shared<spdlog::sinks::ansicolor_stdout_sink_mt>();
#endif
console_sink->set_level(spdlog::level::trace);
// 对齐方式参考:https://blog.csdn.net/alwaysrun/article/details/122771208
console_sink->set_pattern("%^[%Y-%m-%d %H:%M:%S.%e] [%=8l] [%=8t] %$ %v");
// sink组合
std::vector<spdlog::sink_ptr> sinks = {file_sink,console_sink};
logger_ = std::make_shared<spdlog::logger>("multi-sink", begin(sinks), end(sinks));
logger_->set_level(spdlog::level::trace);
logger_->flush_on(spdlog::level::trace);
return true;
}
void Logger::debug(const std::string &str)
{
logger_->debug(str);
}
void Logger::info(const std::string &str)
{
logger_->info(str);
}
void Logger::trace(const std::string &str)
{
logger_->trace(str);
}
void Logger::error(const std::string &str)
{
logger_->error(str);
}
void Logger::critical(const std::string &str)
{
logger_->critical(str);
}
void Logger::warn(const std::string &str)
{
logger_->warn(str);
}