我是靠谱客的博主 谦让水池,最近开发中收集的这篇文章主要介绍新手看spdlog源码做笔记以及附上简单使用手册,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

version 1.7.0

tweakme.h

  • SPDLOG_CLOCK_COARSE
    如果Linux开启 相比常规时钟获得更快的速度但是精确度会稍微降低
  • SPDLOG_NO_THREAD_ID
    如果开启 每次的log call调用获取thread id会返回0
  • SPDLOG_NO_TLS
    如果开启 可以避免spdlog使用线程本地空间 如果你的程序是多线程的可以防止未
    定义thread ids
  • SPDLOG_NO_ATOMIC_LEVELS
    如果开启 如同字面意思不使用原子性的的log level设置
    当且仅当(Use only if)你确定不会通过不同的线程同时改变一个logger的log level时可以开启
  • SPDLOG_WCHAR_FILENAMES
    如果开启 可以使用wchar字符的文件名 WIN下开启才有效
  • SPDLOG_EOL
    如果开启 自定义EOL
  • SPDLOG_FMT_EXTERNAL
    如果开启 使用外部三方库的FMT
  • SPDLOG_WCHAR_TO_UTF8_SUPPORT
    如果开启 字面意思 WIN下开启才有效
  • SPDLOG_PREVENT_CHILD_FD
  • 如果开启 防止子进程继承文件描述符
  • SPDLOG_LEVEL_NAMES
    如果开启 自定义level name
  • SPDLOG_SHORT_LEVEL_NAMES
    如果开启 自定义level name的缩写
  • SPDLOG_DISABLE_DEFAULT_LOGGER
    如果开启 会关闭默认的LOGGER
  • SPDLOG_ACTIVE_LEVEL
    如果开启 自定义编译时level默认为info
  • SPDLOG_FUNCTION
    如果开启 自定义函数名字宏 比如 __PRETTY_FUNCTION__ __FUNCTION__

关于level_t

正常默认使用std::atomic<int>作为level_t的类型
如果有定义上述的SPDLOG_NO_ATOMIC_LEVELS非原子级的Level宏定义
那么level_t会使用 一个自定义的 null_atomic_int 类 这个类提供类似atomic的store和load和exchange操作
发现在exchange里面用到了swap
这里学到一个小技巧 在允许的情况系 交换两个变量的值 swap 会使用std::move效率更高

关于detail/registry.h

单例负责logger的注册管理以及全局的logger设置
比如有默认的flush_level err_handler_ log_level等等

关于logger

class source_loc

filename 文件名
funcname 函数名
line 行号

class log_msg

logger_name
level
time 默认当前时间
thread_id 与上述的SPDLOG_NO_THREAD_ID定义有关
source 默认构造为空
payload 有效荷载msg

关于pattern_formatter

这个主要是控制个格式相关

关于sinks(接收器)

这个主要是控制输出的 我在Debian10 x64的虚拟机下默认是ansicolor_stdout_sink_mt
注意输出有一个输出等级flush_level_在logger中有一个控制是当前日志的等级比这个高才会在log时立刻执行flush
但是ansicolor_stdout_sink_mt在sink_it_时有立刻flush
但是ostream_sink是没有flush那就会由logger的flush_level_控制是否立刻flush
basic_file_sink是文件输出的sink_it_只有write没有flush

一些小结注意事项和设置等如下其实官方的例子比这里好

int test_log()
{
// 默认的
spdlog::info("infomsg");
spdlog::error(fmt::format("error: today is {} {} day ! {}", "a", "bad", 666));
spdlog::critical("criticalmsg: today is {} {} day ! {}", "a", "nice", 777);
// 不会输出 等级不够
spdlog::debug("debugmsg1");
// 设置level
spdlog::set_level(spdlog::level::debug);
spdlog::debug("debugmsg2");
spdlog::set_level(spdlog::level::info);
// 创建osstream
spdlog::create<spdlog::sinks::ostream_sink_mt>("osstream.txt", std::cout, true);
auto log_ins = spdlog::get("osstream.txt");
// 设置flush_level
log_ins->flush_on(spdlog::level::trace);
log_ins->trace("haa ostream trace 1");
log_ins->debug("haa ostream debug 1");
log_ins->set_level(spdlog::level::debug);
log_ins->trace("haa ostream trace 2");
log_ins->debug("haa ostream debug 2");
log_ins->set_level(spdlog::level::info);
log_ins->info("haa ostream info 11");
log_ins->info("haa ostream info 22 {} {}", "a", 1);
log_ins->info(fmt::format("haa ostream info 33 {} {}", "a", 1));
log_ins->warn("haa ostream warn 44");
log_ins->error("haa ostream error 55");
log_ins->critical("haa ostream critical 66");
spdlog::daily_logger_mt("daily.txt", "daily.txt", 0, 0, false, 0);
log_ins = spdlog::get("daily.txt");
log_ins->info("daily info");
spdlog::rotating_logger_mt("rotating.txt", "rotating.txt", 1, 3, true);
log_ins = spdlog::get("rotating.txt");
log_ins->info("a");
log_ins->info("b");
log_ins->info("c");
log_ins->info("d");
// 用osstream测试backtrace
spdlog::create<spdlog::sinks::ostream_sink_mt>("backtrace.txt", std::cout, true);
log_ins = spdlog::get("backtrace.txt");
log_ins->enable_backtrace(3);
log_ins->info(1);
log_ins->info(2);
log_ins->info(3);
log_ins->info(4);
// trace只会有3条
log_ins->dump_backtrace();
// 第二次trace没有记录的 因为上一行trace之后已经没数据了
log_ins->dump_backtrace();
// debug的尽管因为log_level_不会输出 但是会记录的trace中 trace时可以看到debug记录
// trace级别的也是同理
log_ins->trace(5);
log_ins->debug(6);
log_ins->dump_backtrace();
log_ins->info(7);
log_ins->dump_backtrace();
// 创建一个带有多个sink的logger
// 会同时输出和写文件
auto stdout_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
auto rotating_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>("multiply.txt", 0xfffff, 3);
std::vector<spdlog::sink_ptr> sinks{stdout_sink, rotating_sink};
log_ins = std::make_shared<spdlog::logger>("multiply.txt", sinks.begin(), sinks.end());
log_ins->info("multiply 11");
log_ins->info("multiply 22 {} {}", "a", 1);
log_ins->info(fmt::format("multiply 33 {} {}", "a", 1));
// 添加自定义的flag_formatter
class my_formatter_flag : public spdlog::custom_flag_formatter
{
public:
void format(const spdlog::details::log_msg &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_ptr<custom_flag_formatter> clone() const override
{
return spdlog::details::make_unique<my_formatter_flag>();
}
};
spdlog::basic_logger_mt("custom_flag_formatter.txt", "custom_flag_formatter.txt");
log_ins = spdlog::get("custom_flag_formatter.txt");
auto formatter = std::make_unique<spdlog::pattern_formatter>();
// 注意这里的两个*号
// 一定要set_pattern中带有*号才会生效o
// 不然你定义这个custom_flag_formatter也没意义
formatter->add_flag<my_formatter_flag>('*').set_pattern("[%n] [%*] [%^%l%$] %v");
log_ins->set_formatter(std::move(formatter));
log_ins->info("custom_flag_formatter 11");
log_ins->info("custom_flag_formatter 22 {} {}", "a", 1);
log_ins->info(fmt::format("custom_flag_formatter 33 {} {}", "a", 1));
return 0;
}

最后

以上就是谦让水池为你收集整理的新手看spdlog源码做笔记以及附上简单使用手册的全部内容,希望文章能够帮你解决新手看spdlog源码做笔记以及附上简单使用手册所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(64)

评论列表共有 0 条评论

立即
投稿
返回
顶部