kunlang_video/src/logger.cpp

124 lines
3.2 KiB
C++
Raw Normal View History

2025-09-08 14:55:07 +08:00
// logger.cpp
2025-09-08 10:59:08 +08:00
#include "logger.hpp"
2025-11-13 13:55:55 +08:00
2025-11-13 14:06:52 +08:00
#include <chrono>
2025-11-13 13:55:55 +08:00
#include <cstdio>
2025-09-08 10:59:08 +08:00
#include <ctime>
#include <fstream>
2025-11-13 13:55:55 +08:00
#include <iomanip>
2025-11-13 14:09:31 +08:00
#include <sstream>
2025-09-08 10:59:08 +08:00
std::ofstream Logger::log_file;
std::string Logger::current_log_filename;
2025-11-13 13:55:55 +08:00
void Logger::set_log_to_file(const std::string& filename)
2025-09-08 10:59:08 +08:00
{
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()
{
2025-11-13 14:06:52 +08:00
using namespace std::chrono;
auto now = system_clock::now();
2025-11-13 14:09:31 +08:00
zoned_time zt{current_zone(), now};
auto local = zt.get_local_time();
auto ms = duration_cast<milliseconds>(local.time_since_epoch()) % 1000;
2025-11-13 13:55:55 +08:00
2025-11-13 14:09:31 +08:00
std::time_t t = system_clock::to_time_t(now);
std::tm tm_now = *std::localtime(&t);
2025-09-08 10:59:08 +08:00
2025-09-09 14:21:24 +08:00
std::ostringstream ss;
2025-11-13 14:09:31 +08:00
ss << std::put_time(&tm_now, "%Y-%m-%d %H:%M:%S") << '.' << std::setw(3) << std::setfill('0') << ms.count();
2025-11-13 13:55:55 +08:00
2025-09-09 14:21:24 +08:00
return ss.str();
2025-09-08 10:59:08 +08:00
}
2025-09-09 14:16:18 +08:00
std::string Logger::get_current_time_utc8()
{
using namespace std::chrono;
auto now = system_clock::now();
2025-11-13 14:06:52 +08:00
zoned_time zt{current_zone(), now};
2025-09-09 14:16:18 +08:00
2025-11-13 14:09:31 +08:00
auto local = zt.get_local_time();
auto ms = duration_cast<milliseconds>(local.time_since_epoch()) % 1000;
std::time_t t = system_clock::to_time_t(now);
std::tm tm_now = *std::localtime(&t);
2025-09-09 14:16:18 +08:00
std::ostringstream ss;
2025-11-13 14:09:31 +08:00
ss << std::put_time(&tm_now, "%Y%m%d%H%M%S") << std::setw(3) << std::setfill('0') << ms.count();
2025-09-09 14:16:18 +08:00
return ss.str();
}
2025-11-13 13:55:55 +08:00
void Logger::log(LogLevel level, const std::string& msg)
2025-09-08 10:59:08 +08:00
{
std::string level_str;
switch (level)
{
2025-11-13 13:55:55 +08:00
case LogLevel::INFO:
level_str = "[INFO] ";
break;
case LogLevel::WARN:
level_str = "[WARN] ";
break;
case LogLevel::ERROR:
level_str = "[ERROR]";
break;
2025-09-08 10:59:08 +08:00
}
2025-09-09 14:21:24 +08:00
std::string full_msg = get_time_string() + " " + level_str + " " + msg;
2025-09-08 10:59:08 +08:00
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();
}
}
}
2025-11-13 13:55:55 +08:00
size_t Logger::get_file_size(const std::string& filename)
2025-09-08 10:59:08 +08:00
{
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);
}