yituo_video/src/logger.cpp
2025-09-08 14:55:07 +08:00

103 lines
2.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// logger.cpp
#include "logger.hpp"
#include <iomanip>
#include <ctime>
#include <fstream>
#include <cstdio>
std::ofstream Logger::log_file;
std::string Logger::current_log_filename;
void Logger::set_log_to_file(const std::string &filename)
{
current_log_filename = filename;
log_file.open(filename, std::ios::app);
if (!log_file.is_open())
{
std::cerr << "[Logger] Failed to open log file: " << filename << std::endl;
}
}
std::string Logger::get_time_string()
{
using namespace std::chrono;
// 获取当前时间点
auto now = system_clock::now();
auto ms = duration_cast<milliseconds>(now.time_since_epoch()) % 1000;
// 转换为 time_t
auto t = system_clock::to_time_t(now);
std::tm ltm = *std::localtime(&t);
// 拼接格式化字符串
std::ostringstream oss;
oss << std::put_time(&ltm, "%Y-%m-%d %H:%M:%S")
<< '.' << std::setw(3) << std::setfill('0') << ms.count();
return oss.str();
}
void Logger::log(LogLevel level, const std::string &msg)
{
std::string level_str;
switch (level)
{
case LogLevel::INFO:
level_str = "[INFO] ";
break;
case LogLevel::WARN:
level_str = "[WARN] ";
break;
case LogLevel::ERROR:
level_str = "[ERROR]";
break;
}
std::string full_msg = get_time_string() + " " + level_str + " " + msg;
std::cout << full_msg << std::endl;
if (log_file.is_open())
{
log_file << full_msg << std::endl;
log_file.flush();
// 检查是否需要轮转
if (get_file_size(current_log_filename) >= MAX_LOG_FILE_SIZE)
{
rotate_logs();
}
}
}
size_t Logger::get_file_size(const std::string &filename)
{
std::ifstream in(filename, std::ifstream::ate | std::ifstream::binary);
return in.is_open() ? static_cast<size_t>(in.tellg()) : 0;
}
void Logger::rotate_logs()
{
log_file.close();
// 删除最旧的日志
std::string oldest = current_log_filename + "." + std::to_string(MAX_LOG_BACKUP_COUNT);
std::remove(oldest.c_str());
// 重命名 *.4 -> *.5, ..., *.1 -> *.2
for (int i = MAX_LOG_BACKUP_COUNT - 1; i >= 1; --i)
{
std::string old_name = current_log_filename + "." + std::to_string(i);
std::string new_name = current_log_filename + "." + std::to_string(i + 1);
std::rename(old_name.c_str(), new_name.c_str());
}
// 当前日志 -> .1
std::string first_backup = current_log_filename + ".1";
std::rename(current_log_filename.c_str(), first_backup.c_str());
// 重新打开新日志
log_file.open(current_log_filename, std::ios::trunc);
}