* This file is part of the MindStudio project.
* Copyright (c) 2025 Huawei Technologies Co.,Ltd.
*
* MindStudio 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 CORE_FRAMEWORK_LOG_H
#define CORE_FRAMEWORK_LOG_H
#include <mutex>
#include <string>
#include <cstdio>
#include <cstdint>
#include <thread>
#include <unistd.h>
#include <sstream>
#include "securec.h"
namespace Sanitizer {
enum class LogLv : uint8_t {
DEBUG = 0U,
INFO,
WARN,
ERROR,
};
inline bool operator<(const LogLv &a, const LogLv &b)
{
return static_cast<uint8_t>(a) < static_cast<uint8_t>(b);
}
constexpr int64_t MAX_LOG_FILE_SIZE = 1024L * 1024L;
constexpr long MAX_LOG_FILE_NUMBER = 10L;
constexpr int16_t LOG_BUF_SIZE = 4096;
constexpr uint64_t MAX_PIPE_OUTPUT_SIZE = 1UL << 33;
constexpr uint16_t MAX_FILE_PATH_LEN = 4096U;
constexpr size_t MAX_TIMESTAMP_LENGTH = 256U;
constexpr const char* OUTPUT_DIR = "./mindstudio_sanitizer_log";
class Log {
public:
static Log *GetLog();
void AppendBuff(const std::string &text);
FILE *GetLogFp(void)
{
std::lock_guard<std::mutex> guard(mtx_);
if (LogSize() >= MAX_LOG_FILE_SIZE * maxDebugLogSizeRate_) {
RotateLogFile();
}
std::lock_guard<std::mutex> buffGuard(sbuffMtx_);
if (!sLogBuff_.empty() && fp_) {
fprintf(fp_, "%s", sLogBuff_.c_str());
sLogBuff_.clear();
}
return fp_;
}
std::string GetTimeStamp(void) const;
std::string GetRunningTime(void) const;
void SetMaxDebugLogSizeRate(long rate);
private:
Log();
~Log();
Log(Log &) = delete;
Log(const Log &) = delete;
Log &operator=(Log &) = delete;
Log &operator=(const Log &) = delete;
FILE* OpenLogFile(const std::string &path);
void RotateLogFile();
int64_t LogSize() const;
FILE *fp_ { nullptr };
std::string logFilePath_;
long rotateCount_ = 1;
mutable std::mutex mtx_{};
std::string sLogBuff_;
std::mutex sbuffMtx_;
long maxDebugLogSizeRate_;
};
}
#define SAN_LOG(format, ...) \
do { \
Sanitizer::Log &log = *Sanitizer::Log::GetLog(); \
FILE *fp = log.GetLogFp(); \
if (fp != nullptr) { \
fprintf(fp, format "\n", ##__VA_ARGS__); \
fflush(fp); \
} \
} while (0)
#define SAN_ERROR_LOG(format, ...) SAN_LOG("[E] " format, ##__VA_ARGS__)
#define SAN_WARN_LOG(format, ...) SAN_LOG("[W] " format, ##__VA_ARGS__)
#define SAN_INFO_LOG(format, ...) SAN_LOG("[I] " format, ##__VA_ARGS__)
#define SAN_BUFF_LOG(format, ...) \
{ \
char buf[LOG_BUF_SIZE]{0}; \
int ret = sprintf_s(buf, LOG_BUF_SIZE, format "\n", ##__VA_ARGS__); \
if (ret != -1) { \
Sanitizer::Log::GetLog()->AppendBuff(buf); \
} \
}
#define SAN_BUFF_ERROR_LOG(format, ...) SAN_BUFF_LOG("[E] " format, ##__VA_ARGS__)
#define SAN_BUFF_WARN_LOG(format, ...) SAN_BUFF_LOG("[W] " format, ##__VA_ARGS__)
#define SAN_BUFF_INFO_LOG(format, ...) SAN_BUFF_LOG("[I] " format, ##__VA_ARGS__)
#endif