安徽网站备案要多少时间ps抠图教程
- 作者: 五速梦信息网
- 时间: 2026年03月21日 10:02
当前位置: 首页 > news >正文
安徽网站备案要多少时间,ps抠图教程,成都网络维护公司,seo教程大秦英扬一、基本介绍 spdlog 是由 Gustav S. 在 2015 年开发的一个高性能 C 日志库。开发这个库的主要目的是为了提供一个非常快速、轻量、易于使用的日志工具#xff0c;特别适合需要高性能、低延迟日志记录的 C 应用程序。#xff08;由于源码现在比较难下载#xff0c;我把压缩…一、基本介绍 spdlog 是由 Gustav S. 在 2015 年开发的一个高性能 C 日志库。开发这个库的主要目的是为了提供一个非常快速、轻量、易于使用的日志工具特别适合需要高性能、低延迟日志记录的 C 应用程序。由于源码现在比较难下载我把压缩包 上传附件 开发背景 当时许多现有的 C 日志库如 log4cpp 和 Boost.Log虽然功能强大但在性能和资源消耗方面存在较大的开销特别是在需要高吞吐量的环境中。尤其是在多线程或高并发的应用程序中传统日志库可能会因为锁的竞争、内存分配等原因造成显著的性能瓶颈。因此spdlog 的目标是通过简化设计和优化性能来解决这些问题。 主要目标 高性能spdlog 旨在提供最低的性能开销支持多线程和异步日志记录减少日志对应用程序主流程的干扰。简单易用提供直观的 API支持常见的日志需求如日志级别、文件输出、异步日志等方便开发者集成。低依赖spdlog 不依赖任何外部库并且库本身非常小巧易于部署。 为什么开发 spdlog 性能需求许多现有的 C 日志库虽然功能强大但它们的设计考虑了丰富的功能和可扩展性导致性能开销较大。在需要高吞吐量日志记录的应用中性能是一个重要的瓶颈。简化使用许多现有的日志库较为复杂需要配置和学习的时间较长。spdlog 旨在提供一个简单、直接的日志工具降低集成的难度。多线程支持日志记录常常涉及多线程环境在并发环境下传统的日志库可能会带来性能问题spdlog 则致力于提供线程安全的高效日志系统。 适用的项目和场景 spdlog 被广泛应用于需要高效日志记录的 C 项目中特别是在以下几种场景中非常有用
- 高性能应用程序 游戏开发例如开发高性能游戏引擎时日志记录可能会成为一个性能瓶颈spdlog 提供的异步和低延迟日志能力可以帮助减少游戏运行时的开销。金融服务如高频交易系统、银行系统等需要实时记录大量日志spdlog 的高效性非常适合这类应用。
- 多线程和并发系统 Web 服务器如处理大量请求的高并发 Web 服务spdlog 能确保在多线程环境下高效、线程安全地记录日志。分布式系统在微服务架构或分布式计算环境中spdlog 可以帮助记录每个服务和节点的日志同时确保高效性。
- 嵌入式和物联网IoT 在嵌入式设备或 IoT 项目中日志记录需要高效且不消耗太多系统资源。spdlog 的轻量级设计非常适合这些资源受限的环境。
- 实时数据处理和流处理 在处理实时数据流、日志聚合或事件流时spdlog 提供的异步日志功能能显著提高性能减少对实时计算的影响。
- 日志监控和调试 在开发、调试和生产环境中spdlog 提供了丰富的日志级别如 trace, debug, info, warn, error, critical开发者可以根据需要选择不同的日志输出级别来进行调试和错误监控。
- 数据中心和大规模服务器 spdlog 在大规模服务器和数据中心中非常有用尤其是在需要集中管理大量日志数据时。它能够有效地支持多线程和异步写入减少日志记录对系统的影响。 总结 开发者Gustav S.2015 年开发目标提供一个高性能、低开销、易用的 C 日志库专为需要高吞吐量和多线程支持的应用设计。适用项目 高性能应用如游戏、金融服务等多线程或并发系统如 Web 服务器、分布式系统等嵌入式系统和 IoT 设备实时数据处理和流处理日志监控和调试数据中心和大规模服务器 spdlog 通过简化设计并优化性能解决了许多传统日志库在高并发环境下的问题成为许多 C 项目中首选的日志库。 二、优缺点 spdlog 是一个高效且灵活的 C 日志库但它也有一些局限性。以下是它的 优点 和 缺点 的详细分析 优点
- 高性能 低开销spdlog 专注于高性能特别适合需要频繁记录日志的应用程序。它使用了非常高效的日志记录方式减少了内存分配和锁操作。异步日志支持通过异步日志功能spdlog 能够把日志消息先放入队列再由独立线程处理写入操作从而避免了在主线程中的 I/O 阻塞减少了性能损失。
- 多种日志输出方式 spdlog 支持多种日志输出方式如控制台、文件、滚动日志、异步日志和 syslog 等。可以灵活配置满足不同应用的需求。日志文件轮换支持文件大小限制、日志文件数量限制、日期切割等轮换策略避免日志文件无限增长。
- 丰富的日志级别和格式化 支持多种日志级别如 trace, debug, info, warn, error, critical便于根据重要性和严重性过滤和处理日志。自定义格式化可以通过设置格式化字符串来自定义日志的输出格式支持日志输出中包括时间戳、日志级别、文件名、行号等信息。
- 线程安全 spdlog 默认是线程安全的支持多线程环境中同时写入日志。它利用锁机制来保证多个线程对同一日志文件的安全访问。提供了异步日志进一步减少了多线程环境中日志写入的冲突。
- 轻量级 spdlog 是一个轻量级的库依赖少并且在编译时不需要链接任何重量级的第三方库。即使是异步模式下它的性能开销也非常小。
- 跨平台支持 spdlog 支持多个平台包括 Linux、Windows 和 macOS适合跨平台的 C 应用程序开发。提供了多种平台特定的日志输出例如 syslog也支持自定义日志输出目标。
- 易于集成 API 简洁易用安装和配置过程也非常简单。可以方便地嵌入到现有的 C 项目中。 缺点
- 不支持跨进程日志管理 spdlog 是一个单进程日志库默认不支持跨进程共享日志文件。在多个进程同时写日志时可能会遇到并发写入冲突的问题虽然可以使用文件锁或异步日志缓解但这些方法并不能像 logd 或 logcat 那样提供真正的跨进程日志管理和同步。
- 不支持复杂的日志过滤与查询 spdlog 主要集中在日志的输出和格式化上不像 logd、logcat 或其他日志系统那样提供强大的日志查询和过滤功能。虽然你可以在写入时控制日志级别但无法像系统级日志工具那样对日志进行复杂的筛选、过滤、搜索和集中管理。
- 对日志的持久化管理有限 对于日志的持久化和管理spdlog 主要依赖文件系统。虽然支持文件大小限制和轮换但它并不像 logd 等系统级日志管理器那样提供系统级的日志聚合、集中管理和持久化。如果需要将日志集成到集中式日志收集系统如 ELK、Fluentd 等则需要自己实现日志转发功能。
- 无内建的日志压缩或备份功能 spdlog 支持日志轮换但并不内建日志压缩、备份等功能。对于需要保留大量历史日志的应用程序可能需要额外的工具或脚本来处理日志压缩和备份。
- 日志管理功能较简单 spdlog 更注重日志记录本身缺乏一些高级的日志管理功能如日志推送、日志集成、自动清理等。这使得它对于单一应用程序非常合适但在大型分布式系统或需要跨应用程序日志集中管理的环境中可能不太适用。
- 依赖于 C 特性 spdlog 是为 C 设计的依赖于 C 的一些特性如异常处理、模板和类等。如果你在 C 环境中工作或者想在 C 语言项目中使用它可能需要通过 C 封装或者其他适配方式来使用。 总结 适合的场景 高性能要求spdlog 是一个高效的日志库适合需要低延迟和高吞吐量的 C 应用程序。单进程应用如果你的应用程序是单进程或只有少量的线程spdlog 可以提供快速的日志记录。多线程环境spdlog 通过锁机制和异步日志支持可以在多线程环境中安全高效地记录日志。简单的日志管理需求如果你不需要复杂的日志查询和管理功能只是简单地记录日志spdlog 非常合适。 不适合的场景 多进程日志管理如果需要跨进程的日志集中管理spdlog 并不提供这类功能。复杂日志分析如果你需要复杂的日志筛选、查询和分析spdlog 并不适合这种需求。日志聚合系统如果你需要将日志发送到一个日志服务器或集中式日志系统spdlog 并没有内建的支持你需要额外的配置或工具来实现。 总体来说spdlog 是一个非常优秀的 C 日志库在高性能和灵活性方面表现非常好但它的跨进程支持和日志管理功能相对较简单。如果你在一个单进程或小规模多线程环境中工作spdlog 非常适合但如果你需要复杂的日志系统功能或跨进程日志管理可能需要其他工具来补充。 三、与logd/logcat比较 spdlog 和 logd或 logcat在设计上有一些不同特别是在处理多个进程和日志的集中管理方面logd 和 logcat 更加适合多进程和多线程环境中对日志进行统一管理。 spdlog 与 logd/logcat 比较
- 用途和设计目标 spdlog这是一个高性能的 C 日志库主要用于应用程序中记录日志具有快速的性能和灵活的格式化功能。它的目标是提供高效、轻量的日志记录并支持多种输出方式如控制台、文件、异步日志等。它适合单个应用进程中使用。 logd/logcat这两个是 Android 平台上的日志系统logd 是日志守护进程负责收集和管理系统日志而 logcat 是用于查看和查询日志的工具。logd 允许多个进程同时写入日志并提供了集中管理、过滤、优先级控制等功能适合在操作系统级别使用特别是在多进程环境中。
- 多进程支持 spdlog默认情况下spdlog 主要是单进程的日志系统。虽然它支持异步日志和文件锁来避免并发写入问题但它并没有专门针对跨进程的日志协调机制。每个进程将独立管理自己的日志输出。 logd/logcatlogd 是为多进程和多线程设计的允许多个进程同时写入日志且通过操作系统统一管理。这种设计确保了跨进程的日志统一性和可访问性。在 Android 中所有进程的日志都通过 logd 管理进程之间不会直接竞争日志输出。
- 日志集中管理 spdlog日志通常是写入到文件或控制台的管理和查询日志需要额外的工具支持。例如日志文件可能会受到文件系统的限制并且可能需要自己实现日志轮换或聚合。 logd/logcat日志是集中管理的可以通过 logcat 查看所有进程的日志并且支持多种过滤、格式化选项。所有进程的日志都可以通过一个中心化的日志服务logd进行管理减少了进程间的管理复杂性。
- 性能与日志输出 spdlogspdlog 非常注重性能尤其是在单进程、多线程环境下。它支持异步日志可以减少对主线程的影响并且能够高效地写入日志文件或控制台。它对文件写入操作进行了优化并且可以高效地进行日志轮换等操作。 logd/logcatlogd 设计时考虑了多进程的日志管理因此它的性能足够支撑 Android 操作系统中大量的进程日志写入。在处理日志时logcat 提供了强大的查询功能能够对日志进行筛选和排序特别适合调试和故障排查。
- 跨平台支持 spdlogspdlog 是一个跨平台的 C 日志库支持 Linux、Windows 和 macOS 等操作系统。它非常灵活可以配置日志输出方式控制台、文件、syslog 等适合嵌入式、桌面和服务器应用。 logd/logcatlogd 和 logcat 是 Android 专用的日志系统主要用于移动设备的调试和日志管理。如果你在 Android 环境外工作logd 和 logcat 就无法使用。
适用场景 spdlog 更适用于 单进程或小型的多线程应用尤其是那些对性能要求较高的场景。需要灵活配置和高性能日志输出的 C 应用程序。对日志管理有较高要求的开发环境适合开发者使用。 logd/logcat 更适用于 多进程或分布式系统特别是操作系统级别的日志管理。Android 平台或类似的嵌入式平台需要集中管理和查询日志的场景。跨进程日志管理、日志过滤和分析尤其是调试阶段。 总结 如果你是在 Android 或 Linux 等操作系统平台上开发特别是需要跨进程日志管理logd/logcat 提供了集中的日志管理和多进程支持适合大规模应用或系统级日志。如果你是在 C 开发环境中尤其是单进程或小规模多线程环境中并且对日志性能有较高要求spdlog 是一个非常高效且灵活的日志库但对于跨进程日志管理则需要额外的工作和考虑。 从你的需求来看如果涉及到多个进程写日志到同一个地方并且希望集中管理日志logd/logcat 确实比 spdlog 更适合这种场景。 四、基本安装使用 spdlog 是一个非常高效的 C 日志库具有多线程安全性并且支持多种日志级别、日志输出格式以及日志文件管理。它的使用非常简单以下是基本用法 - 安装 spdlog 你可以通过以下命令安装 spdlog如果你没有安装的话 使用 vcpkg vcpkg install spdlog使用 CMake git clone https://github.com/gabime/spdlog.git cd spdlog mkdir build cd build cmake .. make sudo make install2. 基本使用 #include spdlog/spdlog.hint main() {// 控制台日志spdlog::info(Hello, {}!, world);// 支持不同级别的日志spdlog::debug(This is a debug message);spdlog::info(This is an info message);spdlog::warn(This is a warning message);spdlog::error(This is an error message);spdlog::critical(This is a critical message);// 格式化日志spdlog::info(Formatted log: {} {} {}, 1, 2, 1 2);return 0; }3. 日志文件输出 如果你想将日志输出到文件而不是控制台可以这样做 #include spdlog/spdlog.h #include spdlog/sinks/basic_file_sink.hint main() {// 创建一个文件日志器日志将被写入 logs.txtauto file_logger spdlog::basic_logger_mt(file_logger, logs.txt);file_logger-info(This is an info message logged to a file);return 0; }4. 设置日志级别 你可以设置全局的日志级别只有该级别及以上的日志才会被输出 #include spdlog/spdlog.hint main() {// 设置全局日志级别为 debugspdlog::set_level(spdlog::level::debug);// debug 级别的日志将被输出spdlog::debug(This is a debug message);// info 级别的日志将被输出spdlog::info(This is an info message);// warn 级别的日志将被输出spdlog::warn(This is a warning message);// error 级别的日志将被输出spdlog::error(This is an error message);return 0; }5. 自定义格式 你可以通过格式字符串自定义日志的输出格式 #include spdlog/spdlog.hint main() {// 设置输出格式为时间戳 日志级别 消息spdlog::set_pattern(%Y-%m-%d %H:%M:%S [%l] %v);// 输出日志spdlog::info(This is an info message with custom pattern);return 0; }6. 异常捕获 spdlog 支持日志输出时捕获异常并记录堆栈信息 #include spdlog/spdlog.hint main() {try {throw std::runtime_error(An error occurred);} catch (const std::exception e) {spdlog::error(Caught an exception: {}, e.what());}return 0; }五、在C项目中使用的方法 是的spdlog 是专门为 C 设计的日志库它利用了 C 的特性如类、模板和异常处理等因此不能直接在 C 语言中使用。 不过如果你想在 C 语言中使用类似的日志功能有以下几种替代方案
- 使用 C 语言的日志库 对于 C 语言你可以考虑使用其他日志库例如 log4c这是 C 语言的日志库提供类似于 log4j 的功能。zlog这是一个 C 语言编写的高效的日志库支持多种日志级别和输出格式。syslog你可以使用标准的 Unix/Linux 系统日志接口 syslog()它支持将日志消息发送到系统日志服务。
- 使用简单的 C 语言日志功能 如果不需要复杂的功能你可以使用简单的 C 代码来实现一个基础的日志系统 #include stdio.h #include time.hvoid log_info(const char *message) {time_t t;time(t);struct tm *tm_info localtime(t);char time_str[20];strftime(time_str, sizeof(time_str), %Y-%m-%d %H:%M:%S, tm_info);printf([%s] INFO: %s\n, time_str, message); }void log_error(const char *message) {time_t t;time(t);struct tm *tm_info localtime(t);char time_str[20];strftime(time_str, sizeof(time_str), %Y-%m-%d %H:%M:%S, tm_info);printf([%s] ERROR: %s\n, time_str, message); }int main() {log_info(This is an info message);log_error(This is an error message);return 0; }这种方式虽然简单但无法提供像 spdlog 那样的多线程支持、格式化功能和文件日志等高级特性。
- 使用 C 封装 如果你需要在 C 语言程序中使用 spdlog可以考虑通过 C 封装的方式来实现。这种方法可以在 C 语言中调用 C 编写的日志功能具体方法如下 在 C 中封装日志功能。使用 extern C 来暴露 C 风格的接口。在 C 程序中调用这些接口。 例如 // log.cpp (C 部分) #include spdlog/spdlog.hextern C {void log_info(const char *message) {spdlog::info(message);}void log_error(const char *message) {spdlog::error(message);} }然后在 C 程序中调用这些接口 // log.h (C 部分) #ifdef __cplusplus extern C { #endifvoid log_info(const char *message); void log_error(const char *message);#ifdef __cplusplus } #endif// main.c (C 部分) #include stdio.h #include log.hint main() {log_info(This is an info message from C);log_error(This is an error message from C);return 0; }这样就能在 C 语言中间接使用 spdlog 的日志功能了。 六、异步日志使用方法 spdlog 默认情况下日志输出到文件时如果是在多个进程中共享同一个日志文件可能会遇到并发写入的问题导致日志内容出现混乱或者丢失。这是因为多个进程同时写入同一个文件时文件操作是非原子的。 静态库与多个进程 spdlog编译出来的是一个静态库表示把 spdlog 封装成了一个库文件.a 或 .lib并且该库可以被多个进程或线程链接和调用。不过这与并发日志输出问题是两回事。静态库并不会自动处理跨进程的日志同步问题。 解决方案使用 spdlog 支持的多进程日志管理 为了在多个进程中共享日志文件并确保线程安全可以通过以下几种方式解决并发写入问题
- 使用 spdlog 的 异步日志 功能 spdlog 提供了异步日志记录的功能它通过一个独立的日志线程来处理日志消息从而避免了主线程或进程的性能瓶颈和并发问题。异步日志本质上是将日志消息先放入一个队列然后由一个专门的日志线程负责写入文件。这样即使在多个进程中写入日志也不会发生并发写入问题。 #include spdlog/spdlog.h #include spdlog/sinks/basic_file_sink.h #include spdlog/async.hint main() {// 启动异步日志spdlog::init_thread_pool(8192, 1); // 设置日志队列大小和线程池大小// 创建一个异步的文件日志器auto logger spdlog::basic_logger_mtspdlog::async_factory(async_file_logger, logs.txt);logger-info(This is an asynchronous log message.);return 0; }这样你可以保证多个进程同时向文件写入日志时不会造成问题。
- 使用 spdlog 的 文件锁 功能 如果不想使用异步日志也可以考虑使用 spdlog 的文件锁机制来确保每次只有一个进程能写入日志。spdlog 支持通过 sinks::rotating_file_sink_mt 或 sinks::daily_file_sink_mt 来实现文件锁。 #include spdlog/spdlog.h #include spdlog/sinks/rotating_file_sink.hint main() {// 创建一个带文件锁的日志器支持日志轮换auto logger spdlog::rotating_logger_mt(rotating_logger, logs.txt, 1024 * 1024 * 5, 3); // 文件大小为5MB最多保留3个文件logger-info(This is a log message that will be written to a rotating file.);return 0; }该方法适合日志轮换并且通过文件锁避免了并发写入问题。不同进程之间通过文件锁来同步日志写入。
- 使用 日志服务器 或 日志收集系统 如果你有多个进程并且这些进程的日志输出量比较大可以考虑将日志发送到一个中心化的日志系统而不是直接写入文件。例如使用类似 syslog、logstash、Fluentd 或 Kafka 等集中式日志收集系统。 这种方案的好处是可以避免本地文件系统的并发写入问题同时可以方便地进行日志管理和分析。 例如使用 spdlog 配合 syslog 进行日志记录 #include spdlog/spdlog.h #include spdlog/sinks/syslog_sink.hint main() {// 创建一个 syslog 日志器auto logger spdlog::syslog_logger_mt(syslog_logger, myapp);logger-info(This is an info message sent to syslog);return 0; }通过这种方法日志将发送到系统的日志管理器如 rsyslog 或 syslogd并且可以在多个进程间共享。
- 使用日志轮换和合并工具
如果你依然想将日志写入文件但担心多个进程之间的日志竞争问题可以使用外部工具如 logrotate来定期轮换和合并日志文件。这样即使多个进程同时写入日志它们也会被分配到不同的文件中避免冲突。
总结
异步日志 是处理多个进程写入日志时最简单和最有效的方法之一。文件锁机制如使用 rotating_file_sink_mt可以确保同一时刻只有一个进程写入日志。集中式日志系统如 syslog、logstash 等适合大规模日志收集和管理。使用 日志轮换工具 可以解决日志文件的管理问题。 七、作者提供的使用例程 基本方法
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_DEBUG // 必须在头文件之前 或者编译时-DSPDLOG_ACTIVE_LEVELSPDLOG_LEVEL_DEBUG
#include spdlog/spdlog.hint 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 debugspdlog::debug(This message should be displayed..); // change log patternspdlog::set_pattern([%H:%M:%S %z] [%n] [%^—%L—%\(] [thread %t] %v);// 编译时的log设置SPDLOG_ACTIVE_LEVEL宏的等级 和 set_level运行时等级都匹配下面的等级才会被打印SPDLOG_TRACE(Some trace message with param {}, 42);SPDLOG_DEBUG(Some debug message);return 0;
}
[2025-01-17 16:05:58.130] [info] Welcome to spdlog!
[2025-01-17 16:05:58.130] [error] Some error message with arg: 1
[2025-01-17 16:05:58.130] [warning] Easy padding in numbers like 00000012
[2025-01-17 16:05:58.130] [critical] Support for int: 42; hex: 2a; oct: 52; bin: 101010
[2025-01-17 16:05:58.130] [info] Support for floats 1.23
[2025-01-17 16:05:58.130] [info] Positional args are supported too..
[2025-01-17 16:05:58.130] [info] left aligned
[2025-01-17 16:05:58.130] [debug] This message should be displayed..
[16:05:58 08:00] [] [---D---] [thread 6001] Some debug message
Create stdout/stderr logger object
#include spdlog/spdlog.h
#include spdlog/sinks/stdout_color_sinks.h
void stdout_example()
{// create a color multi-threaded loggerauto 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));
}
Basic file logger
#include spdlog/sinks/basic_file_sink.h
void basic_logfile_example()
{try {auto logger spdlog::basic_logger_mt(basic_logger, logs/basic-log.txt);}catch (const spdlog::spdlog_ex ex){std::cout Log init failed: ex.what() std::endl;}
}
Rotating files
#include spdlog/sinks/rotating_file_sink.h
void rotating_example()
{// Create a file rotating logger with 5 MB size max and 3 rotated filesauto max_size 1048576 * 5;auto max_files 3;auto logger spdlog::rotating_logger_mt(some_logger_name, logs/rotating.txt, max_size, max_files);
}
Daily files #include spdlog/sinks/daily_file_sink.h
void daily_example()
{// Create a daily logger - a new file is created every day at 2:30 amauto logger spdlog::daily_logger_mt(daily_logger, logs/daily.txt, 2, 30);
}Backtrace support
// Debug messages can be stored in a ring buffer instead of being logged immediately.
// This is useful to display debug logs only when needed (e.g. when an error happens).
// When needed, call dump_backtrace() to dump them to your log.spdlog::enable_backtrace(32); // Store the latest 32 messages in a buffer.
// or my_logger-enable_backtrace(32)..
for(int i 0; i 100; i)
{spdlog::debug(Backtrace message {}, i); // not logged yet..
}
// e.g. if some error happened:
spdlog::dump_backtrace(); // log them now! show the last 32 messages
// or my_logger-dump_backtrace(32)..
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
// Stopwatch support for spdlog
#include spdlog/stopwatch.h
void stopwatch_example()
{spdlog::stopwatch sw; spdlog::debug(Elapsed {}, sw);spdlog::debug(Elapsed {:.3}, sw);
}Log binary data in hex
// many types of std::containerchar types can be used.
// ranges are supported too.
// format flags:
// {:X} - print in uppercase.
// {:s} - dont separate each byte with space.
// {:p} - dont print the position on each line start.
// {:n} - dont split the output into lines.
// {:a} - show ASCII if :n is not set.#include spdlog/fmt/bin_to_hex.hvoid binary_example()
{auto console spdlog::get(console);std::arraychar, 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 examples:// logger-info(uppercase: {:X}, spdlog::to_hex(buf));// logger-info(uppercase, no delimiters: {:Xs}, spdlog::to_hex(buf));// logger-info(uppercase, no delimiters, no position info: {:Xsp}, spdlog::to_hex(buf));
}Logger with multi sinks - each with a different format and log level // create a logger with 2 targets, with different log levels and formats.
// The console will show only warnings or errors, while the file will log all.
void multi_sink_example()
{auto console_sink std::make_sharedspdlog::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_sharedspdlog::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);
}
User-defined callbacks about log events // create a logger with a lambda function callback, the callback will be called
// each time something is logged to the logger
void callback_example()
{auto callback_sink std::make_sharedspdlog::sinks::callback_sink_mt( {// for example you can be notified by sending an email to yourself});callback_sink-set_level(spdlog::level::err);auto console_sink std::make_sharedspdlog::sinks::stdout_color_sink_mt();spdlog::logger logger(custom_callback_logger, {console_sink, callback_sink});logger.info(some info log);logger.error(critical issue); // will notify you
}
Asynchronous logging
#include spdlog/async.h
#include spdlog/sinks/basic_file_sink.h
void async_example()
{// 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 async_file spdlog::basic_logger_mtspdlog::async_factory(async_file_logger, logs/async_log.txt);// alternatively:// auto async_file spdlog::create_asyncspdlog::sinks::basic_file_sink_mt(async_file_logger, logs/async_log.txt);
}Asynchronous logger with multi sinks #include spdlog/async.h #include spdlog/sinks/stdout_color_sinks.h #include spdlog/sinks/rotating_file_sink.hvoid multi_sink_example2() {spdlog::init_thread_pool(8192, 1);auto stdout_sink std::make_sharedspdlog::sinks::stdout_color_sink_mt ();auto rotating_sink std::make_sharedspdlog::sinks::rotating_file_sink_mt(mylog.txt, 1024*102410, 3);std::vectorspdlog::sink_ptr sinks {stdout_sink, rotating_sink};auto logger std::make_sharedspdlog::async_logger(loggername, sinks.begin(), sinks.end(), spdlog::thread_pool(), spdlog::async_overflow_policy::block);spdlog::register_logger(logger); } User-defined types template struct fmt::formattermy_type : fmt::formatterstd::string {auto format(my_type my, format_context ctx) const - decltype(ctx.out()){return fmt::format_to(ctx.out(), [my_type i{}], my.i);} };void user_defined_example() {spdlog::info(user defined type: {}, my_type(14)); }User-defined flags in the log pattern // 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_ptrcustom_flag_formatter clone() const override{return spdlog::details::make_uniquemy_formatter_flag();} };void custom_flags_example() { auto formatter std::make_uniquespdlog::pattern_formatter();formatter-add_flagmy_formatter_flag().set_pattern([%n] [%] [%^%l%\(] %v);spdlog::set_formatter(std::move(formatter)); }Custom error handler void err_handler_example() {// can be set globally or per logger(logger-set_error_handler(..))spdlog::set_error_handler([](const std::string msg) { spdlog::get(console)-error(*** LOGGER ERROR ***: {}, msg); });spdlog::get(console)-info(some invalid message to trigger an error {}{}{}{}, 3); }syslog #include spdlog/sinks/syslog_sink.h void syslog_example() {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.); } 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 the env variable or argv #include spdlog/cfg/env.h int main (int argc, char *argv[]) {spdlog::cfg::load_env_levels();// or from the command line:// ./example SPDLOG_LEVELinfo,myloggertrace// #include spdlog/cfg/argv.h // for loading levels from argv// spdlog::cfg::load_argv_levels(argc, argv); } \) export SPDLOG_LEVELinfo,myloggertrace \( ./example Log file open/close event handlers // You can get callbacks from spdlog before/after a log file has been opened or closed. // This is useful for cleanup procedures or for adding something to the start/end of the log file. void file_events_example() {// pass the spdlog::file_event_handlers to file sinks for open/close log file notificationsspdlog::file_event_handlers handlers;handlers.before_open [](spdlog::filename_t filename) { spdlog::info(Before opening {}, filename); };handlers.after_open [](spdlog::filename_t filename, std::FILE *fstream) { fputs(After opening\n, fstream); };handlers.before_close [](spdlog::filename_t filename, std::FILE *fstream) { fputs(Before closing\n, fstream); };handlers.after_close [](spdlog::filename_t filename) { spdlog::info(After closing {}, filename); };auto my_logger spdlog::basic_logger_st(some_logger, logs/events-sample.txt, true, handlers); } Replace the Default Logger void replace_default_logger_example() {auto new_logger spdlog::basic_logger_mt(new_default_logger, logs/new-default-log.txt, true);spdlog::set_default_logger(new_logger);spdlog::info(new logger log message); } Log to Qt with nice colors #include spdlog/spdlog.h #include spdlog/sinks/qt_sinks.h MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {setMinimumSize(640, 480);auto log_widget new QTextEdit(this);setCentralWidget(log_widget);int max_lines 500; // keep the text widget to max 500 lines. remove old lines if needed.auto logger spdlog::qt_color_logger_mt(qt_logger, log_widget, max_lines);logger-info(Some info message); } Mapped Diagnostic Context // Mapped Diagnostic Context (MDC) is a map that stores key-value pairs (string values) in thread local storage. // Each thread maintains its own MDC, which loggers use to append diagnostic information to log outputs. // Note: it is not supported in asynchronous mode due to its reliance on thread-local storage. #include spdlog/mdc.h void mdc_example() {spdlog::mdc::put(key1, value1);spdlog::mdc::put(key2, value2);// if not using the default format, use the % formatter to print mdc data// spdlog::set_pattern([%H:%M:%S %z] [%^%L%\)] [%] %v); } https://github.com/0voice
- 上一篇: 安徽网站seo网站建设好后怎样形成app
- 下一篇: 安徽网站关键词优化排名地区网站建设
相关文章
-
安徽网站seo网站建设好后怎样形成app
安徽网站seo网站建设好后怎样形成app
- 技术栈
- 2026年03月21日
-
安徽省住房建设厅网站旅行网站建设论文摘要
安徽省住房建设厅网站旅行网站建设论文摘要
- 技术栈
- 2026年03月21日
-
安徽省住房和城乡建设厅官网网站游戏网络公司名字
安徽省住房和城乡建设厅官网网站游戏网络公司名字
- 技术栈
- 2026年03月21日
-
安徽网站关键词优化排名地区网站建设
安徽网站关键词优化排名地区网站建设
- 技术栈
- 2026年03月21日
-
安徽网站建设服务怎么做微信小说网站
安徽网站建设服务怎么做微信小说网站
- 技术栈
- 2026年03月21日
-
安徽网站建设科技wordpress数据库表
安徽网站建设科技wordpress数据库表
- 技术栈
- 2026年03月21日






