日志结构优化
This commit is contained in:
parent
3cc40699b5
commit
ff56839334
@ -1,13 +1,14 @@
|
||||
// logger.hpp
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <ctime>
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
enum class LogLevel
|
||||
{
|
||||
@ -18,23 +19,23 @@ enum class LogLevel
|
||||
|
||||
class Logger
|
||||
{
|
||||
public:
|
||||
static void set_log_to_file(const std::string &filename);
|
||||
public:
|
||||
static void init(const std::string& log_dir);
|
||||
|
||||
static void log(LogLevel level, const std::string &msg);
|
||||
static void log(LogLevel level, const std::string& msg);
|
||||
|
||||
static std::string get_current_time_utc8();
|
||||
|
||||
private:
|
||||
private:
|
||||
static std::ofstream log_file;
|
||||
static std::string current_log_filename;
|
||||
static std::string log_directory;
|
||||
static std::string current_date;
|
||||
static std::string current_filename;
|
||||
|
||||
static std::string get_time_string();
|
||||
|
||||
static void rotate_logs();
|
||||
static size_t get_file_size(const std::string &filename);
|
||||
|
||||
static constexpr size_t MAX_LOG_FILE_SIZE = 10 * 1024 * 1024; // 10MB
|
||||
static constexpr int MAX_LOG_BACKUP_COUNT = 5;
|
||||
static std::string get_today_date();
|
||||
static void open_log_file();
|
||||
static void check_date_rollover();
|
||||
};
|
||||
|
||||
// 简化宏
|
||||
|
||||
103
src/logger.cpp
103
src/logger.cpp
@ -1,23 +1,41 @@
|
||||
// logger.cpp
|
||||
#include "logger.hpp"
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
std::ofstream Logger::log_file;
|
||||
std::string Logger::current_log_filename;
|
||||
std::string Logger::log_directory;
|
||||
std::string Logger::current_date;
|
||||
std::string Logger::current_filename;
|
||||
|
||||
void Logger::set_log_to_file(const std::string& filename)
|
||||
void Logger::init(const std::string& log_dir)
|
||||
{
|
||||
current_log_filename = filename;
|
||||
log_file.open(filename, std::ios::app);
|
||||
log_directory = log_dir;
|
||||
|
||||
if (!std::filesystem::exists(log_directory)) std::filesystem::create_directories(log_directory);
|
||||
|
||||
current_date = get_today_date();
|
||||
open_log_file();
|
||||
}
|
||||
|
||||
void Logger::open_log_file()
|
||||
{
|
||||
current_filename = log_directory + "/" + current_date + ".log";
|
||||
|
||||
if (log_file.is_open()) log_file.close();
|
||||
|
||||
log_file.open(current_filename, std::ios::app);
|
||||
|
||||
if (!log_file.is_open())
|
||||
{
|
||||
std::cerr << "[Logger] Failed to open log file: " << filename << std::endl;
|
||||
std::cerr << "[Logger] Failed to open log file: " << current_filename << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::check_date_rollover()
|
||||
{
|
||||
std::string today = get_today_date();
|
||||
if (today != current_date)
|
||||
{
|
||||
current_date = today;
|
||||
open_log_file();
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,29 +50,38 @@ std::string Logger::get_time_string()
|
||||
std::tm tm_now = *std::localtime(&t);
|
||||
|
||||
std::ostringstream ss;
|
||||
ss << std::put_time(&tm_now, "%Y-%m-%d %H:%M:%S") << '.' << std::setw(3) << std::setfill('0') << ms.count();
|
||||
ss << std::put_time(&tm_now, "%Y-%m-%d %H:%M:%S") << "." << std::setw(3) << std::setfill('0') << ms.count();
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string Logger::get_today_date()
|
||||
{
|
||||
auto now = std::chrono::system_clock::now();
|
||||
std::time_t t = std::chrono::system_clock::to_time_t(now);
|
||||
std::tm tm_now = *std::localtime(&t);
|
||||
|
||||
std::ostringstream ss;
|
||||
ss << std::put_time(&tm_now, "%Y-%m-%d");
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string Logger::get_current_time_utc8()
|
||||
{
|
||||
using namespace std::chrono;
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;
|
||||
|
||||
auto now = system_clock::now();
|
||||
auto ms = duration_cast<milliseconds>(now.time_since_epoch()) % 1000;
|
||||
|
||||
std::time_t t = system_clock::to_time_t(now);
|
||||
std::time_t t = std::chrono::system_clock::to_time_t(now);
|
||||
std::tm tm_now = *std::localtime(&t);
|
||||
|
||||
std::ostringstream ss;
|
||||
ss << std::put_time(&tm_now, "%Y%m%d%H%M%S") << std::setw(3) << std::setfill('0') << ms.count();
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
void Logger::log(LogLevel level, const std::string& msg)
|
||||
{
|
||||
check_date_rollover();
|
||||
|
||||
std::string level_str;
|
||||
switch (level)
|
||||
{
|
||||
@ -77,41 +104,5 @@ void Logger::log(LogLevel level, const std::string& msg)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ int main()
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
// ---------- 初始化日志 ----------
|
||||
Logger::set_log_to_file(get_executable_dir_file_path("app.log"));
|
||||
Logger::init(get_executable_dir_file_path("logs"));
|
||||
LOG_INFO("[MAIN] ===== Vehicle Video Service Starting =====");
|
||||
|
||||
try
|
||||
@ -41,7 +41,7 @@ int main()
|
||||
g_app_config = AppConfig::load_from_file(get_executable_dir_file_path("config.json"));
|
||||
LOG_INFO("[MAIN] Loaded config from config.json");
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
LOG_ERROR(std::string("[MAIN] Failed to load config: ") + e.what());
|
||||
return -1;
|
||||
@ -63,7 +63,7 @@ int main()
|
||||
LOG_INFO("[MAIN] MQTT thread started.");
|
||||
mqtt_client_thread_func(); // 在回调里执行推流控制
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
LOG_ERROR(std::string("[MAIN] MQTT thread crashed: ") + e.what());
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user