From 508f0a8a1ebdd50969b4615ba0769d5597001fc4 Mon Sep 17 00:00:00 2001 From: Nicholas Barbier Date: Wed, 10 Dec 2025 13:09:28 -0500 Subject: [PATCH] Add log callback support to Logger class This adds the ability to register a callback function that receives log messages, enabling integration with external logging systems. Features: - New LogCallbackFn typedef for the callback function signature - SetLogCallback() method to register/unregister callbacks - Callbacks receive log level, source filename, line number, and message - Option to replace default logging or use callback in addition to it - LOG_SET_CALLBACK macro for convenient access The callback is invoked from the Log() method before (or instead of) writing to stdout/stderr/file, depending on the replace_default_logger setting. Resolves triton-inference-server/server#8304 --- include/triton/common/logging.h | 50 +++++++++++++++++++++++++++++++-- src/logging.cc | 18 ++++++++++-- 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/include/triton/common/logging.h b/include/triton/common/logging.h index bb5a9b3..c589718 100644 --- a/include/triton/common/logging.h +++ b/include/triton/common/logging.h @@ -64,6 +64,20 @@ class Logger { inline static const std::array(Level::kEND)> LEVEL_NAMES{"E", "W", "I"}; + // Type for log callback function. + // When set, this callback is invoked for each log message instead of + // (or in addition to) writing to file/stdout/stderr. + // + // Parameters: + // level - The log level (kERROR, kWARNING, kINFO) + // filename - Source file where the log originated + // line - Line number in the source file + // msg - The formatted log message + // userp - User-provided pointer passed to SetLogCallback + typedef void (*LogCallbackFn)( + Level level, const char* filename, int line, const char* msg, + void* userp); + Logger(); // Is a log level enabled. @@ -140,8 +154,32 @@ class Logger { return std::string(); } - // Log a message. - void Log(const std::string& msg, const Logger::Level level); + // Set a callback function to receive log messages. + // When set, the callback will be invoked for each log message. + // If 'replace_default_logger' is true, the callback replaces the + // default logging behavior. If false, the callback is called + // in addition to the default logging. + // + // Parameters: + // callback_fn - The callback function to invoke, or nullptr to disable + // userp - User-provided pointer passed to callback + // replace_default_logger - If true, callback replaces default logging + void SetLogCallback( + LogCallbackFn callback_fn, void* userp, bool replace_default_logger) + { + const std::lock_guard lock(mutex_); + log_callback_ = callback_fn; + log_callback_userp_ = userp; + replace_default_logger_ = replace_default_logger; + } + + // Get the current log callback function. + LogCallbackFn LogCallback() const { return log_callback_; } + + // Log a message. Extended version that includes source location. + void Log( + const std::string& msg, const Logger::Level level, + const char* filename = nullptr, int line = 0); // Flush the log. void Flush(); @@ -156,6 +194,11 @@ class Logger { std::mutex mutex_; std::string filename_; std::ofstream file_stream_; + + // Log callback support + LogCallbackFn log_callback_ = nullptr; + void* log_callback_userp_ = nullptr; + bool replace_default_logger_ = false; }; extern Logger gLogger_; @@ -219,6 +262,9 @@ class LogMessage { static_cast(std::max(0, (L)))) #define LOG_SET_OUT_FILE(FN) triton::common::gLogger_.SetLogFile((FN)) #define LOG_SET_FORMAT(F) triton::common::gLogger_.SetLogFormat((F)) +#define LOG_SET_CALLBACK(CB, USERP, REPLACE) \ + triton::common::gLogger_.SetLogCallback((CB), (USERP), (REPLACE)) +#define LOG_CALLBACK triton::common::gLogger_.LogCallback() #define LOG_VERBOSE_LEVEL triton::common::gLogger_.VerboseLevel() #define LOG_FORMAT triton::common::gLogger_.LogFormat() diff --git a/src/logging.cc b/src/logging.cc index 89f162c..8622fb8 100644 --- a/src/logging.cc +++ b/src/logging.cc @@ -48,9 +48,22 @@ Logger::Logger() } void -Logger::Log(const std::string& msg, const Level level) +Logger::Log( + const std::string& msg, const Level level, const char* filename, int line) { const std::lock_guard lock(mutex_); + + // Invoke callback if set + if (log_callback_ != nullptr) { + log_callback_(level, filename, line, msg.c_str(), log_callback_userp_); + + // If callback replaces default logger, don't also write to file/stdout + if (replace_default_logger_) { + return; + } + } + + // Default logging behavior if (file_stream_.is_open()) { file_stream_ << msg << std::endl; } else if (level == Level::kINFO) { @@ -154,7 +167,8 @@ LogMessage::~LogMessage() log_record << escaped_heading << '\n'; } log_record << escaped_message; - gLogger_.Log(log_record.str(), level_); + // Pass source location info to Log() for callback support + gLogger_.Log(log_record.str(), level_, path_.c_str(), line_); } }} // namespace triton::common