Skip to content

Commit

Permalink
Check for dynamic log level at compile-time using constexpr
Browse files Browse the repository at this point in the history
  • Loading branch information
odygrd committed Sep 22, 2024
1 parent 4ec51bd commit 195c930
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 23 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
attempting to log `std::string s(std::numeric_limits<uint32_t>::max(), 'a');` would previously cause a crash.
- Tuned `transit_events_soft_limit` and `transit_events_hard_limit` default values; added error checks for invalid
configurations.
- Improved dynamic log level handling by checking at compile-time using `constexpr` on the hot path.
- Added support for appending a custom timestamp format to log filenames via `StartCustomTimestampFormat`.
Example usage:
```cpp
Expand Down
8 changes: 4 additions & 4 deletions include/quill/CsvWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class CsvWriter
}()),
quill::PatternFormatterOptions{"%(message)", "", Timezone::GmtTime});

_logger->template log_statement<false>(quill::LogLevel::None, &header_metadata, TCsvSchema::header);
_logger->template log_statement<false, false>(quill::LogLevel::None, &header_metadata, TCsvSchema::header);
}

/**
Expand All @@ -78,7 +78,7 @@ class CsvWriter
Frontend::create_or_get_logger(unique_name + "_csv", std::move(sink),
quill::PatternFormatterOptions{"%(message)", "", Timezone::GmtTime});

_logger->template log_statement<false>(quill::LogLevel::None, &header_metadata, TCsvSchema::header);
_logger->template log_statement<false, false>(quill::LogLevel::None, &header_metadata, TCsvSchema::header);
}

/**
Expand All @@ -92,7 +92,7 @@ class CsvWriter
_logger = Frontend::create_or_get_logger(
unique_name + "_csv", sinks, quill::PatternFormatterOptions{"%(message)", "", Timezone::GmtTime});

_logger->template log_statement<false>(quill::LogLevel::None, &header_metadata, TCsvSchema::header);
_logger->template log_statement<false, false>(quill::LogLevel::None, &header_metadata, TCsvSchema::header);
}

/**
Expand All @@ -112,7 +112,7 @@ class CsvWriter
template <typename... Args>
void append_row(Args&&... fields)
{
_logger->template log_statement<false>(quill::LogLevel::None, &line_metadata, fields...);
_logger->template log_statement<false, false>(quill::LogLevel::None, &line_metadata, fields...);
}

/**
Expand Down
14 changes: 8 additions & 6 deletions include/quill/LogMacros.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,8 +307,9 @@
{ \
if (likelyhood(logger->template should_log_statement<log_level>())) \
{ \
QUILL_DEFINE_MACRO_METADATA(__FUNCTION__, fmt, tags, log_level); \
logger->template log_statement<QUILL_IMMEDIATE_FLUSH>(quill::LogLevel::None, &macro_metadata, ##__VA_ARGS__); \
QUILL_DEFINE_MACRO_METADATA(__FUNCTION__, fmt, tags, log_level); \
logger->template log_statement<QUILL_IMMEDIATE_FLUSH, false>( \
quill::LogLevel::None, &macro_metadata, ##__VA_ARGS__); \
} \
} while (0)

Expand All @@ -335,8 +336,9 @@
{ \
if (QUILL_LIKELY(logger->template should_log_statement<quill::LogLevel::Backtrace>())) \
{ \
QUILL_DEFINE_MACRO_METADATA(__FUNCTION__, fmt, tags, quill::LogLevel::Backtrace); \
logger->template log_statement<QUILL_IMMEDIATE_FLUSH>(quill::LogLevel::None, &macro_metadata, ##__VA_ARGS__); \
QUILL_DEFINE_MACRO_METADATA(__FUNCTION__, fmt, tags, quill::LogLevel::Backtrace); \
logger->template log_statement<QUILL_IMMEDIATE_FLUSH, false>( \
quill::LogLevel::None, &macro_metadata, ##__VA_ARGS__); \
} \
} while (0)

Expand All @@ -349,8 +351,8 @@
{ \
if (logger->should_log_statement(log_level)) \
{ \
QUILL_DEFINE_MACRO_METADATA(__FUNCTION__, fmt, tags, quill::LogLevel::Dynamic); \
logger->template log_statement<QUILL_IMMEDIATE_FLUSH>(log_level, &macro_metadata, ##__VA_ARGS__); \
QUILL_DEFINE_MACRO_METADATA(__FUNCTION__, fmt, tags, quill::LogLevel::Dynamic); \
logger->template log_statement<QUILL_IMMEDIATE_FLUSH, true>(log_level, &macro_metadata, ##__VA_ARGS__); \
} \
} while (0)

Expand Down
29 changes: 19 additions & 10 deletions include/quill/Logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,24 @@ class LoggerImpl : public detail::LoggerBase
*
* @return true if the message is written to the queue, false if it is dropped (when a dropping queue is used)
*/
template <bool immediate_flush, typename... Args>
template <bool immediate_flush, bool has_dynamic_log_level, typename... Args>
QUILL_ATTRIBUTE_HOT bool log_statement(LogLevel dynamic_log_level,
MacroMetadata const* macro_metadata, Args&&... fmt_args)
{
#ifndef NDEBUG
if (has_dynamic_log_level)
{
assert((dynamic_log_level != quill::LogLevel::None) &&
"When has_dynamic_log_level is set to true then dynamic_log_level should not be None");
}

if (dynamic_log_level != quill::LogLevel::None)
{
assert((macro_metadata->log_level() == quill::LogLevel::Dynamic) &&
"MacroMetadata LogLevel must be Dynamic when using a dynamic_log_level");

assert(has_dynamic_log_level &&
"When dynamic_log_level is used then has_dynamic_log_level must also be true");
}

if (macro_metadata->log_level() != quill::LogLevel::Dynamic)
Expand Down Expand Up @@ -119,7 +128,7 @@ class LoggerImpl : public detail::LoggerBase
detail::compute_encoded_size_and_cache_string_lengths(
thread_context->get_conditional_arg_size_cache(), fmt_args...);

if (dynamic_log_level != LogLevel::None)
if constexpr (has_dynamic_log_level)
{
// For the dynamic log level we want to add to the total size to store the dynamic log level
total_size += sizeof(dynamic_log_level);
Expand Down Expand Up @@ -182,7 +191,7 @@ class LoggerImpl : public detail::LoggerBase
// encode remaining arguments
detail::encode(write_buffer, thread_context->get_conditional_arg_size_cache(), fmt_args...);

if (dynamic_log_level != LogLevel::None)
if constexpr (has_dynamic_log_level)
{
// write the dynamic log level
// The reason we write it last is that is less likely to break the alignment in the buffer
Expand Down Expand Up @@ -222,7 +231,7 @@ class LoggerImpl : public detail::LoggerBase

// we pass this message to the queue and also pass capacity as arg
// We do not want to drop the message if a dropping queue is used
while (!this->log_statement<false>(LogLevel::None, &macro_metadata, max_capacity))
while (!this->log_statement<false, false>(LogLevel::None, &macro_metadata, max_capacity))
{
std::this_thread::sleep_for(std::chrono::nanoseconds{100});
}
Expand All @@ -241,7 +250,7 @@ class LoggerImpl : public detail::LoggerBase
"", "", "", nullptr, LogLevel::Critical, MacroMetadata::Event::FlushBacktrace};

// We do not want to drop the message if a dropping queue is used
while (!this->log_statement<false>(LogLevel::None, &macro_metadata))
while (!this->log_statement<false, false>(LogLevel::None, &macro_metadata))
{
std::this_thread::sleep_for(std::chrono::nanoseconds{100});
}
Expand Down Expand Up @@ -272,8 +281,8 @@ class LoggerImpl : public detail::LoggerBase
std::atomic<bool>* backend_thread_flushed_ptr = &backend_thread_flushed;

// We do not want to drop the message if a dropping queue is used
while (!this->log_statement<false>(LogLevel::None, &macro_metadata,
reinterpret_cast<uintptr_t>(backend_thread_flushed_ptr)))
while (!this->log_statement<false, false>(
LogLevel::None, &macro_metadata, reinterpret_cast<uintptr_t>(backend_thread_flushed_ptr)))
{
if (sleep_duration_ns > 0)
{
Expand Down Expand Up @@ -307,8 +316,8 @@ class LoggerImpl : public detail::LoggerBase
LoggerImpl(std::string logger_name, std::vector<std::shared_ptr<Sink>> sinks,
PatternFormatterOptions pattern_formatter_options, ClockSourceType clock_source,
UserClockSource* user_clock)
: detail::LoggerBase(static_cast<std::string&&>(logger_name),
static_cast<std::vector<std::shared_ptr<Sink>>&&>(sinks),
: detail::LoggerBase(
static_cast<std::string&&>(logger_name), static_cast<std::vector<std::shared_ptr<Sink>>&&>(sinks),
static_cast<PatternFormatterOptions&&>(pattern_formatter_options), clock_source, user_clock)

{
Expand All @@ -318,7 +327,7 @@ class LoggerImpl : public detail::LoggerBase
this->clock_source = ClockSourceType::User;
}
}

/**
* Encodes header information into the write buffer
*
Expand Down
6 changes: 3 additions & 3 deletions include/quill/backend/SignalHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ class SignalHandlerContext
if (logger->template should_log_statement<log_level>()) \
{ \
static constexpr quill::MacroMetadata macro_metadata{ \
"SignalHandler:~", "", fmt, nullptr, log_level, quill::MacroMetadata::Event::Log}; \
\
logger->template log_statement<false>(quill::LogLevel::None, &macro_metadata, ##__VA_ARGS__); \
"SignalHandler:~", "", fmt, nullptr, log_level, quill::MacroMetadata::Event::Log}; \
\
logger->template log_statement<false, false>(quill::LogLevel::None, &macro_metadata, ##__VA_ARGS__); \
} \
} while (0)

Expand Down

0 comments on commit 195c930

Please sign in to comment.