Skip to content

Commit cc320fa

Browse files
committed
Introduce Logger concept and eliminate use of std::function for logger injection.
1 parent 2126cd6 commit cc320fa

File tree

1 file changed

+13
-12
lines changed

1 file changed

+13
-12
lines changed

src/iceberg/util/logger.h

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
#pragma once
2121

2222
#include <format>
23-
#include <functional>
2423
#include <memory>
2524
#include <source_location>
2625
#include <string>
@@ -135,6 +134,10 @@ class LoggerInterface {
135134
~LoggerInterface() = default;
136135
};
137136

137+
/// \brief Concept to constrain types that implement the Logger interface
138+
template <typename T>
139+
concept Logger = std::is_base_of_v<LoggerInterface<T>, T>;
140+
138141
/// \brief Default spdlog-based logger implementation
139142
class SpdlogLogger : public LoggerInterface<SpdlogLogger> {
140143
public:
@@ -211,15 +214,13 @@ class LoggerRegistry {
211214
///
212215
/// \tparam LoggerImpl The logger implementation type
213216
/// \param logger The logger instance to set as default
214-
template <typename LoggerImpl>
217+
template <Logger LoggerImpl>
215218
void SetDefaultLogger(std::shared_ptr<LoggerImpl> logger) {
216-
static_assert(std::is_base_of_v<LoggerInterface<LoggerImpl>, LoggerImpl>,
217-
"LoggerImpl must inherit from LoggerInterface");
218219
default_logger_ = std::static_pointer_cast<void>(logger);
219-
log_func_ = [logger](LogLevel level, std::string_view format_str,
220-
const std::string& formatted_message) {
221-
if (logger->ShouldLog(level)) {
222-
logger->LogImpl(level, "{}", formatted_message);
220+
log_func_ = [](const void* logger_ptr, LogLevel level, const std::string& message) {
221+
auto* typed_logger = static_cast<const LoggerImpl*>(logger_ptr);
222+
if (typed_logger->ShouldLog(level)) {
223+
typed_logger->LogImpl(level, "{}", message);
223224
}
224225
};
225226
}
@@ -228,22 +229,22 @@ class LoggerRegistry {
228229
///
229230
/// \tparam LoggerImpl The expected logger implementation type
230231
/// \return Shared pointer to the logger, or nullptr if type doesn't match
231-
template <typename LoggerImpl>
232+
template <Logger LoggerImpl>
232233
std::shared_ptr<LoggerImpl> GetDefaultLogger() const {
233234
return std::static_pointer_cast<LoggerImpl>(default_logger_);
234235
}
235236

236237
/// \brief Log using the default logger
237238
template <typename... Args>
238239
void Log(LogLevel level, std::string_view format_str, Args&&... args) const {
239-
if (log_func_) {
240+
if (default_logger_ && log_func_) {
240241
std::string formatted_message;
241242
if constexpr (sizeof...(args) > 0) {
242243
formatted_message = std::vformat(format_str, std::make_format_args(args...));
243244
} else {
244245
formatted_message = std::string(format_str);
245246
}
246-
log_func_(level, format_str, formatted_message);
247+
log_func_(default_logger_.get(), level, formatted_message);
247248
}
248249
}
249250

@@ -254,7 +255,7 @@ class LoggerRegistry {
254255
LoggerRegistry() = default;
255256

256257
std::shared_ptr<void> default_logger_;
257-
std::function<void(LogLevel, std::string_view, const std::string&)> log_func_;
258+
void (*log_func_)(const void*, LogLevel, const std::string&) = nullptr;
258259
};
259260

260261
/// \brief Convenience macros for logging with automatic source location

0 commit comments

Comments
 (0)