// Logger.cpp - 日志实现 #include "pch.h" #include "Logger.h" #include #include #include namespace commkit { Logger::Logger() {} Logger::~Logger() {} Logger& Logger::Instance() { static Logger instance; return instance; } void Logger::SetLevel(Level level) { level_ = level; } void Logger::EnableFileOutput(bool enable) { std::lock_guard lock(file_mutex_); file_output_enabled_ = enable; } std::wstring Logger::StringToWString(const std::string& str) const { if (str.empty()) return L""; int len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, nullptr, 0); if (len <= 0) return L""; std::wstring wstr(len - 1, L'\0'); MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, &wstr[0], len); return wstr; } std::wstring Logger::FormatLine(Level level, const std::string& message) { // 获取当前本地时间 auto now = std::time(nullptr); struct tm tm_buf; localtime_s(&tm_buf, &now); // 格式化时间戳 std::wostringstream woss; woss << L"[" << std::put_time(&tm_buf, L"%Y-%m-%d %H:%M:%S") << L"]"; // 级别标记 const wchar_t* level_str = L"?"; switch (level) { case Level::Debug: level_str = L"DBG"; break; case Level::Info: level_str = L"INF"; break; case Level::Warning: level_str = L"WRN"; break; case Level::Error: level_str = L"ERR"; break; } woss << L"[" << level_str << L"] "; // 消息体 woss << StringToWString(message); return woss.str(); } void Logger::WriteToFile(const std::wstring& line) { // 日志文件路径:%TEMP%\CommModifyKit.log wchar_t temp_path[MAX_PATH] = {0}; if (GetTempPathW(MAX_PATH, temp_path) == 0) return; std::wstring file_path = std::wstring(temp_path) + L"CommModifyKit.log"; // 追加模式打开 HANDLE hFile = CreateFileW(file_path.c_str(), FILE_APPEND_DATA, FILE_SHARE_READ, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); if (hFile == INVALID_HANDLE_VALUE) return; // 写入一行 + 换行 std::wstring line_with_eol = line + L"\r\n"; DWORD written = 0; WriteFile(hFile, line_with_eol.c_str(), static_cast(line_with_eol.size() * sizeof(wchar_t)), &written, nullptr); CloseHandle(hFile); } void Logger::Log(Level level, const std::string& message) { // 级别过滤 if (static_cast(level) < static_cast(level_)) { return; } // 格式化日志行 std::wstring line = FormatLine(level, message); // 输出到调试器(DebugView 等) OutputDebugStringW(line.c_str()); OutputDebugStringW(L"\r\n"); // 可选:写入文件 { std::lock_guard lock(file_mutex_); if (file_output_enabled_) { WriteToFile(line); } } } } // namespace commkit