0

我试图理解为什么我的可变参数在spdlog. 我知道有一个SPDLOG_LOGGER_INFO宏可以做我所做的事情,但目前我需要了解它是如何SPDLOG_LOGGER_CALL工作的。所以这里是代码:

#include <iostream>
#include <spdlog/sinks/syslog_sink.h>
#include <spdlog/spdlog.h>
#include <memory>
#include <syslog.h>

int main()
{
    auto logger = std::make_shared<spdlog::logger>(
            "logger", 
            std::make_shared<spdlog::sinks::syslog_sink_mt>(
                "", LOG_ODELAY, LOG_USER, true));
    std::string msg = "my message";
    int i = 10;
    SPDLOG_LOGGER_CALL(logger, spdlog::level::info, "%d %s", i, msg);
    return 0;
}

编译后我得到以下输出

Aug 12 9:38:03 mymachine test: [2021-08-12 9:38:03.424] [logger] [info] [main.cpp:30] %d %s

但是我希望在输出中看到完整的消息,即

Aug 12 9:38:03 mymachine test: [2021-08-12 9:38:03.424] [logger] [info] [main.cpp:30] 10 my message

我觉得我错过了一些小而重要的东西。有人愿意帮忙吗?

这是 SPDLOG_LOGGER_CALL 定义的地方

4

1 回答 1

1

SPDLOG_LOGGER_CALL()只是一个包装器spdlog::logger::log(),它不使用printf-style 格式字符串,就像您期望的那样。如果您阅读spdlog 的文档,您会看到 spdlog 在内部使用{fmt}库:

功能丰富的格式,使用优秀的fmt库。

它有自己的格式字符串语法

格式字符串包含用大括号括起来的“替换字段” {}。大括号中不包含的任何内容都被视为文字文本,它会原封不动地复制到输出中。

这就是您%d %s在输出中看到的原因,因为它被视为文字文本。

实际上,spdlog::logger::log() 最终调用 fmt::detail::vformat_to(),按原样传递您的格式字符串和参数。

所以,尝试使用"{} {}"而不是"%d %s"

SPDLOG_LOGGER_CALL(logger, spdlog::level::info, "{} {}", i, msg);

或者:

SPDLOG_LOGGER_CALL(logger, spdlog::level::info, "{:d} {:s}", i, msg);
于 2021-08-12T19:10:04.977 回答