塘沽做网站公司,要个网站,wordpress如何安全,关键词搜索排名文章目录一、下载 spdlog方法1#xff1a;使用包管理器#xff08;推荐#xff09;方法2#xff1a;手动下载二、编译 spdlog使用 CMake 编译编译选项三、在项目中使用CMake 项目集成简单使用示例四、编译示例程序五、依赖要求注意事项一、环境准备1. 安装编译工具2. 获取 …文章目录一、下载 spdlog方法1使用包管理器推荐方法2手动下载二、编译 spdlog使用 CMake 编译编译选项三、在项目中使用CMake 项目集成简单使用示例四、编译示例程序五、依赖要求注意事项一、环境准备1. 安装编译工具2. 获取 spdlog 源代码二、使用 CMake 生成不同配置方法1使用批处理脚本推荐方法2手动命令编译三、完整的编译脚本四、单独编译各版本命令编译 x64 Debug编译 x64 Release编译 Win32 Debug编译 Win32 Release五、打包为可分发库六、使用注意事项1. 编译器版本对应关系2. 文件命名规则3. 在项目中使用使用例子完整的 spdlog 使用示例项目结构1. CMakeLists.txt2. logger_config.h - 日志配置类3. logger_config.cpp4. main.cpp - 主程序示例5. advanced_logging.cpp - 高级功能演示6. 编译和运行Windows (MSVC):Linux/Mac:7. 示例输出8. 主要特点一、下载 spdlog方法1使用包管理器推荐vcpkg:vcpkginstallspdlogConan:conaninstallspdlog/1.x.xAPT (Ubuntu/Debian):sudoapt-getinstalllibspdlog-dev方法2手动下载Git Clone:gitclone https://github.com/gabime/spdlog.gitcdspdlog# 切换到稳定版本gitcheckout v1.x.x直接下载 ZIP:访问 https://github.com/gabime/spdlog 下载最新版本二、编译 spdlogspdlog 是 header-only 库但如果你需要编译为动态/静态库使用 CMake 编译# 克隆仓库gitclone https://github.com/gabime/spdlog.gitcdspdlog# 创建构建目录mkdirbuildcdbuild# 配置 CMakecmake..-DCMAKE_BUILD_TYPERelease# 编译cmake --build.--config Release# 安装可选sudocmake --install.编译选项# 指定编译为静态库cmake..-DSPDLOG_BUILD_SHAREDOFF# 编译并运行测试cmake..-DSPDLOG_BUILD_TESTSON cmake --build.--targettest# 编译示例cmake..-DSPDLOG_BUILD_EXAMPLEON# 指定安装路径cmake..-DCMAKE_INSTALL_PREFIX/usr/local三、在项目中使用CMake 项目集成方法1find_package如果已安装find_package(spdlog REQUIRED) target_link_libraries(your_target PRIVATE spdlog::spdlog)方法2添加为子模块add_subdirectory(spdlog) target_link_libraries(your_target PRIVATE spdlog::spdlog)方法3FetchContentCMake 3.11include(FetchContent) FetchContent_Declare( spdlog GIT_REPOSITORY https://github.com/gabime/spdlog.git GIT_TAG v1.x.x ) FetchContent_MakeAvailable(spdlog) target_link_libraries(your_target PRIVATE spdlog::spdlog)简单使用示例#includespdlog/spdlog.h#includespdlog/sinks/basic_file_sink.hintmain(){// 基础使用spdlog::info(Hello, {}!,World);spdlog::warn(This is a warning);// 创建文件日志autofile_loggerspdlog::basic_logger_mt(file_logger,logs.txt);file_logger-info(File log message);// 设置日志级别spdlog::set_level(spdlog::level::debug);return0;}四、编译示例程序CMakeLists.txt:cmake_minimum_required(VERSION 3.10) project(SpdlogExample) set(CMAKE_CXX_STANDARD 17) # 方法1如果spdlog在子目录 add_subdirectory(spdlog) # 方法2如果已安装 find_package(spdlog REQUIRED) add_executable(example main.cpp) target_link_libraries(example PRIVATE spdlog::spdlog)编译命令:mkdirbuildcdbuild cmake..make./example五、依赖要求C11 或更高版本推荐 CMake 3.10可选依赖用于额外功能fmt格式化库pthread多线程支持注意事项头文件版本spdlog 是 header-only 库可以直接复制头文件使用跨平台支持 Windows、Linux、macOS性能默认是线程安全的支持异步日志编译时间由于是模板库编译时间可能较长可以使用预编译头文件优化选择哪种方式取决于你的项目需求。对于简单项目直接包含头文件即可对于大型项目建议使用包管理器或 CMake 集成。我来为您详细介绍如何编译 x64 和 Win32 的 Debug/Release 版本的 spdlog 库。一、环境准备1. 安装编译工具# 1. 安装 Visual Studio (确保包含 C 开发组件)# 2. 安装 CMake: https://cmake.org/download/# 3. 可选: 安装 vcpkg 用于依赖管理2. 获取 spdlog 源代码gitclone https://github.com/gabime/spdlog.gitcdspdlog二、使用 CMake 生成不同配置方法1使用批处理脚本推荐create_builds.bat:echo off setlocal enabledelayedexpansion set SPDLOG_DIR%cd% set GENERATORVisual Studio 17 2022 REM 创建所有构建目录 mkdir build_x64_debug 2nul mkdir build_x64_release 2nul mkdir build_win32_debug 2nul mkdir build_win32_release 2nul echo 生成 x64 Debug 配置... cd build_x64_debug cmake %SPDLOG_DIR% -G %GENERATOR% -A x64 -DCMAKE_BUILD_TYPEDebug cd .. echo 生成 x64 Release 配置... cd build_x64_release cmake %SPDLOG_DIR% -G %GENERATOR% -A x64 -DCMAKE_BUILD_TYPERelease cd .. echo 生成 Win32 Debug 配置... cd build_win32_debug cmake %SPDLOG_DIR% -G %GENERATOR% -A Win32 -DCMAKE_BUILD_TYPEDebug cd .. echo 生成 Win32 Release 配置... cd build_win32_release cmake %SPDLOG_DIR% -G %GENERATOR% -A Win32 -DCMAKE_BUILD_TYPERelease cd .. echo 所有配置生成完成 pause方法2手动命令编译# 1. x64 Debugmkdirbuild_x64_debugcdbuild_x64_debug cmake..-GVisual Studio 17 2022-A x64 -DCMAKE_BUILD_TYPEDebug cmake --build.--config Debugcd..# 2. x64 Releasemkdirbuild_x64_releasecdbuild_x64_release cmake..-GVisual Studio 17 2022-A x64 -DCMAKE_BUILD_TYPERelease cmake --build.--config Releasecd..# 3. Win32 Debugmkdirbuild_win32_debugcdbuild_win32_debug cmake..-GVisual Studio 17 2022-A Win32 -DCMAKE_BUILD_TYPEDebug cmake --build.--config Debugcd..# 4. Win32 Releasemkdirbuild_win32_releasecdbuild_win32_release cmake..-GVisual Studio 17 2022-A Win32 -DCMAKE_BUILD_TYPERelease cmake --build.--config Releasecd..三、完整的编译脚本build_all.bat:echo off setlocal enabledelayedexpansion echo echo SPDLOG 多平台编译脚本 echo echo. set SRC_DIR%~dp0 if %SRC_DIR% set SRC_DIR%cd% set BUILD_TYPESDebug Release set ARCH_TYPESx64 Win32 set VS_GENERATORVisual Studio 17 2022 REM 编译配置 set CMAKE_OPTIONS-DSPDLOG_BUILD_SHAREDON ^ -DSPDLOG_BUILD_EXAMPLEOFF ^ -DSPDLOG_BUILD_TESTSOFF ^ -DSPDLOG_INSTALLON REM 遍历所有配置 for %%a in (%ARCH_TYPES%) do ( for %%b in (%BUILD_TYPES%) do ( set BUILD_DIRbuild_%%a_%%b echo. echo echo 编译配置: %%a - %%b echo REM 创建构建目录 if exist !BUILD_DIR! ( echo 清理目录: !BUILD_DIR! rmdir /s /q !BUILD_DIR! ) mkdir !BUILD_DIR! cd !BUILD_DIR! REM 生成 CMake 配置 echo 生成 CMake 配置... cmake %SRC_DIR% -G %VS_GENERATOR% -A %%a %CMAKE_OPTIONS% if errorlevel 1 ( echo CMake 配置失败! cd .. exit /b 1 ) REM 编译项目 echo 编译 %%b 版本... cmake --build . --config %%b -- /m if errorlevel 1 ( echo 编译失败! cd .. exit /b 1 ) REM 安装可选 echo 安装库文件... cmake --install . --config %%b --prefix install_%%a_%%b cd .. echo 完成: !BUILD_DIR! ) ) echo. echo echo 所有配置编译完成 echo echo. echo 输出目录结构: echo ├── build_x64_Debug/ echo │ ├── spdlog.dll (Debug x64) echo │ ├── spdlog.lib echo │ └── install_x64_Debug/ echo ├── build_x64_Release/ echo │ ├── spdlog.dll (Release x64) echo │ ├── spdlog.lib echo │ └── install_x64_Release/ echo ├── build_Win32_Debug/ echo │ ├── spdlog.dll (Debug Win32) echo │ ├── spdlog.lib echo │ └── install_Win32_Debug/ echo └── build_Win32_Release/ echo ├── spdlog.dll (Release Win32) echo ├── spdlog.lib echo └── install_Win32_Release/ echo. pause四、单独编译各版本命令编译 x64 Debugmkdir build_x64_debug cd build_x64_debug cmake .. -G Visual Studio 17 2022 -A x64 ^ -DCMAKE_BUILD_TYPEDebug ^ -DSPDLOG_BUILD_SHAREDON cmake --build . --config Debug编译 x64 Releasemkdir build_x64_release cd build_x64_release cmake .. -G Visual Studio 17 2022 -A x64 ^ -DCMAKE_BUILD_TYPERelease ^ -DSPDLOG_BUILD_SHAREDON cmake --build . --config Release编译 Win32 Debugmkdir build_win32_debug cd build_win32_debug cmake .. -G Visual Studio 17 2022 -A Win32 ^ -DCMAKE_BUILD_TYPEDebug ^ -DSPDLOG_BUILD_SHAREDON cmake --build . --config Debug编译 Win32 Releasemkdir build_win32_release cd build_win32_release cmake .. -G Visual Studio 17 2022 -A Win32 ^ -DCMAKE_BUILD_TYPERelease ^ -DSPDLOG_BUILD_SHAREDON cmake --build . --config Release五、打包为可分发库package_libs.bat:echo off setlocal set VERSION1.12.0 set PACKAGE_DIRspdlog-%VERSION%-windows echo 创建打包目录... mkdir %PACKAGE_DIR% mkdir %PACKAGE_DIR%\include mkdir %PACKAGEDIR%\lib mkdir %PACKAGE_DIR%\bin REM 复制头文件 xcopy /E /I include %PACKAGE_DIR%\include\ echo. echo 复制库文件... echo REM x64 Debug mkdir %PACKAGE_DIR%\lib\x64\debug copy build_x64_debug\Debug\*.lib %PACKAGE_DIR%\lib\x64\debug\ 2nul mkdir %PACKAGE_DIR%\bin\x64\debug copy build_x64_debug\Debug\*.dll %PACKAGE_DIR%\bin\x64\debug\ 2nul REM x64 Release mkdir %PACKAGE_DIR%\lib\x64\release copy build_x64_release\Release\*.lib %PACKAGE_DIR%\lib\x64\release\ 2nul mkdir %PACKAGE_DIR%\bin\x64\release copy build_x64_release\Release\*.dll %PACKAGE_DIR%\bin\x64\release\ 2nul REM Win32 Debug mkdir %PACKAGE_DIR%\lib\win32\debug copy build_win32_debug\Debug\*.lib %PACKAGE_DIR%\lib\win32\debug\ 2nul mkdir %PACKAGE_DIR%\bin\win32\debug copy build_win32_debug\Debug\*.dll %PACKAGE_DIR%\bin\win32\debug\ 2nul REM Win32 Release mkdir %PACKAGE_DIR%\lib\win32\release copy build_win32_release\Release\*.lib %PACKAGE_DIR%\lib\win32\release\ 2nul mkdir %PACKAGE_DIR%\bin\win32\release copy build_win32_release\Release\*.dll %PACKAGE_DIR%\bin\win32\release\ 2nul REM 创建配置文件 echo Creating CMake config files... ( echo # SPDLOG Config echo set(SPDLOG_VERSION %VERSION%) echo set(SPDLOG_INCLUDE_DIRS \${CMAKE_CURRENT_LIST_DIR}/../include) echo. echo # Import targets echo if(NOT TARGET spdlog::spdlog) echo add_library(spdlog::spdlog SHARED IMPORTED) echo. echo # x64 Debug echo set_target_properties(spdlog::spdlog PROPERTIES echo IMPORTED_CONFIGURATIONS Debug echo IMPORTED_IMPLIB_DEBUG \${CMAKE_CURRENT_LIST_DIR}/lib/x64/debug/spdlogd.lib echo IMPORTED_LOCATION_DEBUG \${CMAKE_CURRENT_LIST_DIR}/bin/x64/debug/spdlogd.dll echo ) echo. echo # x64 Release echo set_target_properties(spdlog::spdlog PROPERTIES echo IMPORTED_CONFIGURATIONS Release echo IMPORTED_IMPLIB_RELEASE \${CMAKE_CURRENT_LIST_DIR}/lib/x64/release/spdlog.lib echo IMPORTED_LOCATION_RELEASE \${CMAKE_CURRENT_LIST_DIR}/bin/x64/release/spdlog.dll echo ) echo endif() ) %PACKAGE_DIR%\spdlog-config.cmake echo. echo 打包完成: %PACKAGE_DIR% echo 包含: echo - x64 Debug/Release (DLL LIB) echo - Win32 Debug/Release (DLL LIB) echo - 头文件 echo - CMake 配置文件 REM 压缩打包 powershell Compress-Archive -Path %PACKAGE_DIR% -DestinationPath %PACKAGE_DIR%.zip echo. echo 已创建压缩包: %PACKAGE_DIR%.zip pause六、使用注意事项1. 编译器版本对应关系Visual Studio 版本 CMake 生成器名称 VS 2022 Visual Studio 17 2022 VS 2019 Visual Studio 16 2019 VS 2017 Visual Studio 15 20172. 文件命名规则Debug 版本: spdlogd.lib / spdlogd.dll Release 版本: spdlog.lib / spdlog.dll3. 在项目中使用CMakeLists.txt:# 根据配置选择库文件 if(CMAKE_SIZEOF_VOID_P EQUAL 8) set(ARCH_DIR x64) else() set(ARCH_DIR win32) endif() if(CMAKE_BUILD_TYPE STREQUAL Debug) set(CONFIG_DIR debug) set(LIB_NAME spdlogd) else() set(CONFIG_DIR release) set(LIB_NAME spdlog) endif() # 设置库路径 set(SPDLOG_LIB_DIR ${CMAKE_SOURCE_DIR}/libs/spdlog/lib/${ARCH_DIR}/${CONFIG_DIR}) set(SPDLOG_DLL_DIR ${CMAKE_SOURCE_DIR}/libs/spdlog/bin/${ARCH_DIR}/${CONFIG_DIR}) # 添加库 add_library(spdlog SHARED IMPORTED) set_target_properties(spdlog PROPERTIES IMPORTED_IMPLIB ${SPDLOG_LIB_DIR}/${LIB_NAME}.lib IMPORTED_LOCATION ${SPDLOG_DLL_DIR}/${LIB_NAME}.dll ) # 包含头文件 target_include_directories(your_target PRIVATE ${CMAKE_SOURCE_DIR}/libs/spdlog/include) target_link_libraries(your_target PRIVATE spdlog)这样你就可以得到完整的 x64/Win32 的 Debug/Release 版本 spdlog 库了使用例子完整的 spdlog 使用示例这里我提供一个完整的 C 项目包含多个 spdlog 使用场景。项目结构spdlog_example/ ├── CMakeLists.txt ├── main.cpp ├── logger_config.h └── advanced_logging.cpp1. CMakeLists.txtcmake_minimum_required(VERSION 3.10) project(SpdlogExample CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 选项使用静态库还是动态库 option(USE_STATIC_SPDLOG Use static spdlog library OFF) # 查找或下载 spdlog find_package(spdlog QUIET) if(NOT spdlog_FOUND) message(STATUS spdlog not found, downloading...) # 方法1使用 FetchContent include(FetchContent) FetchContent_Declare( spdlog GIT_REPOSITORY https://github.com/gabime/spdlog.git GIT_TAG v1.12.0 ) FetchContent_MakeAvailable(spdlog) # 或者方法2下载源码 # file(DOWNLOAD https://github.com/gabime/spdlog/archive/refs/tags/v1.12.0.zip # ${CMAKE_BINARY_DIR}/spdlog.zip) # execute_process(COMMAND ${CMAKE_COMMAND} -E tar xzf spdlog.zip) # add_subdirectory(${CMAKE_BINARY_DIR}/spdlog-1.12.0) endif() # 设置编译模式 if(MSVC) add_compile_options(/W4 /EHsc) if(USE_STATIC_SPDLOG) add_definitions(-DSPDLOG_COMPILED_LIB) endif() else() add_compile_options(-Wall -Wextra -pedantic) endif() # 添加可执行文件 add_executable(spdlog_example main.cpp logger_config.h advanced_logging.cpp ) # 链接 spdlog target_link_libraries(spdlog_example PRIVATE spdlog::spdlog) # 添加测试可选 enable_testing() add_test(NAME SpdlogExample COMMAND spdlog_example) # 安装规则可选 install(TARGETS spdlog_example RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib )2. logger_config.h - 日志配置类/** * file logger_config.h * brief spdlog 日志配置类 */#ifndefLOGGER_CONFIG_H#defineLOGGER_CONFIG_H#includespdlog/spdlog.h#includespdlog/sinks/basic_file_sink.h#includespdlog/sinks/rotating_file_sink.h#includespdlog/sinks/daily_file_sink.h#includespdlog/sinks/stdout_color_sinks.h#includespdlog/sinks/windows_eventlog_sink.h#includespdlog/async.h#includememory#includestring#includevector#ifdef_WIN32#includewindows.h#endif/** * class LoggerManager * brief 日志管理器单例模式 */classLoggerManager{public:// 日志级别枚举enumclassLogLevel{TRACEspdlog::level::trace,DEBUGspdlog::level::debug,INFOspdlog::level::info,WARNspdlog::level::warn,ERRORspdlog::level::err,CRITICALspdlog::level::critical,OFFspdlog::level::off};// 日志类型enumclassLoggerType{CONSOLE,FILE,ROTATING_FILE,DAILY_FILE,CONSOLE_AND_FILE,ASYNC,EVENT_LOG// Windows only};/** * brief 获取单例实例 */staticLoggerManagerinstance(){staticLoggerManager manager;returnmanager;}/** * brief 初始化日志系统 * param logger_name 日志器名称 * param type 日志类型 * param level 日志级别 * param file_path 文件路径文件日志需要 * param max_size 最大文件大小旋转文件需要单位MB * param max_files 最大文件数旋转文件需要 */voidinitialize(conststd::stringlogger_namedefault,LoggerType typeLoggerType::CONSOLE_AND_FILE,LogLevel levelLogLevel::INFO,conststd::stringfile_pathlogs/app.log,size_t max_size10,// 10MBsize_t max_files5);/** * brief 获取日志器 */std::shared_ptrspdlog::loggergetLogger()const{returnlogger_;}/** * brief 设置日志级别 */voidsetLevel(LogLevel level);/** * brief 设置日志模式同步/异步 */voidsetAsyncMode(boolasync,size_t queue_size8192,size_t thread_count1);/** * brief 设置日志格式 */voidsetPattern(conststd::stringpattern);/** * brief 立即刷新日志 */voidflush();/** * brief 注册自定义日志器 */voidregisterCustomLogger(conststd::shared_ptrspdlog::loggercustom_logger);// 禁用拷贝和移动LoggerManager(constLoggerManager)delete;LoggerManageroperator(constLoggerManager)delete;private:LoggerManager()default;~LoggerManager();std::shared_ptrspdlog::loggerlogger_;std::vectorspdlog::sink_ptrsinks_;boolasync_mode_false;};// 便捷宏定义#defineLOG_TRACE(...)SPDLOG_LOGGER_TRACE(LoggerManager::instance().getLogger(),__VA_ARGS__)#defineLOG_DEBUG(...)SPDLOG_LOGGER_DEBUG(LoggerManager::instance().getLogger(),__VA_ARGS__)#defineLOG_INFO(...)SPDLOG_LOGGER_INFO(LoggerManager::instance().getLogger(),__VA_ARGS__)#defineLOG_WARN(...)SPDLOG_LOGGER_WARN(LoggerManager::instance().getLogger(),__VA_ARGS__)#defineLOG_ERROR(...)SPDLOG_LOGGER_ERROR(LoggerManager::instance().getLogger(),__VA_ARGS__)#defineLOG_CRITICAL(...)SPDLOG_LOGGER_CRITICAL(LoggerManager::instance().getLogger(),__VA_ARGS__)// 带位置的日志#defineLOG_INFO_LOC(...)SPDLOG_LOGGER_INFO(LoggerManager::instance().getLogger(),{}:{} - {},__FILE__,__LINE__,fmt::format(__VA_ARGS__))#endif// LOGGER_CONFIG_H3. logger_config.cpp/** * file logger_config.cpp * brief 日志配置实现 */#includelogger_config.h#includefilesystemnamespacefsstd::filesystem;LoggerManager::~LoggerManager(){if(logger_){logger_-flush();spdlog::drop(logger_-name());}spdlog::shutdown();}voidLoggerManager::initialize(conststd::stringlogger_name,LoggerType type,LogLevel level,conststd::stringfile_path,size_t max_size,size_t max_files){// 清理现有日志器if(logger_){spdlog::drop(logger_-name());}sinks_.clear();// 创建 sinkswitch(type){caseLoggerType::CONSOLE:{autoconsole_sinkstd::make_sharedspdlog::sinks::stdout_color_sink_mt();sinks_.push_back(console_sink);break;}caseLoggerType::FILE:{// 确保日志目录存在fs::pathpath(file_path);fs::create_directories(path.parent_path());autofile_sinkstd::make_sharedspdlog::sinks::basic_file_sink_mt(file_path,true);sinks_.push_back(file_sink);break;}caseLoggerType::ROTATING_FILE:{fs::pathpath(file_path);fs::create_directories(path.parent_path());autorotating_sinkstd::make_sharedspdlog::sinks::rotating_file_sink_mt(file_path,max_size*1024*1024,max_files);sinks_.push_back(rotating_sink);break;}caseLoggerType::DAILY_FILE:{fs::pathpath(file_path);fs::create_directories(path.parent_path());autodaily_sinkstd::make_sharedspdlog::sinks::daily_file_sink_mt(file_path,0,0);// 每天午夜创建新文件sinks_.push_back(daily_sink);break;}caseLoggerType::CONSOLE_AND_FILE:{autoconsole_sinkstd::make_sharedspdlog::sinks::stdout_color_sink_mt();sinks_.push_back(console_sink);fs::pathpath(file_path);fs::create_directories(path.parent_path());autofile_sinkstd::make_sharedspdlog::sinks::basic_file_sink_mt(file_path,true);sinks_.push_back(file_sink);break;}caseLoggerType::ASYNC:{setAsyncMode(true);autoconsole_sinkstd::make_sharedspdlog::sinks::stdout_color_sink_mt();sinks_.push_back(console_sink);break;}#ifdef_WIN32caseLoggerType::EVENT_LOG:{autoeventlog_sinkstd::make_sharedspdlog::sinks::win_eventlog_sink_mt(logger_name);sinks_.push_back(eventlog_sink);break;}#endifdefault:throwstd::runtime_error(Unsupported logger type);}// 创建日志器if(async_mode_){logger_spdlog::create_asyncspdlog::sinks::stdout_color_sink_mt(logger_name);}else{logger_std::make_sharedspdlog::logger(logger_name,begin(sinks_),end(sinks_));}// 设置日志级别setLevel(level);// 设置日志格式logger_-set_pattern([%Y-%m-%d %H:%M:%S.%e] [%^%l%$] [%n] [thread %t] %v);// 设置刷新级别logger_-flush_on(spdlog::level::warn);// 注册日志器spdlog::register_logger(logger_);spdlog::info(Logger initialized: {},logger_name);}voidLoggerManager::setLevel(LogLevel level){if(logger_){logger_-set_level(static_castspdlog::level::level_enum(level));}}voidLoggerManager::setAsyncMode(boolasync,size_t queue_size,size_t thread_count){if(async!async_mode_){spdlog::init_thread_pool(queue_size,thread_count);async_mode_true;}async_mode_async;}voidLoggerManager::setPattern(conststd::stringpattern){if(logger_){logger_-set_pattern(pattern);}}voidLoggerManager::flush(){if(logger_){logger_-flush();}}voidLoggerManager::registerCustomLogger(conststd::shared_ptrspdlog::loggercustom_logger){if(custom_logger){spdlog::register_logger(custom_logger);}}4. main.cpp - 主程序示例/** * file main.cpp * brief spdlog 使用示例 */#includelogger_config.h#includespdlog/fmt/ostr.h// 支持自定义类型格式化#includespdlog/fmt/bundled/format.h#includeiostream#includethread#includevector#includechrono#includememory#includerandom// 自定义类型示例structUser{std::string name;intage;std::string email;// 支持 spdlog 格式化输出friendstd::ostreamoperator(std::ostreamos,constUseruser){returnosfmt::format(User{{name{}, age{}, email{}}},user.name,user.age,user.email);}};// 演示基本日志功能voiddemo_basic_logging(){std::cout 基础日志演示 \n;LOG_INFO(应用程序启动);LOG_DEBUG(调试信息{},这是一条调试消息);LOG_INFO(欢迎使用 spdlog版本{},SPDLOG_VERSION);LOG_WARN(警告内存使用率达到 {}%,85.5);LOG_ERROR(错误文件 {} 不存在,config.json);// 带参数的格式化LOG_INFO(用户 {} 在 {} 登录,张三,2024-01-15 10:30:00);// 条件日志intretry_count3;SPDLOG_LOGGER_INFO(LoggerManager::instance().getLogger(),重试次数: {}, 状态: {},retry_count,retry_count0?继续:停止);}// 演示多线程日志voiddemo_multithread_logging(){std::cout\n 多线程日志演示 \n;std::vectorstd::threadthreads;constintthread_count5;autoworker[](intid){for(inti0;i3;i){LOG_INFO(线程 {} - 任务 {},id,i);std::this_thread::sleep_for(std::chrono::milliseconds(100));}};for(inti0;ithread_count;i){threads.emplace_back(worker,i1);}for(autot:threads){t.join();}LOG_INFO(所有线程执行完成);}// 演示性能日志voiddemo_performance_logging(){std::cout\n 性能日志演示 \n;autostartstd::chrono::high_resolution_clock::now();// 模拟一些工作std::random_device rd;std::mt19937gen(rd());std::uniform_int_distributiondis(1,100);intsum0;constintiterations1000000;for(inti0;iiterations;i){sumdis(gen);}autoendstd::chrono::high_resolution_clock::now();autodurationstd::chrono::duration_caststd::chrono::milliseconds(end-start);// 使用性能日志级别LOG_INFO(计算完成迭代次数: {}, 总和: {}, 耗时: {} ms,iterations,sum,duration.count());// 日志级别控制LoggerManager::instance().setLevel(LoggerManager::LogLevel::DEBUG);LOG_DEBUG(详细性能数据: 平均每次迭代耗时: {:.6f} ms,duration.count()/static_castdouble(iterations));}// 演示自定义类型日志voiddemo_custom_type_logging(){std::cout\n 自定义类型日志演示 \n;User user{张三,25,zhangsanexample.com};LOG_INFO(用户信息: {},user);std::vectorUserusers{{李四,30,lisiexample.com},{王五,28,wangwuexample.com},{赵六,35,zhaoliuexample.com}};LOG_INFO(用户列表:);for(constautou:users){LOG_INFO( - {},u);}}// 演示异常日志voiddemo_exception_logging(){std::cout\n 异常日志演示 \n;try{throwstd::runtime_error(模拟业务异常);}catch(conststd::exceptione){LOG_ERROR(捕获异常: {}, 位置: {}:{},e.what(),__FILE__,__LINE__);// 记录堆栈信息需要其他库支持这里只是示例LOG_ERROR(异常堆栈:);LOG_ERROR( - main());LOG_ERROR( - demo_exception_logging());LOG_ERROR( - std::runtime_error::runtime_error());}}// 演示不同日志级别voiddemo_log_levels(){std::cout\n 日志级别演示 \n;autologgerLoggerManager::instance();// 显示所有级别的日志logger.setLevel(LoggerManager::LogLevel::TRACE);LOG_TRACE(这是一条 TRACE 级别的日志);LOG_DEBUG(这是一条 DEBUG 级别的日志);LOG_INFO(这是一条 INFO 级别的日志);LOG_WARN(这是一条 WARN 级别的日志);LOG_ERROR(这是一条 ERROR 级别的日志);LOG_CRITICAL(这是一条 CRITICAL 级别的日志);// 设置为只显示 ERROR 及以上logger.setLevel(LoggerManager::LogLevel::ERROR);LOG_INFO(这条 INFO 日志不会被显示);LOG_ERROR(这条 ERROR 日志会被显示);}// 演示文件日志voiddemo_file_logging(){std::cout\n 文件日志演示 \n;autologgerLoggerManager::instance();// 重新初始化为文件日志logger.initialize(file_logger,LoggerManager::LoggerType::FILE,LoggerManager::LogLevel::INFO,logs/file_demo.log);LOG_INFO(这条日志会写入文件);LOG_WARN(警告信息也会写入文件);LOG_ERROR(错误信息同样写入文件);std::cout日志已写入 logs/file_demo.log 文件\n;}// 演示异步日志voiddemo_async_logging(){std::cout\n 异步日志演示 \n;autologgerLoggerManager::instance();logger.setAsyncMode(true,8192,2);constintmessage_count1000;autostartstd::chrono::high_resolution_clock::now();std::vectorstd::threadthreads;constintthread_count4;autoworker[logger](intid,intcount){for(inti0;icount;i){SPDLOG_LOGGER_INFO(logger.getLogger(),异步日志 - 线程 {} - 消息 {},id,i);}};intmessages_per_threadmessage_count/thread_count;for(inti0;ithread_count;i){threads.emplace_back(worker,i1,messages_per_thread);}for(autot:threads){t.join();}autoendstd::chrono::high_resolution_clock::now();autodurationstd::chrono::duration_caststd::chrono::milliseconds(end-start);LOG_INFO(异步日志完成总共 {} 条消息耗时 {} ms,message_count,duration.count());// 等待异步队列清空logger.flush();}// 演示日志配置voiddemo_logger_configuration(){std::cout\n 日志配置演示 \n;autologgerLoggerManager::instance();// 1. 自定义日志格式logger.setPattern([%Y-%m-%d %H:%M:%S] [%l] [%n] %v);LOG_INFO(自定义格式日志);// 2. 恢复默认格式logger.setPattern([%Y-%m-%d %H:%M:%S.%e] [%^%l%$] [%n] [thread %t] %v);LOG_INFO(恢复默认格式);// 3. 设置不同的日志级别logger.setLevel(LoggerManager::LogLevel::WARN);LOG_INFO(这条 INFO 日志不会显示);LOG_WARN(这条 WARN 日志会显示);// 4. 刷新日志logger.flush();LOG_INFO(日志已刷新到磁盘);}intmain(){try{// 初始化日志系统LoggerManager::instance().initialize(demo_logger,LoggerManager::LoggerType::CONSOLE_AND_FILE,LoggerManager::LogLevel::INFO,logs/demo.log);// 设置全局异常处理器spdlog::set_error_handler([](conststd::stringmsg){std::cerrspdlog 错误: msgstd::endl;});// 运行各种演示demo_basic_logging();demo_multithread_logging();demo_performance_logging();demo_custom_type_logging();demo_exception_logging();demo_log_levels();demo_file_logging();demo_async_logging();demo_logger_configuration();// 程序结束日志LOG_INFO(程序正常退出);}catch(conststd::exceptione){std::cerr程序异常: e.what()std::endl;return1;}return0;}5. advanced_logging.cpp - 高级功能演示/** * file advanced_logging.cpp * brief spdlog 高级功能演示 */#includelogger_config.h#includespdlog/sinks/ostream_sink.h#includespdlog/sinks/udp_sink.h#includespdlog/sinks/tcp_sink.h#includespdlog/sinks/syslog_sink.h#includespdlog/sinks/android_sink.h#includespdlog/fmt/bin_to_hex.h#includesstream#includefstream#includeiomanip// 演示二进制数据日志voiddemo_binary_logging(){std::cout\n 二进制数据日志演示 \n;unsignedcharbinary_data[]{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};LOG_INFO(二进制数据: {},spdlog::to_hex(binary_data,sizeof(binary_data)));LOG_INFO(带 ASCII 显示: {},spdlog::to_hex(binary_data,sizeof(binary_data),true));// 格式化显示std::string hex_dumpspdlog::to_hex(binary_data,sizeof(binary_data),8);LOG_INFO(格式化十六进制:\n{},hex_dump);}// 演示条件编译日志voiddemo_conditional_logging(){std::cout\n 条件编译日志演示 \n;#ifdef_DEBUGLOG_DEBUG(这是调试版本);#elseLOG_INFO(这是发布版本);#endif// SPDLOG_LOGGER_CALL 宏interror_code404;SPDLOG_LOGGER_CALL(LoggerManager::instance().getLogger(),spdlog::level::err,错误代码: {},error_code);}// 演示流式日志不推荐性能较低voiddemo_stream_logging(){std::cout\n 流式日志演示 \n;// 注意流式日志性能较低建议使用格式化字符串autologgerLoggerManager::instance().getLogger();SPDLOG_LOGGER_INFO(logger,流式日志: 第一部分 123 第二部分);}// 演示自定义 sinkvoiddemo_custom_sink(){std::cout\n 自定义 Sink 演示 \n;// 创建 stringstream sinkautooss_sinkstd::make_sharedspdlog::sinks::ostream_sink_mt(std::cout);autocustom_loggerstd::make_sharedspdlog::logger(custom,oss_sink);custom_logger-set_pattern([custom] %v);custom_logger-info(这是通过自定义 sink 输出的日志);// 注册到管理器LoggerManager::instance().registerCustomLogger(custom_logger);}// 演示速率限制日志voiddemo_rate_limited_logging(){std::cout\n 速率限制日志演示 \n;// spdlog 本身没有内置速率限制但可以通过条件控制staticintlog_count0;staticautolast_log_timestd::chrono::steady_clock::now();autonowstd::chrono::steady_clock::now();autoelapsedstd::chrono::duration_caststd::chrono::seconds(now-last_log_time);if(elapsed.count()1){// 每秒最多一条LOG_INFO(速率限制日志 - 计数: {},log_count);last_log_timenow;}}// 演示结构化日志JSON 格式voiddemo_structured_logging(){std::cout\n 结构化日志演示 \n;// 设置为 JSON 格式LoggerManager::instance().setPattern({\timestamp\:\%Y-%m-%dT%H:%M:%S.%eZ\,\level\:\%l\,\thread\:%t,\message\:\%v\});LOG_INFO(用户登录成功);LOG_WARN(内存使用率偏高);// 恢复默认格式LoggerManager::instance().setPattern([%Y-%m-%d %H:%M:%S.%e] [%^%l%$] %v);}// 演示日志轮转voiddemo_log_rotation(){std::cout\n 日志轮转演示 \n;autologgerLoggerManager::instance();// 重新初始化为旋转文件日志logger.initialize(rotation_logger,LoggerManager::LoggerType::ROTATING_FILE,LoggerManager::LogLevel::INFO,logs/rotation.log,1,// 1MB3);// 保留3个文件// 生成大量日志以触发轮转for(inti0;i1000;i){LOG_INFO(这是第 {} 条日志消息用于测试日志轮转功能,i);}std::cout已生成测试日志检查 logs/ 目录下的 rotation.log 文件\n;}// 演示系统日志Linux/Unixvoiddemo_syslog_logging(){std::cout\n 系统日志演示 \n;#ifndef_WIN32// Linux/Unix 系统日志try{autosyslog_sinkstd::make_sharedspdlog::sinks::syslog_sink_mt(spdlog_demo);autosyslog_loggerstd::make_sharedspdlog::logger(syslog,syslog_sink);syslog_logger-info(这是一条系统日志消息);LoggerManager::instance().registerCustomLogger(syslog_logger);}catch(constspdlog::spdlog_exex){LOG_WARN(系统日志不可用: {},ex.what());}#elseLOG_INFO(Windows 系统不支持 Unix 系统日志);#endif}// 演示网络日志UDP/TCPvoiddemo_network_logging(){std::cout\n 网络日志演示 \n;LOG_INFO(网络日志功能需要额外的网络配置);LOG_INFO(可以使用 udp_sink 或 tcp_sink 发送日志到远程服务器);// 示例代码需要服务器支持/* try { // UDP 日志 auto udp_sink std::make_sharedspdlog::sinks::udp_sink_mt(127.0.0.1, 9999); auto udp_logger std::make_sharedspdlog::logger(udp, udp_sink); udp_logger-info(UDP 日志消息); // TCP 日志 auto tcp_sink std::make_sharedspdlog::sinks::tcp_sink_mt(127.0.0.1, 9998); auto tcp_logger std::make_sharedspdlog::logger(tcp, tcp_sink); tcp_logger-info(TCP 日志消息); } catch (const std::exception e) { LOG_ERROR(网络日志错误: {}, e.what()); } */}// 演示日志分析voiddemo_log_analysis(){std::cout\n 日志分析演示 \n;// 读取日志文件进行分析std::ifstreamlog_file(logs/demo.log);if(log_file.is_open()){std::string line;intinfo_count0,error_count0,warn_count0;while(std::getline(log_file,line)){if(line.find([info])!std::string::npos)info_count;if(line.find([error])!std::string::npos)error_count;if(line.find([warn])!std::string::npos)warn_count;}LOG_INFO(日志分析结果:);LOG_INFO( INFO 消息: {} 条,info_count);LOG_INFO( WARN 消息: {} 条,warn_count);LOG_INFO( ERROR 消息: {} 条,error_count);log_file.close();}else{LOG_WARN(无法打开日志文件进行分析);}}6. 编译和运行Windows (MSVC):# 创建构建目录mkdirbuildcdbuild# 配置 CMake根据你的 VS 版本调整cmake..-GVisual Studio 17 2022-A x64# 编译cmake --build.--config Release# 运行.\Release\spdlog_example.exeLinux/Mac:mkdirbuildcdbuild cmake..-DCMAKE_BUILD_TYPEReleasemake-j4 ./spdlog_example7. 示例输出程序运行后会在控制台输出彩色日志在logs/目录下生成日志文件演示各种日志功能 基础日志演示 [2024-01-15 10:30:00.123] [INFO] [demo_logger] 应用程序启动 [2024-01-15 10:30:00.124] [INFO] [demo_logger] 欢迎使用 spdlog版本1.12.0 [2024-01-15 10:30:00.125] [WARN] [demo_logger] 警告内存使用率达到 85.5% 多线程日志演示 [2024-01-15 10:30:00.126] [INFO] [demo_logger] 线程 1 - 任务 0 [2024-01-15 10:30:00.126] [INFO] [demo_logger] 线程 2 - 任务 0 ...8. 主要特点这个示例展示了✅ 多线程安全日志✅ 彩色控制台输出✅ 文件日志普通、轮转、每日✅ 异步日志高性能✅ 自定义日志格式✅ 结构化日志JSON✅ 二进制数据日志✅ 异常日志记录✅ 性能监控日志✅ 条件编译日志✅ 自定义类型支持✅ 日志级别控制✅ 日志刷新策略你可以根据需要修改和扩展这个示例来满足具体的项目需求。