* 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.
*/
#include "log_config.h"
#include <fcntl.h>
#include "check_utils.h"
#include "common_util.h"
#include "file_system.h"
#include "log_utils.h"
namespace mindie_llm {
const char *MODULE_NAME_LLM = "llm";
const char *MODULE_NAME_ATB = "llmmodels";
const char *MODULE_NAME_SERVER = "server";
const char *LOGGER_NAME_LLM_TOKEN = "llm-token";
const char *LOGGER_NAME_LLM_REQUEST = "llm-request";
const char *ALL_COMPONENT_NAME = "*";
const std::unordered_map<LoggerType, std::string> LOGGER_NAME_MAP{
{LoggerType::MINDIE_LLM, MODULE_NAME_LLM},
{LoggerType::MINDIE_LLM_REQUEST, LOGGER_NAME_LLM_REQUEST},
{LoggerType::MINDIE_LLM_TOKEN, LOGGER_NAME_LLM_TOKEN},
{LoggerType::ATB, MODULE_NAME_ATB},
{LoggerType::SECURITY, MODULE_NAME_SERVER},
{LoggerType::DEBUG, MODULE_NAME_SERVER}};
const std::unordered_map<LoggerType, std::string> MODULE_NAME_MAP{{LoggerType::MINDIE_LLM, MODULE_NAME_LLM},
{LoggerType::ATB, MODULE_NAME_ATB},
{LoggerType::SECURITY, MODULE_NAME_SERVER},
{LoggerType::DEBUG, MODULE_NAME_SERVER}};
LogConfig::LogConfig(const LogConfig &config)
: logToStdOut_(config.logToStdOut_),
logToFile_(config.logToFile_),
logVerbose_(config.logVerbose_),
logLevel_(config.logLevel_),
baseDir_(config.baseDir_),
logFilePath_(config.logFilePath_),
logFileSize_(config.logFileSize_),
logFileCount_(config.logFileCount_) {}
int LogConfig::Init(LoggerType loggerType) {
InitLogToStdoutFlag(loggerType);
InitLogToFileFlag(loggerType);
InitLogLevel(loggerType);
InitLogFilePath(loggerType);
InitLogVerbose(loggerType);
InitLogRotationParam(loggerType);
return LOG_OK;
}
void LogConfig::InitLogToStdoutFlag(LoggerType loggerType) {
const char *mindieLogToStdout = std::getenv("MINDIE_LOG_TO_STDOUT");
if (mindieLogToStdout != nullptr) {
LogUtils::SetMindieLogParamBool(loggerType, logToStdOut_, mindieLogToStdout);
return;
}
}
void LogConfig::InitLogToFileFlag(LoggerType loggerType) {
const char *mindieLogToFile = std::getenv("MINDIE_LOG_TO_FILE");
if (mindieLogToFile != nullptr) {
LogUtils::SetMindieLogParamBool(loggerType, logToFile_, mindieLogToFile);
return;
}
}
void LogConfig::InitLogLevel(LoggerType loggerType) {
const char *mindieLogLevel = std::getenv("MINDIE_LOG_LEVEL");
if (mindieLogLevel != nullptr) {
LogUtils::SetMindieLogParamLevel(loggerType, logLevel_, mindieLogLevel);
return;
}
logLevel_ = DEFAULT_LOG_LEVEL;
}
void LogConfig::InitLogFilePath(LoggerType loggerType) {
const char *mindieLogPath = std::getenv("MINDIE_LOG_PATH");
std::string lastDir = "/debug";
if (loggerType == LoggerType::SECURITY) {
lastDir = "/security";
}
if (mindieLogPath != nullptr) {
LogUtils::SetMindieLogParamString(loggerType, logFilePath_, mindieLogPath);
if (logFilePath_[0] != '/') {
logFilePath_ = DEFAULT_LOG_PATH + "/" + logFilePath_ + lastDir;
} else {
logFilePath_ = logFilePath_ + "/log" + lastDir;
}
} else {
logFilePath_ = DEFAULT_LOG_PATH + lastDir;
}
LogUtils::GetLogFileName(loggerType, logFilePath_);
}
void LogConfig::InitLogVerbose(LoggerType loggerType) {
const char *mindieLogVerbose = std::getenv("MINDIE_LOG_VERBOSE");
if (mindieLogVerbose != nullptr) {
LogUtils::SetMindieLogParamBool(loggerType, logVerbose_, mindieLogVerbose);
return;
}
}
void LogConfig::InitLogRotationParam(LoggerType loggerType) {
if (loggerType == LoggerType::MINDIE_LLM_TOKEN) {
logFileSize_ = 1 * 1024 * 1024;
logFileCount_ = 2;
return;
}
const char *mindieLogRotate = std::getenv("MINDIE_LOG_ROTATE");
if (mindieLogRotate != nullptr) {
LogUtils::SetMindieLogParamString(loggerType, logRotateConfig_, mindieLogRotate);
LogUtils::UpdateLogFileParam(logRotateConfig_, logFileSize_, logFileCount_);
return;
}
}
int LogConfig::ValidateSettings() {
if (!logToFile_) {
return LOG_OK;
}
if (!CheckAndGetLogPath(logFilePath_)) {
std::cout << "Cannot get the log path." << std::endl;
return LOG_INVALID_PARAM;
}
if (logFileSize_ > MAX_ROTATION_FILE_SIZE_LIMIT || logFileSize_ < MIN_ROTATION_FILE_SIZE_LIMIT) {
std::cout << "Invalid max file size, which should be greater than " << MIN_ROTATION_FILE_SIZE_LIMIT
<< " bytes and less than " << MAX_ROTATION_FILE_SIZE_LIMIT << " bytes." << std::endl;
return LOG_INVALID_PARAM;
}
if (logFileCount_ > MAX_ROTATION_FILE_COUNT_LIMIT || logFileCount_ < MIN_ROTATION_FILE_COUNT_LIMIT) {
std::cout << "Invalid max file count, which should be greater than " << MIN_ROTATION_FILE_COUNT_LIMIT
<< " and less than " << MAX_ROTATION_FILE_COUNT_LIMIT;
return LOG_INVALID_PARAM;
}
return LOG_OK;
}
void LogConfig::MakeDirsWithTimeOut(const std::string &parentPath) const {
uint32_t limitTime = 500;
auto start = std::chrono::steady_clock::now();
std::chrono::milliseconds timeout(limitTime);
while (!FileSystem::Exists(parentPath)) {
auto it = FileSystem::Makedirs(parentPath, MAX_LOG_DIR_PERM);
if (it) {
break;
}
auto elapsed = std::chrono::steady_clock::now() - start;
if (elapsed >= timeout) {
std::cout << "Create dirs failed : timed out!" << std::endl;
break;
}
}
}
bool LogConfig::CheckAndGetLogPath(const std::string &configLogPath) {
if (configLogPath.empty()) {
std::cout << "The path of log in config is empty." << std::endl;
return false;
}
std::string filePath = configLogPath;
std::string baseDir = "/";
if (configLogPath[0] != '/') {
const char *homePath = std::getenv("HOME");
if (homePath == nullptr) {
throw std::runtime_error("homePath is null, please check env HOME");
}
baseDir = std::string(homePath);
filePath = std::string(homePath) + "/" + configLogPath;
}
if (filePath.length() > MAX_PATH_LENGTH) {
std::cout << "The path of log is too long: " << filePath << std::endl;
return false;
}
size_t lastSlash = filePath.rfind('/', filePath.size() - 1);
if (lastSlash == std::string::npos) {
std::cout << "The form of logPath is invalid: " << filePath << std::endl;
return false;
}
std::string parentPath = filePath.substr(0, lastSlash);
std::string errMsg;
MakeDirsWithTimeOut(parentPath);
FileValidationParams params1 = {true, MAX_LOG_DIR_PERM, MAX_ROTATION_FILE_SIZE_LIMIT, true};
if (!FileUtils::IsFileValid(parentPath.c_str(), errMsg, params1)) {
throw std::runtime_error(errMsg);
}
if (filePath.size() > PATH_MAX) {
std::cerr << "Error: Allowed maximum path length is " << PATH_MAX << ", but got " << filePath.size()
<< ". You can reduce log directory length.\n";
throw std::runtime_error(std::string("Log file path length exceeds PATH_MAX."));
}
baseDir_ = baseDir;
logFilePath_ = filePath;
return true;
}
}