* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
* MindIE is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#ifndef MINDIE_LLM_LOG_H
#define MINDIE_LLM_LOG_H
#include <iostream>
#include <mutex>
#include <sstream>
#include <unordered_map>
#include "common_util.h"
#include "log_config.h"
#include "log_level_dynamic_handler.h"
#include "logger_def.h"
namespace mindie_llm {
using LogLevel = spdlog::level::level_enum;
const std::map<std::string, std::string> ERROR_CODE_MAPPING = {
{"BACKEND_CONFIG_VAL_FAILED", "MIE05E020000"},
{"BACKEND_INIT_FAILED", "MIE05E020001"},
{"LLM_MANAGER_CONFIG_FAILED", "MIE05E030000"},
{"LLM_MANAGER_INIT_FAILED", "MIE05E030001"},
{"TEXT_GENERATOR_PLUGIN_NAME_INVALID", "MIE05E010000"},
{"TEXT_GENERATOR_FEAT_COMPAT_INVALID", "MIE05E010001"},
{"TEXT_GENERATOR_REQ_ID_INVALID", "MIE05E010002"},
{"TEXT_GENERATOR_TEMP_ZERO_DIV_ERR", "MIE05E010003"},
{"TEXT_GENERATOR_REQ_PENALTY_ZERO_DIV_ERR", "MIE05E010004"},
{"TEXT_GENERATOR_ZERO_ITER_ERR", "MIE05E010005"},
{"TEXT_GENERATOR_ZERO_TIME_ERR", "MIE05E010006"},
{"TEXT_GENERATOR_REQ_ID_UNUSED", "MIE05E010007"},
{"TEXT_GENERATOR_GENERATOR_BACKEND_INVALID", "MIE05E010008"},
{"TEXT_GENERATOR_LOGITS_SHAPE_MISMATCH", "MIE05E010009"},
{"TEXT_GENERATOR_MISSING_PREFILL_OR_INVALID_DECODE_REQ", "MIE05E010010"},
{"TEXT_GENERATOR_MAX_BLOCK_SIZE_INVALID", "MIE05E010011"},
{"TEXT_GENERATOR_EOS_TOKEN_ID_TYPE_INVALID", "MIE05E010012"},
{"ATB_MODELS_PARAM_OUT_OF_RANGE", "MIE05E000000"},
{"ATB_MODELS_MODEL_PARAM_JSON_INVALID", "MIE05E000001"},
{"ATB_MODELS_EXECUTION_FAILURE", "MIE05E000002"},
{"ATB_MODELS_PARAM_INVALID", "MIE05E000003"},
{"ATB_MODELS_INTERNAL_ERROR", "MIE05E000004"},
{"ATB_MODELS_OUT_OF_MEMORY", "MIE05E000005"},
};
class Log {
public:
explicit Log(const std::shared_ptr<LogConfig> logConfig);
static std::shared_ptr<Log> GetInstance(LoggerType loggerType);
static void CreateAllLoggers();
static void CreateInstance(LoggerType loggerType);
static const std::shared_ptr<LogConfig> GetLogConfig(LoggerType loggerType);
static void LogMessage(LoggerType loggerType, LogLevel level, const std::string& message);
static void Flush();
static void GetErrorCode(std::ostringstream& oss, const std::string& args);
static std::string GetLevelStr(const LogLevel level);
static std::string GetUserName();
static void SetAllLogLevel(LogLevel level);
static void SetLogLevel(LoggerType loggerType, LogLevel level);
~Log() = default;
private:
void SetFileEventHandle(spdlog::file_event_handlers& handlers) const;
int Initialize(LoggerType loggerType);
bool ShouldPrintToStdout(LoggerType loggerType);
std::string GetLogPattern(LoggerType loggerType);
static std::string GetLoggerFormat(LoggerType loggerType);
static void SanitizeMessage(std::string& msg);
private:
static std::once_flag atbLogInitFlag;
static std::unordered_map<LoggerType, std::shared_ptr<Log>> loggerMap;
std::shared_ptr<spdlog::logger> innerLogger_;
std::shared_ptr<LogConfig> logConfig_;
};
}
template <typename T>
inline std::ostream& operator<<(std::ostream& os, const std::vector<T>& vec) {
for (auto& el : vec) {
os << el << ',';
}
return os;
}
#ifndef LOG_FILENAME
#define LOG_FILENAME (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
#endif
#ifdef FUZZ_TEST
#define MINDIE_LLM_LOG(level, msg, loggerType, ...)
#else
#define MINDIE_LLM_LOG(level, msg, loggerType, ...) \
do { \
if (mindie_llm::Log::GetInstance(loggerType) != nullptr && \
mindie_llm::Log::GetLogConfig(loggerType)->logLevel_ <= (level)) { \
std::ostringstream oss; \
MINDIE_LLM_FORMAT_LOG(oss, level, msg, ##__VA_ARGS__); \
mindie_llm::Log::LogMessage(loggerType, level, oss.str()); \
} \
} while (0)
#endif
#define MINDIE_LLM_FORMAT_LOG(oss, level, msg, ...) \
do { \
oss << mindie_llm::Log::GetLevelStr(level); \
if (mindie_llm::Log::GetLogConfig(mindie_llm::LoggerType::MINDIE_LLM)->logVerbose_) { \
oss << "[" << LOG_FILENAME << ":" << __LINE__ << "] "; \
} \
mindie_llm::Log::GetErrorCode(oss, #__VA_ARGS__); \
oss << msg; \
} while (0)
#define MINDIE_LLM_LOG_WARN(msg, ...) \
MINDIE_LLM_LOG(spdlog::level::warn, msg, mindie_llm::LoggerType::MINDIE_LLM, __VA_ARGS__)
#define MINDIE_LLM_LOG_WARN_REQUEST(msg, ...) \
MINDIE_LLM_LOG(spdlog::level::warn, msg, mindie_llm::LoggerType::MINDIE_LLM_REQUEST, __VA_ARGS__)
#define MINDIE_LLM_LOG_WARN_TOKEN(msg, ...) \
MINDIE_LLM_LOG(spdlog::level::warn, msg, mindie_llm::LoggerType::MINDIE_LLM_TOKEN, __VA_ARGS__)
#define MINDIE_LLM_LOG_ERROR(msg, ...) \
MINDIE_LLM_LOG(spdlog::level::err, msg, mindie_llm::LoggerType::MINDIE_LLM, __VA_ARGS__)
#define MINDIE_LLM_LOG_FATAL(msg, ...) \
MINDIE_LLM_LOG(spdlog::level::critical, msg, mindie_llm::LoggerType::MINDIE_LLM, __VA_ARGS__)
#define MINDIE_LLM_LOG_DEBUG(msg, ...) \
MINDIE_LLM_LOG(spdlog::level::debug, msg, mindie_llm::LoggerType::MINDIE_LLM, __VA_ARGS__)
#define MINDIE_LLM_LOG_DEBUG_REQUEST(msg, ...) \
MINDIE_LLM_LOG(spdlog::level::debug, msg, mindie_llm::LoggerType::MINDIE_LLM_REQUEST, __VA_ARGS__)
#define MINDIE_LLM_LOG_DEBUG_TOKEN(msg, ...) \
MINDIE_LLM_LOG(spdlog::level::debug, msg, mindie_llm::LoggerType::MINDIE_LLM_TOKEN, __VA_ARGS__)
#define MINDIE_LLM_LOG_INFO(msg, ...) \
MINDIE_LLM_LOG(spdlog::level::info, msg, mindie_llm::LoggerType::MINDIE_LLM, __VA_ARGS__)
#define MINDIE_LLM_LOG_INFO_REQUEST(msg, ...) \
MINDIE_LLM_LOG(spdlog::level::info, msg, mindie_llm::LoggerType::MINDIE_LLM_REQUEST, __VA_ARGS__)
#define MINDIE_LLM_LOG_INFO_TOKEN(msg, ...) \
MINDIE_LLM_LOG(spdlog::level::info, msg, mindie_llm::LoggerType::MINDIE_LLM_TOKEN, __VA_ARGS__)
#define ATB_SPEED_LOG(level, msg, ...) \
do { \
if (mindie_llm::Log::GetInstance(mindie_llm::LoggerType::ATB) != nullptr && \
mindie_llm::Log::GetLogConfig(mindie_llm::LoggerType::ATB)->logLevel_ <= (level)) { \
std::ostringstream oss; \
ATB_SPEED_FORMAT_LOG(oss, level, msg, ##__VA_ARGS__); \
mindie_llm::Log::LogMessage(mindie_llm::LoggerType::ATB, level, oss.str()); \
} \
} while (0)
#define ATB_SPEED_FORMAT_LOG(oss, level, msg, ...) \
do { \
oss << mindie_llm::Log::GetLevelStr(level); \
if (mindie_llm::Log::GetLogConfig(mindie_llm::LoggerType::ATB)->logVerbose_) { \
oss << "[" << LOG_FILENAME << ":" << __LINE__ << "] "; \
} \
mindie_llm::Log::GetErrorCode(oss, #__VA_ARGS__); \
oss << msg; \
} while (0)
#define ATB_SPEED_LOG_DEBUG(msg, ...) ATB_SPEED_LOG(spdlog::level::debug, msg, __VA_ARGS__)
#define ATB_SPEED_LOG_INFO(msg, ...) ATB_SPEED_LOG(spdlog::level::info, msg, __VA_ARGS__)
#define ATB_SPEED_LOG_WARN(msg, ...) ATB_SPEED_LOG(spdlog::level::warn, msg, __VA_ARGS__)
#define ATB_SPEED_LOG_ERROR(msg, ...) ATB_SPEED_LOG(spdlog::level::err, msg, __VA_ARGS__)
#define ATB_SPEED_LOG_FATAL(msg, ...) ATB_SPEED_LOG(spdlog::level::critical, msg, __VA_ARGS__)
#ifdef UT_ENABLED
#define ULOG_LOG(level, msg, errCode, submoduleName)
#else
#define ULOG_LOG(level, msg, errCode, submoduleName) \
do { \
if (mindie_llm::Log::GetInstance(mindie_llm::LoggerType::DEBUG) != nullptr && \
mindie_llm::Log::GetLogConfig(mindie_llm::LoggerType::DEBUG)->logLevel_ <= (level)) { \
std::ostringstream oss; \
ULOG_FORMAT_LOG(oss, level, msg, errCode, submoduleName); \
mindie_llm::Log::LogMessage(mindie_llm::LoggerType::DEBUG, level, oss.str()); \
} \
} while (0)
#define ULOG_FORMAT_LOG(oss, level, msg, errCode, submoduleName) \
do { \
if (mindie_llm::Log::GetLogConfig(mindie_llm::LoggerType::DEBUG)->logVerbose_) { \
oss << mindie_llm::Log::GetLevelStr(level) << "[" << LOG_FILENAME << ":" << __LINE__ << "] " << (errCode) \
<< "[" << (submoduleName) << "] "; \
} else { \
oss << errCode; \
} \
oss << msg; \
} while (0)
#endif
#ifdef UT_ENABLED
#define ULOG_DEBUG(submoduleName, msg)
#define ULOG_INFO(submoduleName, msg)
#define ULOG_WARN(submoduleName, errCode, msg)
#define ULOG_ERROR(submoduleName, errCode, msg)
#define ULOG_CRITICAL(submoduleName, errCode, msg)
#else
#define ULOG_DEBUG(submoduleName, msg) ULOG_LOG(spdlog::level::debug, msg, "", submoduleName)
#define ULOG_INFO(submoduleName, msg) ULOG_LOG(spdlog::level::info, msg, "", submoduleName)
#define ULOG_WARN(submoduleName, errCode, msg) ULOG_LOG(spdlog::level::warn, msg, errCode, submoduleName)
#define ULOG_ERROR(submoduleName, errCode, msg) ULOG_LOG(spdlog::level::err, msg, errCode, submoduleName)
#define ULOG_CRITICAL(submoduleName, errCode, msg) ULOG_LOG(spdlog::level::critical, msg, errCode, submoduleName)
#endif
#ifdef UT_ENABLED
#define ULOG_AUDIT(userID, moduleName, operation, ret)
#else
#define ULOG_AUDIT(userID, moduleName, operation, ret) \
do { \
if (mindie_llm::Log::GetInstance(mindie_llm::LoggerType::SECURITY) != nullptr) { \
std::ostringstream oss; \
oss << "[" << mindie_llm::Log::GetUserName() << "] [" << (userID) << "] [" << moduleName << "] [" \
<< operation << "] [" << ret << "]"; \
mindie_llm::Log::LogMessage(mindie_llm::LoggerType::SECURITY, spdlog::level::info, oss.str()); \
} \
} while (0)
#endif
#endif