封装了一个简单的单例 spdlog

本人机器 i3-3220 双核  6GB 内存,SSD 硬盘

spdlog 文件日志速度可以达到 3.6W/s,控制台  3.3K/s

m_log.h

// static function check dir

// Check only one layer

#ifndef _CHECK_DIR_

#define _CHECK_DIR_

#ifdef WIN32

#include #include #endif

#ifdef linux

#include #include #include #endif

static bool check_dir(const char* dir)

{

if (_access(dir, 0) == -1)

{

#ifdef WIN32

int flag = _mkdir(dir);

#endif

#ifdef linux

int flag = mkdir(dir.c_str(), 0777);

#endif

return (flag == 0);

}

return true;

};

#endif

//*****************************************************

//注意:

//文件名 __FILE__ ,函数名 __func__ ,行号__LINE__ 是编译器实现的

//并非C++头文件中定义的

//前两个变量是string类型,且__LINE__是整形,所以需要转为string类型

//******************************************************

//整数类型文件行号 ->转换为string类型 std::to_string 处理

#ifdef _WIN32

#define __FILENAME__ (strrchr(__FILE__, '\\') ? (strrchr(__FILE__, '\\') + 1):__FILE__)

#else

#define __FILENAME__ (strrchr(__FILE__, '/') ? (strrchr(__FILE__, '/') + 1):__FILE__)

#endif

//定义一个在日志后添加 文件名 函数名 行号 的宏定义

#ifndef suffix

#define suffix(msg) std::string(msg).append(" //")\

.append(__FILENAME__).append(":").append(__func__)\

.append("()#").append(std::to_string(__LINE__))\

.append(".").c_str()

#endif

//在 spdlog.h 之前定义,才有效

#ifndef SPDLOG_TRACE_ON

#define SPDLOG_TRACE_ON

#endif

#ifndef SPDLOG_DEBUG_ON

#define SPDLOG_DEBUG_ON

#endif

//引入 log 头文件

#include // spdlog 封装

#ifndef _MY_LOG_WRAPPER_H_

#define _MY_LOG_WRAPPER_H_

class M_LOG_LIB

{

public:

M_LOG_LIB()

{

check_dir("logs");

std::vectorsinks;

//设置为异步日志,同步纯文件日志 3W/s,控制台日志 3k/s

//spdlog::set_async_mode(32768); // 必须为 2 的幂

#ifdef _CONSOLE

sinks.push_back(std::make_shared());

#endif

sinks.push_back(std::make_shared("logs/log", 0, 0));

//sinks.push_back(std::make_shared("logs/file.log"));

nml_logger = std::make_shared("both", begin(sinks), end(sinks));

//register it if you need to access it globally

spdlog::register_logger(nml_logger);

// 设置日志记录级别

#ifdef _DEBUG

nml_logger->set_level(spdlog::level::trace);

#else

nml_logger->set_level(spdlog::level::err);

#endif

//设置 logger 格式

nml_logger->set_pattern("%T.%e %t [%L] %v");

//设置当出发 err 或更严重的错误时立刻刷新日志到 disk

nml_logger->flush_on(spdlog::level::err);

//trd_logger = spdlog::daily_logger_mt("logs/trade", 0, 0);

};

inline ~M_LOG_LIB()

{

spdlog::drop_all();

};

inline auto getLogger() { return nml_logger; }

void Out(const char * fmt, ...)

{

char tmp[2048] = { 0 };

va_list args;

va_start(args, fmt);

vsprintf_s(tmp, fmt, args);

va_end(args);

nml_logger->info(tmp);

};

//目前只有一个 logger 需要增加交易 logger

std::shared_ptrnml_logger;

//std::shared_ptrtrd_logger;

};

#endif

//如果没有生成对象,则生成并定义相关宏

//否则标记其为外部对象,直接使用

//可在整个工程里面 每个 cpp 里面包含该头文件

#ifndef _MY_OUTLOG_OBJECT_

#define _MY_OUTLOG_OBJECT_

extern M_LOG_LIB OutLog;

#define TTT(msg,...) OutLog.getLogger()->trace(suffix(msg),__VA_ARGS__)

#define DDD(msg,...) OutLog.getLogger()->debug(suffix(msg),__VA_ARGS__)

#define EEE(...) OutLog.getLogger()->error(__VA_ARGS__)

#define WWW(...) OutLog.getLogger()->warn(__VA_ARGS__)

#define III(...) OutLog.getLogger()->info(__VA_ARGS__)

#define CCC(...) OutLog.getLogger()->critical(__VA_ARGS__)

#endif

使用方法

main.cpp

#include #include #include #include #include #include #include #include "m_log.h"

M_LOG_LIB OutLog;

int main(int args, char*[])

{

using namespace std::chrono;

using clock = steady_clock;

//check_dir("a/b/c");

//OutLog.getLogger()->set_level(spdlog::level::info);

OutLog.getLogger()->trace("test trace {:6.6f}",12321.345);

TTT("test TTT {}", 121113);

DDD("test DDD {}", 121113);

EEE("test EEE {}", 121113);

WWW("test WWW {}", 121113);

III("test III {}", 121113);

CCC("test CCC {}", 121113);

int thread_count = 10;

int howmany = 10000;

std::ios::sync_with_stdio(false);

std::atomicmsg_counter{ 0 };

std::vectorthreads;

auto start = clock::now();

for (int t = 0; t < thread_count; ++t)

{

threads.push_back(std::thread([&]()

{

while (true)

{

int counter = ++msg_counter;

if (counter > howmany) break;

CCC("spdlog message #{}: for your pleasure", counter);

}

}));

}

for (auto &t : threads)

{

t.join();

};

durationdelta = clock::now() - start;

float deltaf = delta.count();

auto rate = howmany / deltaf;

std::cout << "Total: " << howmany << std::endl;

std::cout << "Threads: " << thread_count << std::endl;

std::cout << "Delta = " << deltaf << " seconds" << std::endl;

std::cout << "Rate = " << rate << "/sec" << std::endl;

}

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐