flashburn
flashburn

Reputation: 4508

SPDLOG_LOGGER_CALL and __VA_ARGS__ in

I'm trying to understand why my variadic arguments don't work in spdlog. I understand that there is an SPDLOG_LOGGER_INFO macro to do what I do, but at the moment I need to understand how SPDLOG_LOGGER_CALL works. So here is the code:

#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;
}

After I compile it I get the following output

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

However I'm expecting to see a full message in the output, i.e.

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

I feel like I'm missing something small but important. Would someone care to help out?

Here is where SPDLOG_LOGGER_CALL defined

Upvotes: 0

Views: 1418

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 595897

SPDLOG_LOGGER_CALL() is just a wrapper for spdlog::logger::log(), which does not use printf-style format strings, like you are expecting. If you read spdlog's documentation, you will see that spdlog uses the {fmt} library internally:

Feature rich formatting, using the excellent fmt library.

Which has its own syntax for format strings:

Format strings contain “replacement fields” surrounded by curly braces {}. Anything that is not contained in braces is considered literal text, which is copied unchanged to the output.

That is why you are seeing %d %s in your output, as it is being treated as literal text.

Indeed, spdlog::logger::log() ends up calling fmt::detail::vformat_to(), passing it your format strings and arguments as-is.

So, try using "{} {}" instead of "%d %s":

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

Alternatively:

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

Upvotes: 1

Related Questions