# easylog **Repository Path**: yyx_dev/easylog ## Basic Information - **Project Name**: easylog - **Description**: 插件式的同步异步日志系统 - **Primary Language**: C++ - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 1 - **Created**: 2023-07-20 - **Last Updated**: 2025-04-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # esylog `esylog`是一个快速的、仅头文件的、跨平台支持的C++日志库。   ## 项目特点 - 模仿spdlog实现 - 日志输出支持{fmt}库或C风格的格式串 - 版本仅需C++11 - 支持同步和异步两种日志器 - 异步日志器支持三种刷新方式,即时刷新、按秒刷新、总是刷新 - 支持多种落地位置,如标准输出和普通文件和滚动文件,并支持扩展 - 日志器注册表管理全局日志器 - 支持自定义日志消息格式 - 支持终端彩色打印 - 支持多线程写入 - 支持全局日志配置接口 - FATAL日志支持打印堆栈信息   ## 使用示例 #### 默认日志器 最基本的全局的默认日志器,便于简单输出日志。 ```cpp esylog::debug("{}:{}", "I get a debug log", 1); esylog::info ("{}:{}", "I get a info log", 2); esylog::warn ("{}:{}", "I get a warn log", 3); esylog::error("{}:{}", "I get a error log", 4); esylog::fatal("{}:{}", "I get a fatal log", 5); ESYLOG_DEBUG("{}:{}", "I get a debug log", 1) ESYLOG_INFO( "{}:{}", "I get a info log", 2) ESYLOG_WARN( "{}:{}", "I get a warn log", 3) ESYLOG_ERROR("{}:{}", "I get a error log", 4) ESYLOG_FATAL("{}:{}", "I get a fatal log", 5) ESYLOG_LOGGER_DEBUG(lgr, "{}:{}", "I get a debug log", 1) ESYLOG_LOGGER_INFO( lgr, "{}:{}", "I get a info log", 2) ESYLOG_LOGGER_WARN( lgr, "{}:{}", "I get a warn log", 3) ESYLOG_LOGGER_ERROR(lgr, "{}:{}", "I get a error log", 4) ESYLOG_LOGGER_FATAL(lgr, "{}:{}", "I get a fatal log", 5) ``` #### 同步日志器 可自定义相关配置的同步日志器,日志输出由业务线程负责。 ```cpp logger_builder::ptr llb = std::make_shared(); llb->build_logger_type(logger_builder::sync); llb->build_logger_name("sync"); llb->build_limit_level(level::debug); llb->build_sinker(); logger::ptr lgr = llb->build(); lgr->info("{}:{}", "I get a info log", 1); ``` #### 异步日志器 可自定义日志器配置,日志输出交给异步工作线程处理,不会阻塞业务线程。 ```cpp logger_builder::ptr llb = std::make_shared(); llb->build_logger_type(logger_builder::async); llb->build_logger_name("async"); llb->build_limit_level(level::debug); llb->build_sinker(); llb->build_work_type(logger_builder::work_type::safe); llb->build_thread_num(); llb->build_buffer_size(); llb->build_buffer_increment(); llb->build_buffer_threshold(); logger::ptr lgr = llb->build(); lgr->info("{}:{}", "I get a info log", 2); ``` 异步日志器支持即时刷新,或者设置刷新时间,或者总是刷新 ```cpp lgr->flush(); lgr->set_flush_every(util::time::time_enum::t2sec); lgr->set_always_flush(); ``` #### 为日志器添加落地器 目前提供的落地器,有标准输出、普通文件、按时间滚动和按体积滚动共四种落地器。 ```cpp logger_builder::ptr llb = std::make_shared(); //... llb->build_sinker(); llb->build_sinker(); llb->build_sinker(time_enum::t2sec); llb->build_sinker(size_enum::m5MB); logger::ptr lgr = llb->build(); lgr->info("I get a info log"); ``` #### 日志器全局注册表 全局的日志器注册表,用来管理所有全局的日志器,可以添加和获取日志器。以便在项目的任意位置获取自定义的日志器。 ```cpp registry::instance()->add(lgr); registry::instance()->get(name); registry::instance()->default_logger(); ``` #### 自定义日志格式 支持设置日志字符串的格式化规则,提供格式化规则串,日志格式化器会按照规则格式化日志。 ```cpp // 时间 %d // 制表符 %T // 线程编号 %t // 日志等级 %p // 日志器名 %c // 源文件名 %f // 行号 %l // 函数名 %a // 消息主体 %m // 换行符 %n // 百分号 %% sinker::ptr sk = sinker_factory::create(); formatter fmtr("[%d{%F %H:%M:%S}][%p][%t][%c][%f:%l]%T%m [%a]%n"); sk->set_formatter(fmtr); ``` #### 全局配置接口 目前日志库提供一些全局的配置接口,以便进行全局配置。 ```cpp void set_level(level_enum lv); void set_pattern(const std::string& p); void set_colorful(bool color); void set_color(const color_mode& cols); void set_fn_pattern(const std::string& patt); void set_max_file_size(size_enum size); void set_max_live_time(time_enum time); void set_max_history(size_t num); void set_total_size_cap(size_enum size); void set_work_type(worker_type type); void set_thread_num(size_t num); void set_buffer_size(size_t size); void set_buffer_increment(size_t incr); void set_buffer_threshold(size_t thre); void add(const logger::ptr& logger); bool has(const std::string& name); logger::ptr get(const std::string& name); logger::ptr default_logger(); ```   ## 性能测试 分别使用同步异步日志来输出一百万条日志,并计算每秒的日志输出条数以及输出量。 云服务器 Ubuntu22.04系统 2核2G 硬盘 40G 带宽3M ```txt ---------------- 同步日志性能测试 ---------------- 测试开始,日志共 1000000 条,单条大小 100 Bytes,总大小 97656 KB 线程0: 输出日志 333333 条,耗时 4.776920 s 线程1: 输出日志 333333 条,耗时 4.803588 s 线程2: 输出日志 333333 条,耗时 4.837192 s 总耗时:4.776920 s 每秒输出日志条数 209339 条 每秒输出日志大小 20443 KB ---------------- 异步日志性能测试 ---------------- 测试开始,日志共 1000000 条,单条大小 100 Bytes,总大小 97656 KB 线程1: 输出日志 333333 条,耗时 0.783362 s 线程2: 输出日志 333333 条,耗时 0.806406 s 线程0: 输出日志 333333 条,耗时 0.824926 s 总耗时:0.783362 s 每秒输出日志条数 1276549 条 每秒输出日志大小 124663 KB ``` RedmiBook14pro 2020 AMD R5 5500U 6核16G 硬盘 512G ```txt ---------------- 同步日志性能测试 ---------------- 测试开始,日志共 1000000 条,单条大小 100 Bytes,总大小 97656 KB 线程0: 输出日志 333333 条,耗时 5.157611 s 线程1: 输出日志 333333 条,耗时 6.139245 s 线程2: 输出日志 333333 条,耗时 6.346160 s 总耗时:6.346160 s 每秒输出日志条数 1193888 条 每秒输出日志大小 118934 KB ---------------- 异步日志性能测试 ---------------- 测试开始,日志共 1000000 条,单条大小 100 Bytes,总大小 97656 KB 线程1: 输出日志 333333 条,耗时 0.758197 s 线程2: 输出日志 333333 条,耗时 0.763640 s 线程0: 输出日志 333333 条,耗时 0.764615 s 总耗时:0.764615 s 每秒输出日志条数 1318918 条 每秒输出日志大小 128800 KB ``` iMac 2020 M1 macOS12.6 8核8G 硬盘 256G ```txt ---------------- 同步日志性能测试 ---------------- 测试开始,日志共 1000000 条,单条大小 100 Bytes,总大小 97656 KB 线程0: 输出日志 333333 条,耗时 3.660836 s 线程1: 输出日志 333333 条,耗时 3.956032 s 线程2: 输出日志 333333 条,耗时 3.976212 s 总耗时:3.660836 s 每秒输出日志条数 273161 条 每秒输出日志大小 26675 KB ---------------- 异步日志性能测试 ---------------- 测试开始,日志共 1000000 条,单条大小 100 Bytes,总大小 97656 KB 线程0: 输出日志 333333 条,耗时 0.661250 s 线程2: 输出日志 333333 条,耗时 0.704420 s 线程1: 输出日志 333333 条,耗时 0.706501 s 总耗时:0.661250 s 每秒输出日志条数 1512286 条 每秒输出日志大小 147684 KB ``` 2核2G的服务器可轻松达到每秒输出一百万条日志的要求。 > 注: > 如果您因缺少头文件而无法成功编译,那是因为我将这些文件安装到系统目录中了, > 具体可以从该仓库下载 [third-party-libraries](https://gitee.com/yyx_dev/third-party-libraries) (该仓库存放一些常用的C/C++库)