From 32f9c0cc00ec7e1224370ed2ce70eb8a99204f31 Mon Sep 17 00:00:00 2001 From: Alexey Rybalchenko Date: Wed, 2 Jul 2025 11:50:32 +0200 Subject: [PATCH] Add LOGFD and LOGPD macros --- README.md | 6 ++++-- logger/Logger.h | 31 ++++++++++++++++++++++++++----- test/macros.cxx | 7 +++++++ 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 1f209bf..e4afef2 100644 --- a/README.md +++ b/README.md @@ -68,9 +68,11 @@ A number of additional logging macros are provided: - `LOGV(severity, verbosity)` Log the line with the provided verbosity, e.g. `LOG(info, veryhigh) << "abcd";` - `LOGF(severity, ...)` The arguments are given to `fmt::printf`, which formats the string using a [printf syntax](https://fmt.dev/dev/api.html#printf-formatting) and the result is logged, e.g. `LOGF(info, "Hello %s!", "world");` - `LOGP(severity, ...)` The arguments are given to `fmt::format`, which formats the string using a [Python-like syntax](https://fmt.dev/dev/syntax.html) and the result is logged, e.g. `LOGP(info, "Hello {}!", "world");` +- `LOGPD(severity, ...)` Same as `LOGP`, but accepts dynamic severity (runtime variable), e.g. `LOGPD(dynamicSeverity, "Hello {}!", "world");` +- `LOGFD(severity, ...)` Same as `LOGF`, but accepts dynamic severity (runtime variable), e.g. `LOGFD(dynamicSeverity, "Hello %s!", "world");` - `LOGN(severity)` Logs an empty line, e.g. `LOGN(info);` - `LOG_IF(severity, condition)` Logs the line if the provided condition if true -- `LOGD(severity, file, line, f)` Logs the line with the provided file, line and function parameters (only if the active verbosity allows it). +- `LOGD(severity, file, line, f)` Logs the line with the provided file, line and function parameters (accepts severity as a variable), e.g. `LOGD(dynamicSeverity, "main.cpp", "42", "main");` ## 3. Severity @@ -224,7 +226,7 @@ If only output from custom sinks is desirable, console/file sinks must be deacti ## Naming conflicts? -By default, `` defines unprefixed macros: `LOG`, `LOGV`, `LOGF`, `LOGP`, `LOGN`, `LOGD`, `LOG_IF`. +By default, `` defines unprefixed macros: `LOG`, `LOGV`, `LOGF`, `LOGP`, `LOGPD`, `LOGFD`, `LOGN`, `LOGD`, `LOG_IF`. Define an option `FAIR_NO_LOG*` to prevent the above unprefixed macros to be defined, e.g. diff --git a/logger/Logger.h b/logger/Logger.h index b8c27eb..faa5682 100644 --- a/logger/Logger.h +++ b/logger/Logger.h @@ -394,16 +394,16 @@ inline std::ostream& operator<<(std::ostream& os, const Verbosity& v) { return o #undef LOGV #define LOGV FAIR_LOGV #endif -// allow user of this header file to prevent definition of the LOGF macro, by defining FAIR_NO_LOGF before including this header -#ifndef FAIR_NO_LOGF -#undef LOGF -#define LOGF FAIR_LOGF -#endif // allow user of this header file to prevent definition of the LOGP macro, by defining FAIR_NO_LOGP before including this header #ifndef FAIR_NO_LOGP #undef LOGP #define LOGP FAIR_LOGP #endif +// allow user of this header file to prevent definition of the LOGF macro, by defining FAIR_NO_LOGF before including this header +#ifndef FAIR_NO_LOGF +#undef LOGF +#define LOGF FAIR_LOGF +#endif // allow user of this header file to prevent definition of the LOGN macro, by defining FAIR_NO_LOGN before including this header #ifndef FAIR_NO_LOGN #undef LOGN @@ -419,6 +419,16 @@ inline std::ostream& operator<<(std::ostream& os, const Verbosity& v) { return o #undef LOG_IF #define LOG_IF FAIR_LOG_IF #endif +// allow user of this header file to prevent definition of the LOGPD macro, by defining FAIR_NO_LOGPD before including this header +#ifndef FAIR_NO_LOGPD +#undef LOGPD +#define LOGPD FAIR_LOGPD +#endif +// allow user of this header file to prevent definition of the LOGFD macro, by defining FAIR_NO_LOGFD before including this header +#ifndef FAIR_NO_LOGFD +#undef LOGFD +#define LOGFD FAIR_LOGFD +#endif // Log line if the provided severity is below or equals the configured one #define FAIR_LOG(severity) \ @@ -436,6 +446,17 @@ inline std::ostream& operator<<(std::ostream& os, const Verbosity& v) { return o #define FAIR_LOGP(severity, ...) FAIR_LOG(severity) << fmt::format(__VA_ARGS__) #define FAIR_LOGF(severity, ...) FAIR_LOG(severity) << fmt::sprintf(__VA_ARGS__) +// Log with fmt- or printf-like formatting (dynamic severity) +#define FAIR_LOGPD(severity, ...) \ + for (bool fairLOggerunLikelyvariable3 = false; !fair::Logger::SuppressSeverity(severity) && !fairLOggerunLikelyvariable3; fairLOggerunLikelyvariable3 = true) \ + for (bool fairLOggerunLikelyvariable = false; fair::Logger::Logging(severity) && !fairLOggerunLikelyvariable; fairLOggerunLikelyvariable = true) \ + fair::Logger(severity, MSG_ORIGIN) << fmt::format(__VA_ARGS__) + +#define FAIR_LOGFD(severity, ...) \ + for (bool fairLOggerunLikelyvariable3 = false; !fair::Logger::SuppressSeverity(severity) && !fairLOggerunLikelyvariable3; fairLOggerunLikelyvariable3 = true) \ + for (bool fairLOggerunLikelyvariable = false; fair::Logger::Logging(severity) && !fairLOggerunLikelyvariable; fairLOggerunLikelyvariable = true) \ + fair::Logger(severity, MSG_ORIGIN) << fmt::sprintf(__VA_ARGS__) + // Log an empty line #define FAIR_LOGN(severity) \ for (bool fairLOggerunLikelyvariable3 = false; !fair::Logger::SuppressSeverity(fair::Severity::severity) && !fairLOggerunLikelyvariable3; fairLOggerunLikelyvariable3 = true) \ diff --git a/test/macros.cxx b/test/macros.cxx index 0947375..05605a8 100644 --- a/test/macros.cxx +++ b/test/macros.cxx @@ -51,6 +51,13 @@ int main() CheckOutput(ToStr(R"(^\[.*\]\[\d{2}:\d{2}:\d{2}\.\d{6}\]\[FATAL\]\[a:4:b\])", " c\n$"), []() { LOGD(Severity::fatal, "a", "4", "b") << "c"; }); + + // Test dynamic severity macros + Logger::SetVerbosity(Verbosity::verylow); + Severity dynamicSeverity = Severity::fatal; + + CheckOutput("^Hello dynamic world :-\\)!\n$", [&]() { LOGPD(dynamicSeverity, "Hello {} {}!", "dynamic world", ":-)"); }); + CheckOutput("^Hello dynamic world :-\\)!\n$", [&]() { LOGFD(dynamicSeverity, "Hello %s %s!", "dynamic world", ":-)"); }); } catch (runtime_error& rte) { cout << rte.what() << endl; return 1;