有时候写了一个非常简单的小工具,想要记录日志测试,甚至都不想添加一个头文件,这个时候希望有个非常简单的日志记录类,能够直接复制粘贴就能使用,不用考虑线程问题等复杂场景,于是就有了下面这个类,亲测可用。

支持输入日志到终端或者文件。

#include <iostream>
#include <fstream>
#include <chrono>
#include <ctime>
#include <string>

class Logger {
public:

    static std::string getLogFilename() {
        auto now = std::chrono::system_clock::now();
        std::time_t current_time = std::chrono::system_clock::to_time_t(now);
        std::tm local_time{};

        if (localtime_s(&local_time, &current_time) != 0) {
            return "default.log";
        }

        char time_str[100];
        std::strftime(time_str, sizeof(time_str), "%Y%m%d_%H%M%S", &local_time);
        return std::string(time_str) + ".log";
    }

    static std::wstring getLogFilenameW() {
        auto now = std::chrono::system_clock::now();
        std::time_t current_time = std::chrono::system_clock::to_time_t(now);
        std::tm local_time{};

        if (localtime_s(&local_time, &current_time) != 0) {
            return L"default.log";
        }

        wchar_t time_str[100];
        std::wcsftime(time_str, sizeof(time_str) / sizeof(wchar_t), L"%Y%m%d_%H%M%S", &local_time);
        return std::wstring(time_str) + L".log";
    }

    static void log(const std::string& message, const std::string& filename = "") {
        // 获取当前时间
        auto now = std::chrono::system_clock::now();
        std::time_t current_time = std::chrono::system_clock::to_time_t(now);
        std::tm local_time{};

        // 使用安全的localtime_s替代localtime
        if (localtime_s(&local_time, &current_time) != 0) {
            std::cerr << "获取本地时间失败" << std::endl;
            return;
        }

        // 格式化时间字符串
        char time_str[100];
        std::strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", &local_time);

        // 构造完整日志信息
        std::string log_entry = "[" + std::string(time_str) + "] " + message + "\n";

        if (filename.empty()) {
            // 输出到控制台
            std::cout << log_entry;
        }
        else {
            // 追加模式写入文件
            std::ofstream log_file(filename, std::ios::app);
            if (log_file.is_open()) {
                log_file << log_entry;
            }
            else {
                std::cerr << "无法打开日志文件: " << filename << std::endl;
            }
        }
    }

    static void log(const std::wstring& message, const std::string& filename = "") {
        // 设置本地化环境
        std::locale::global(std::locale(""));

        // 获取当前时间
        auto now = std::chrono::system_clock::now();
        std::time_t current_time = std::chrono::system_clock::to_time_t(now);
        std::tm local_time{};

        // 使用安全的localtime_s替代localtime
        if (localtime_s(&local_time, &current_time) != 0) {
            std::cerr << "获取本地时间失败" << std::endl;
            return;
        }

        // 转换宽字符消息
        const wchar_t* wstr = message.c_str();
        size_t buffer_size = 0;

        // 使用安全的wcstombs_s替代wcstombs
        if (wcstombs_s(&buffer_size, nullptr, 0, wstr, 0) != 0)
        {
            std::cerr << "宽字符转换失败" << std::endl;
            return;
        }

        std::string narrow_msg(buffer_size, 0);
        if (wcstombs_s(&buffer_size, &narrow_msg[0], buffer_size, wstr, _TRUNCATE) != 0)
        {
            std::cerr << "宽字符转换失败" << std::endl;
            return;
        }
        narrow_msg.resize(buffer_size - 1); // 去除末尾的null字符

        // 格式化时间字符串
        char time_str[100];
        std::strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", &local_time);

        // 构造完整日志信息
        std::string log_entry = "[" + std::string(time_str) + "] " + narrow_msg + "\n";

        if (filename.empty()) {
            // 输出到控制台
            std::cout << log_entry;
        }
        else {
            // 追加模式写入文件
            std::ofstream log_file(filename, std::ios::app);
            if (log_file.is_open()) {
                log_file << log_entry;
            }
            else {
                std::wcerr << L"无法打开日志文件: " << filename.c_str() << std::endl;
            }
        }
    }
};

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐