* Copyright (c) 2025-2026 Huawei Technologies Co., Ltd.
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
* CANN Open Software License Agreement Version 2.0 (the "License").
* Please refer to the License for details. You may not use this file except in compliance with the License.
* 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 FITNESS FOR A PARTICULAR PURPOSE.
* See LICENSE in the root of the software repository for the full text of the License.
*/
* \file log_module_manager.cpp
* \brief
*/
#include "host_log/log_module_manager.h"
#include <string>
#include <map>
#include <algorithm>
#include <stdexcept>
#include <iostream>
namespace npu::tile_fwk {
namespace {
constexpr int32_t kInvalidModuleLogLevel = -1;
constexpr const char* kEnvModuleLogLevel = "ASCEND_MODULE_LOG_LEVEL";
const std::map<std::string, LogModule> kLogModuleMap = {
{"FUNCTION", LogModule::FUNCTION},
{"PASS", LogModule::PASS},
{"CODEGEN", LogModule::CODEGEN},
{"MACHINE", LogModule::MACHINE},
{"DISTRIBUTED", LogModule::DISTRIBUTED},
{"SIMULATION", LogModule::SIMULATION},
{"VERIFY", LogModule::VERIFY},
{"COMPILER_MONITOR", LogModule::COMPILER_MONITOR},
{"ADAPTER", LogModule::ADAPTER},
{"PLATFORM", LogModule::PLATFORM}
};
inline bool IsLogLevelValid(const int32_t logLevel) { return logLevel >= DLOG_DEBUG && logLevel <= DLOG_ERROR; }
inline bool IsLogModuleValid(const LogModule logModule)
{
return logModule >= LogModule::FUNCTION && logModule < LogModule::BOTTOM;
}
bool GetEnvStr(const char* envName, std::string& envValue)
{
const size_t envValueMaxLen = 1024UL;
const char* envStr = std::getenv(envName);
if (envStr == nullptr || strnlen(envStr, envValueMaxLen) >= envValueMaxLen) {
return false;
}
envValue = envStr;
return true;
}
int ParseStrToInt(const std::string& str)
{
try {
return std::stoi(str);
} catch (const std::invalid_argument& ia) {
std::cerr << "Invalid argument: " << ia.what() << std::endl;
} catch (const std::out_of_range& oor) {
std::cerr << "Out of Range error: " << oor.what() << std::endl;
}
return -1;
}
void Trim(std::string& s)
{
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int c) { return !std::isspace(c); }));
s.erase(std::find_if(s.rbegin(), s.rend(), [](int c) { return !std::isspace(c); }).base(), s.end());
}
void ParseModuleLogLevel(const std::string& levelStr, std::map<std::string, int>& moduleLogLevel)
{
if (levelStr.empty()) {
return;
}
size_t lastPos = 0;
size_t pos = levelStr.find(":");
while (pos != std::string::npos) {
std::string subLevelStr = levelStr.substr(lastPos, pos - lastPos);
size_t subPos = subLevelStr.find("=");
if (subPos != std::string::npos) {
std::string subModuleName = subLevelStr.substr(0, subPos);
Trim(subModuleName);
moduleLogLevel.emplace(subModuleName, ParseStrToInt(subLevelStr.substr(subPos + 1)));
}
lastPos = pos + 1;
pos = levelStr.find(":", lastPos);
}
std::string subLevelStr = levelStr.substr(lastPos);
size_t subPos = subLevelStr.find("=");
if (subPos != std::string::npos) {
std::string subModuleName = subLevelStr.substr(0, subPos);
Trim(subModuleName);
moduleLogLevel.emplace(subModuleName, ParseStrToInt(subLevelStr.substr(subPos + 1)));
}
}
}
LogModuleManager& LogModuleManager::Instance()
{
static LogModuleManager logModuleManager;
return logModuleManager;
}
LogModuleManager::LogModuleManager()
{
moduleLogLevel_.fill(kInvalidModuleLogLevel);
std::string moduleLogLevelStr;
if (!GetEnvStr(kEnvModuleLogLevel, moduleLogLevelStr)) {
return;
}
std::map<std::string, int> moduleLogLevelMap;
ParseModuleLogLevel(moduleLogLevelStr, moduleLogLevelMap);
for (const auto& item : moduleLogLevelMap) {
auto iter = kLogModuleMap.find(item.first);
if (iter == kLogModuleMap.end()) {
continue;
}
if (!IsLogLevelValid(item.second)) {
continue;
}
moduleLogLevel_[static_cast<size_t>(iter->second)] = item.second;
}
}
LogModuleManager::~LogModuleManager() { moduleLogLevel_.fill(kInvalidModuleLogLevel); }
int32_t LogModuleManager::GetModuleLogLevel(const LogModule logModule) const
{
return IsLogModuleValid(logModule) ? moduleLogLevel_[static_cast<size_t>(logModule)] : kInvalidModuleLogLevel;
}
int32_t LogModuleManager::GetLowestLogLevel() const
{
int32_t lowestLogLevel = kInvalidModuleLogLevel;
for (size_t i = 0; i < moduleLogLevel_.size(); ++i) {
if (!IsLogLevelValid(moduleLogLevel_[i])) {
continue;
}
if (lowestLogLevel < 0 || moduleLogLevel_[i] < lowestLogLevel) {
lowestLogLevel = moduleLogLevel_[i];
}
}
return lowestLogLevel;
}
}