diff --git a/projects/hipdnn/backend/src/logging/ComponentFormatter.hpp b/projects/hipdnn/backend/src/logging/ComponentFormatter.hpp deleted file mode 100644 index 213ccdd1be1..00000000000 --- a/projects/hipdnn/backend/src/logging/ComponentFormatter.hpp +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright © Advanced Micro Devices, Inc., or its affiliates. -// SPDX-License-Identifier: MIT - -#pragma once - -#include "LoggingUtils.hpp" -#include -#include -#include -#include - -namespace hipdnn_backend::logging -{ - -class ComponentFormatter final : public spdlog::formatter -{ -public: - // NOLINTNEXTLINE(modernize-use-equals-default) - not trivial, has member initializer - ComponentFormatter() - : _callbackReceiverFormatter{ - std::make_unique(generateCallbackReceiverPatternString())} - { - } - - // NOLINTNEXTLINE(readability-convert-member-functions-to-static) - virtual override - void format(const spdlog::details::log_msg& msg, spdlog::memory_buf_t& dest) override - { - // The logger "hipdnn_callback_receiver" receives pre-formatted strings from a callback sink. - // The component name is already prepended to the message, so we use a pattern without [component]. - if(msg.logger_name == "hipdnn_callback_receiver") - { - _callbackReceiverFormatter->format(msg, dest); - } - else - { - auto standardFormatter = std::make_unique( - generatePatternString(std::string(msg.logger_name.data(), msg.logger_name.size()))); - standardFormatter->format(msg, dest); - } - } - - // NOLINTNEXTLINE(readability-convert-member-functions-to-static) - virtual override - std::unique_ptr clone() const override - { - return std::make_unique(); - } - -private: - std::unique_ptr _callbackReceiverFormatter; -}; - -} // namespace hipdnn_backend::logging diff --git a/projects/hipdnn/backend/src/logging/Logging.cpp b/projects/hipdnn/backend/src/logging/Logging.cpp index 398a9ec3cb6..e7906e32945 100644 --- a/projects/hipdnn/backend/src/logging/Logging.cpp +++ b/projects/hipdnn/backend/src/logging/Logging.cpp @@ -2,7 +2,6 @@ // SPDX-License-Identifier: MIT #include "Logging.hpp" -#include "ComponentFormatter.hpp" #include "PlatformUtils.hpp" #include @@ -31,7 +30,16 @@ namespace std::mutex s_loggingInitMutex; // NOLINT(readability-identifier-naming) bool s_loggingInitialized = false; // NOLINT(readability-identifier-naming) const std::string S_BACKEND_LOGGER_NAME = "hipdnn_backend"; -const std::string S_CALLBACK_RECEIVER_LOGGER_NAME = "hipdnn_callback_receiver"; + +// Pattern string for the backend logger. +// Component name is already included in messages (e.g., "[hipdnn_backend] ..."), +// so the pattern includes timestamp, thread ID, and log level, but not a component name. +constexpr const char* BACKEND_LOGGER_PATTERN = "[%Y-%m-%d %H:%M:%S.%e] [tid %t] [%l] %v"; + +std::shared_ptr getBackendLogger() +{ + return spdlog::get(S_BACKEND_LOGGER_NAME); +} } // namespace @@ -130,21 +138,19 @@ void initialize() auto backendLogger = std::make_shared( S_BACKEND_LOGGER_NAME, sharedSink, spdlog::thread_pool()); - // In spdlog, the formatting is a property of the underlying sink, not the logger. - // However, we need one destination sink for thread safety because the mutex is attached to the sink. - // Therefore, we implement a custom formatter to have distinct formatting for the backend, which does not use a callback sink. - backendLogger->set_formatter( - std::make_unique()); - spdlog::register_logger(backendLogger); + // Use a simple pattern formatter for the single unified logger + // Component name is already included in the message (e.g., "[hipdnn_backend] ...") + backendLogger->set_pattern(BACKEND_LOGGER_PATTERN); - auto callbackReceiverLogger = std::make_shared( - S_CALLBACK_RECEIVER_LOGGER_NAME, sharedSink, spdlog::thread_pool()); - // Use ComponentFormatter which detects "hipdnn_callback_receiver" and applies appropriate formatting - callbackReceiverLogger->set_formatter( - std::make_unique()); - spdlog::register_logger(callbackReceiverLogger); + // Set spdlog to accept all messages (trace is most verbose) + // Actual filtering is done in HIPDNN_BACKEND_LOG*() macro via isLogLevelEnabled() + backendLogger->set_level(spdlog::level::trace); + + spdlog::register_logger(backendLogger); - setLogLevel(logLevel); + // Update the data_sdk log level cache for use by the + // HIPDNN_BACKEND_LOG*() macros to filter-out logs based on level. + hipdnn_data_sdk::logging::setLogLevel(logLevel); s_loggingInitialized = true; @@ -167,66 +173,47 @@ void cleanup() s_loggingInitialized = false; } -void setLogLevel(hipdnnSeverity_t severity) +namespace +{ +// Helper to convert hipdnnSeverity_t to spdlog level +spdlog::level::level_enum toSpdlogLevel(hipdnnSeverity_t severity) { switch(severity) { - case HIPDNN_SEV_OFF: - spdlog::set_level(spdlog::level::off); - break; - case HIPDNN_SEV_INFO: - spdlog::set_level(spdlog::level::info); - break; - case HIPDNN_SEV_WARN: - spdlog::set_level(spdlog::level::warn); - break; - case HIPDNN_SEV_ERROR: - spdlog::set_level(spdlog::level::err); - break; case HIPDNN_SEV_FATAL: - spdlog::set_level(spdlog::level::critical); - break; + return spdlog::level::critical; + case HIPDNN_SEV_ERROR: + return spdlog::level::err; + case HIPDNN_SEV_WARN: + return spdlog::level::warn; + case HIPDNN_SEV_INFO: + return spdlog::level::info; + case HIPDNN_SEV_OFF: default: - // Unknown severity, default to off - spdlog::set_level(spdlog::level::off); - break; + return spdlog::level::off; } } +} // namespace -std::shared_ptr getCallbackReceiverLogger() +void logMessage(hipdnnSeverity_t severity, const std::string& message) { - return spdlog::get(S_CALLBACK_RECEIVER_LOGGER_NAME); -} + // Check log level using data_sdk infrastructure + if(!hipdnn_data_sdk::logging::isLogLevelEnabled(severity)) + { + return; + } -std::shared_ptr getBackendLogger() -{ - return spdlog::get(S_BACKEND_LOGGER_NAME); + if(auto logger = getBackendLogger()) + { + logger->log(toSpdlogLevel(severity), message); + } } void hipdnnLoggingCallback(hipdnnSeverity_t severity, const char* msg) { - initialize(); - - if(auto logger = getCallbackReceiverLogger()) - { - switch(severity) - { - case HIPDNN_SEV_FATAL: - logger->critical(msg); - break; - case HIPDNN_SEV_ERROR: - logger->error(msg); - break; - case HIPDNN_SEV_WARN: - logger->warn(msg); - break; - case HIPDNN_SEV_OFF: - break; - default: - logger->info(msg); - break; - } - } + // Message already includes component name from source (frontend/plugins) + // Route through central backend logMessage function + logMessage(severity, msg); } } // namespace logging diff --git a/projects/hipdnn/backend/src/logging/Logging.hpp b/projects/hipdnn/backend/src/logging/Logging.hpp index 7b68e873273..4a99533cb95 100644 --- a/projects/hipdnn/backend/src/logging/Logging.hpp +++ b/projects/hipdnn/backend/src/logging/Logging.hpp @@ -12,25 +12,52 @@ // Backend-specific logging macros // These are separate from HIPDNN_LOG_* used by frontend/plugins to avoid conflicts #ifdef HIPDNN_BACKEND_COMPILATION -#define _HIPDNN_BACKEND_LOG_ACTION(spdlog_level, ...) \ - do \ - { \ - hipdnn_backend::logging::initialize(); \ - auto _logger = hipdnn_backend::logging::getBackendLogger(); \ - if(_logger && _logger->should_log(spdlog_level)) \ - { \ - _logger->log(spdlog_level, __VA_ARGS__); \ - } \ +#include +#include + +#define HIPDNN_BACKEND_LOG_INFO(...) \ + do \ + { \ + hipdnn_backend::logging::initialize(); \ + if(hipdnn_data_sdk::logging::isLogLevelEnabled(HIPDNN_SEV_INFO)) \ + { \ + hipdnn_backend::logging::logMessage( \ + HIPDNN_SEV_INFO, fmt::format("[hipdnn_backend] {}", fmt::format(__VA_ARGS__))); \ + } \ + } while(0) + +#define HIPDNN_BACKEND_LOG_WARN(...) \ + do \ + { \ + hipdnn_backend::logging::initialize(); \ + if(hipdnn_data_sdk::logging::isLogLevelEnabled(HIPDNN_SEV_WARN)) \ + { \ + hipdnn_backend::logging::logMessage( \ + HIPDNN_SEV_WARN, fmt::format("[hipdnn_backend] {}", fmt::format(__VA_ARGS__))); \ + } \ + } while(0) + +#define HIPDNN_BACKEND_LOG_ERROR(...) \ + do \ + { \ + hipdnn_backend::logging::initialize(); \ + if(hipdnn_data_sdk::logging::isLogLevelEnabled(HIPDNN_SEV_ERROR)) \ + { \ + hipdnn_backend::logging::logMessage( \ + HIPDNN_SEV_ERROR, fmt::format("[hipdnn_backend] {}", fmt::format(__VA_ARGS__))); \ + } \ } while(0) -#define HIPDNN_BACKEND_LOG_INFO(...) \ - _HIPDNN_BACKEND_LOG_ACTION(spdlog::level::level_enum::info, __VA_ARGS__) -#define HIPDNN_BACKEND_LOG_WARN(...) \ - _HIPDNN_BACKEND_LOG_ACTION(spdlog::level::level_enum::warn, __VA_ARGS__) -#define HIPDNN_BACKEND_LOG_ERROR(...) \ - _HIPDNN_BACKEND_LOG_ACTION(spdlog::level::level_enum::err, __VA_ARGS__) -#define HIPDNN_BACKEND_LOG_FATAL(...) \ - _HIPDNN_BACKEND_LOG_ACTION(spdlog::level::level_enum::critical, __VA_ARGS__) +#define HIPDNN_BACKEND_LOG_FATAL(...) \ + do \ + { \ + hipdnn_backend::logging::initialize(); \ + if(hipdnn_data_sdk::logging::isLogLevelEnabled(HIPDNN_SEV_FATAL)) \ + { \ + hipdnn_backend::logging::logMessage( \ + HIPDNN_SEV_FATAL, fmt::format("[hipdnn_backend] {}", fmt::format(__VA_ARGS__))); \ + } \ + } while(0) #endif // HIPDNN_BACKEND_COMPILATION namespace hipdnn_backend::logging @@ -40,11 +67,7 @@ void initialize(); void cleanup(); -void setLogLevel(hipdnnSeverity_t severity); - -std::shared_ptr getBackendLogger(); - -std::shared_ptr getCallbackReceiverLogger(); +void logMessage(hipdnnSeverity_t severity, const std::string& message); void hipdnnLoggingCallback(hipdnnSeverity_t severity, const char* msg); diff --git a/projects/hipdnn/backend/src/logging/LoggingUtils.hpp b/projects/hipdnn/backend/src/logging/LoggingUtils.hpp deleted file mode 100644 index 8729a6bedfb..00000000000 --- a/projects/hipdnn/backend/src/logging/LoggingUtils.hpp +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright © Advanced Micro Devices, Inc., or its affiliates. -// SPDX-License-Identifier: MIT - -#pragma once - -#include - -namespace hipdnn_backend::logging -{ - -/** - * @brief Generate the spdlog pattern string for a component - * - * This is used internally by the backend for formatting log messages. - * The pattern includes timestamp, thread ID, log level, and component name. - * - * @param componentName The name of the component - * @return The spdlog pattern string - */ -inline std::string generatePatternString(const std::string& componentName) -{ - return "[%Y-%m-%d %H:%M:%S.%e] [tid %t] [%l] [" + componentName + "] %v"; -} - -/** - * @brief Generate the spdlog pattern string for callback-received messages - * - * This is used for messages received via the logging callback from non-backend components. - * The component name is already prepended to the message, so we only add timestamp, thread ID, and level. - * - * @return The spdlog pattern string - */ -inline std::string generateCallbackReceiverPatternString() -{ - return "[%Y-%m-%d %H:%M:%S.%e] [tid %t] [%l] %v"; -} - -} // namespace hipdnn_backend::logging