Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Logger accessors #600

Merged
merged 2 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
- [v7.4.0](#v740)
- [v7.3.0](#v730)
- [v7.2.2](#v722)
- [v7.2.1](#v721)
Expand Down Expand Up @@ -78,6 +79,11 @@
- [v1.1.0](#v110)
- [v1.0.0](#v100)

## v7.4.0

- Added accessors to `Logger` for sinks, user clock source, clock source type, and pattern formatter options that can be
used to create another `Logger` with similar configuration

## v7.3.0

- Added the option to explicitly specify the `Logger` used by the built-in `SignalHandler` for logging errors during
Expand Down
2 changes: 1 addition & 1 deletion MODULE.bazel
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module(
name = "quill",
version = "7.3.0",
version = "7.4.0",
compatibility_level = 1,
)

Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def configureDoxyfile(input_dir, output_dir):
project = 'Quill'
copyright = '2024, Odysseas Georgoudis'
author = 'Odysseas Georgoudis'
release = 'v7.3.0'
release = 'v7.4.0'

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
Expand Down
2 changes: 1 addition & 1 deletion include/quill/Backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ QUILL_BEGIN_NAMESPACE

/** Version Info - When updating VersionMajor please also update the namespace in Attributes.h **/
constexpr uint32_t VersionMajor{7};
constexpr uint32_t VersionMinor{3};
constexpr uint32_t VersionMinor{4};
constexpr uint32_t VersionPatch{0};
constexpr uint32_t Version{VersionMajor * 10000 + VersionMinor * 100 + VersionPatch};

Expand Down
36 changes: 35 additions & 1 deletion include/quill/core/LoggerBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ class LoggerBase
public:
/***/
LoggerBase(std::string logger_name, std::vector<std::shared_ptr<Sink>> sinks,
PatternFormatterOptions pattern_formatter_options, ClockSourceType clock_source, UserClockSource* user_clock)
PatternFormatterOptions pattern_formatter_options, ClockSourceType clock_source,
UserClockSource* user_clock)
: logger_name(static_cast<std::string&&>(logger_name)),
user_clock(user_clock),
pattern_formatter_options(static_cast<PatternFormatterOptions&&>(pattern_formatter_options)),
Expand Down Expand Up @@ -67,6 +68,39 @@ class LoggerBase
*/
QUILL_NODISCARD std::string const& get_logger_name() const noexcept { return logger_name; }

/**
* Returns the user-defined clock source.
* @return A pointer to the constant UserClockSource object.
*/
QUILL_NODISCARD UserClockSource* get_user_clock_source() const noexcept {
return user_clock;
}

/**
* Returns the type of clock source being used.
* @return The ClockSourceType enum value representing the current clock source.
*/
QUILL_NODISCARD ClockSourceType get_clock_source_type() const noexcept { return clock_source; }

/**
* Returns the pattern formatter options.
* @return A constant reference to the PatternFormatterOptions object.
*/
QUILL_NODISCARD PatternFormatterOptions const& get_pattern_formatter_options() const noexcept
{
return pattern_formatter_options;
}

/**
* Returns a const reference to the sinks vector.
* @warning The returned sinks should be treated as read-only. Do not modify the Sink objects as they are used by the backend thread
* @return A constant reference to the std::vector<std::shared_ptr<Sink>> object
*/
QUILL_NODISCARD std::vector<std::shared_ptr<Sink>> const& get_sinks() const noexcept
{
return sinks;
}

/**
* This function sets the logger's validity flag to false, indicating that the logger is no longer valid.
*/
Expand Down
82 changes: 45 additions & 37 deletions include/quill/sinks/Sink.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,14 @@

QUILL_BEGIN_NAMESPACE

/** Forward Declaration **/
/** Forward Declarations **/
class MacroMetadata;

namespace detail
{
class BackendWorker;
}

/**
* Base class for sinks
*/
Expand All @@ -46,42 +51,6 @@ class Sink
Sink(Sink const&) = delete;
Sink& operator=(Sink const&) = delete;

/**
* @brief Logs a formatted log message to the sink.
* @note Accessor for backend processing.
* @param log_metadata Pointer to the macro metadata.
* @param log_timestamp Timestamp of the log event.
* @param thread_id ID of the thread.
* @param thread_name Name of the thread.
* @param process_id Process Id
* @param logger_name Name of the logger.
* @param log_level Log level of the message.
* @param log_level_description Description of the log level.
* @param log_level_short_code Short code representing the log level.
* @param named_args Vector of key-value pairs of named args
* @param log_message The log message.
* @param log_statement The log statement.
*/
QUILL_ATTRIBUTE_HOT virtual void write_log(
MacroMetadata const* log_metadata, uint64_t log_timestamp, std::string_view thread_id,
std::string_view thread_name, std::string const& process_id, std::string_view logger_name,
LogLevel log_level, std::string_view log_level_description, std::string_view log_level_short_code,
std::vector<std::pair<std::string, std::string>> const* named_args,
std::string_view log_message, std::string_view log_statement) = 0;

/**
* @brief Flushes the sink, synchronizing the associated sink with its controlled output sequence.
*/
QUILL_ATTRIBUTE_HOT virtual void flush_sink() = 0;

/**
* @brief Executes periodic tasks by the backend thread, providing an opportunity for the user
* to perform custom tasks. For example, batch committing to a database, or any other
* desired periodic operations.
* @note It is recommended to avoid heavy operations within this function as it may affect performance of the backend thread.
*/
QUILL_ATTRIBUTE_HOT virtual void run_periodic_tasks() noexcept {}

/**
* @brief Sets a log level filter on the sink.
* @note Thread safe.
Expand Down Expand Up @@ -128,6 +97,43 @@ class Sink
_new_filter.store(true, std::memory_order_relaxed);
}

protected:
/**
* @brief Logs a formatted log message to the sink.
* @note Accessor for backend processing.
* @param log_metadata Pointer to the macro metadata.
* @param log_timestamp Timestamp of the log event.
* @param thread_id ID of the thread.
* @param thread_name Name of the thread.
* @param process_id Process Id
* @param logger_name Name of the logger.
* @param log_level Log level of the message.
* @param log_level_description Description of the log level.
* @param log_level_short_code Short code representing the log level.
* @param named_args Vector of key-value pairs of named args
* @param log_message The log message.
* @param log_statement The log statement.
*/
QUILL_ATTRIBUTE_HOT virtual void write_log(
MacroMetadata const* log_metadata, uint64_t log_timestamp, std::string_view thread_id,
std::string_view thread_name, std::string const& process_id, std::string_view logger_name,
LogLevel log_level, std::string_view log_level_description, std::string_view log_level_short_code,
std::vector<std::pair<std::string, std::string>> const* named_args,
std::string_view log_message, std::string_view log_statement) = 0;

/**
* @brief Flushes the sink, synchronizing the associated sink with its controlled output sequence.
*/
QUILL_ATTRIBUTE_HOT virtual void flush_sink() = 0;

/**
* @brief Executes periodic tasks by the backend thread, providing an opportunity for the user
* to perform custom tasks. For example, batch committing to a database, or any other
* desired periodic operations.
* @note It is recommended to avoid heavy operations within this function as it may affect performance of the backend thread.
*/
QUILL_ATTRIBUTE_HOT virtual void run_periodic_tasks() noexcept {}

/**
* @brief Applies all registered filters to the log record.
* @note Called internally by the backend worker thread.
Expand Down Expand Up @@ -185,6 +191,8 @@ class Sink
}

private:
friend class detail::BackendWorker;

/** Local Filters for this sink **/
std::vector<Filter*> _local_filters;

Expand Down
2 changes: 1 addition & 1 deletion meson.build
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
project('quill', 'cpp', version : '7.3.0', default_options : ['warning_level=3', 'cpp_std=c++17'])
project('quill', 'cpp', version : '7.4.0', default_options : ['warning_level=3', 'cpp_std=c++17'])

inc_dirs = include_directories('include')

Expand Down
12 changes: 11 additions & 1 deletion test/unit_tests/LoggerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ TEST_CASE("check_logger")
LoggerManager& lm = LoggerManager::instance();

std::vector<std::shared_ptr<Sink>> sinks;
sinks.push_back(std::move(sink));
sinks.push_back(sink);

Logger* logger_1 = static_cast<Logger*>(lm.create_or_get_logger<Logger>(
"logger_1", std::move(sinks),
Expand All @@ -30,6 +30,16 @@ TEST_CASE("check_logger")
// Check default log level
REQUIRE_EQ(logger_1->get_log_level(), LogLevel::Info);
REQUIRE_EQ(logger_1->get_logger_name(), "logger_1");
REQUIRE_EQ(logger_1->get_pattern_formatter_options().add_metadata_to_multi_line_logs, false);
REQUIRE_EQ(logger_1->get_pattern_formatter_options().format_pattern,
"%(time) [%(thread_id)] %(short_source_location:<28) "
"LOG_%(log_level:<9) %(logger:<12) %(message)");
REQUIRE_EQ(logger_1->get_pattern_formatter_options().timestamp_pattern, "%H:%M:%S.%Qns");
REQUIRE_EQ(logger_1->get_pattern_formatter_options().timestamp_timezone, quill::Timezone::GmtTime);
REQUIRE_EQ(logger_1->get_clock_source_type(), ClockSourceType::Tsc);
REQUIRE_EQ(logger_1->get_user_clock_source(), nullptr);
REQUIRE_EQ(logger_1->get_sinks().size(), 1);
REQUIRE_EQ(logger_1->get_sinks().front().get(), sink.get());

#ifndef QUILL_NO_EXCEPTIONS
// throw if backtrace log level is used
Expand Down