-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlogger.cpp
More file actions
130 lines (111 loc) · 3.81 KB
/
logger.cpp
File metadata and controls
130 lines (111 loc) · 3.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include "logger.h"
#include <Windows.h>
#include <iostream>
#include <chrono>
#include <iomanip>
#include <sstream>
#include <io.h>
#include <fcntl.h>
Logger& Logger::instance() {
static Logger instance;
return instance;
}
Logger::~Logger() {
shutdown();
}
void Logger::init(const std::wstring& logFilePath) {
std::lock_guard<std::mutex> lock(m_mutex);
if (m_initialized) return;
// Get console handle
m_consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
// Enable ANSI escape codes for Windows console
DWORD dwMode = 0;
GetConsoleMode(m_consoleHandle, &dwMode);
SetConsoleMode(m_consoleHandle, dwMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
m_logFile.open(logFilePath, std::ios::out | std::ios::app);
m_initialized = true;
}
void Logger::shutdown() {
std::lock_guard<std::mutex> lock(m_mutex);
if (m_logFile.is_open()) {
m_logFile.close();
}
m_initialized = false;
}
std::wstring Logger::getTimestamp() {
auto now = std::chrono::system_clock::now();
auto time = std::chrono::system_clock::to_time_t(now);
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch()) % 1000;
std::tm localTime;
localtime_s(&localTime, &time);
std::wostringstream oss;
oss << std::put_time(&localTime, L"%Y-%m-%d %H:%M:%S")
<< L"." << std::setfill(L'0') << std::setw(3) << ms.count();
return oss.str();
}
std::wstring Logger::getLevelPrefix(LogLevel level) {
switch (level) {
case LogLevel::INFO: return L"INFO ";
case LogLevel::USB_DEVICE: return L"USB ";
case LogLevel::AUDIO_DEVICE: return L"AUDIO ";
case LogLevel::USB_CONNECTED: return L"+++ USB CONNECTED ";
case LogLevel::USB_DISCONNECTED:return L"!!! USB DISCONNECTED ";
case LogLevel::AUDIO_CHANGE: return L"*** AUDIO CHANGE ";
case LogLevel::SECTION: return L"";
case LogLevel::WARNING: return L"WARN ";
case LogLevel::ERROR_LOG: return L"ERROR ";
default: return L" ";
}
}
void Logger::writeToConsole(const std::wstring& text) {
if (m_consoleHandle) {
DWORD written = 0;
WriteConsoleW(m_consoleHandle, text.c_str(), static_cast<DWORD>(text.length()), &written, nullptr);
}
}
void Logger::setConsoleColor(LogLevel level) {
switch (level) {
case LogLevel::USB_CONNECTED:
writeToConsole(L"\033[92m"); // Bright green
break;
case LogLevel::USB_DISCONNECTED:
writeToConsole(L"\033[91m"); // Bright red
break;
case LogLevel::AUDIO_CHANGE:
writeToConsole(L"\033[93m"); // Bright yellow
break;
case LogLevel::SECTION:
writeToConsole(L"\033[96m"); // Bright cyan
break;
case LogLevel::WARNING:
writeToConsole(L"\033[33m"); // Yellow
break;
case LogLevel::ERROR_LOG:
writeToConsole(L"\033[31m"); // Red
break;
default:
break;
}
}
void Logger::resetConsoleColor() {
writeToConsole(L"\033[0m");
}
void Logger::log(LogLevel level, const std::wstring& message) {
std::lock_guard<std::mutex> lock(m_mutex);
std::wstring timestamp = getTimestamp();
std::wstring prefix = getLevelPrefix(level);
std::wstring fullMessage = L"[" + timestamp + L"] " + prefix + message + L"\n";
// Console output with color using WriteConsoleW
setConsoleColor(level);
writeToConsole(fullMessage);
resetConsoleColor();
// File output (no color codes)
if (m_logFile.is_open()) {
m_logFile << fullMessage;
m_logFile.flush();
}
}
void Logger::logSection(const std::wstring& title) {
log(LogLevel::SECTION, L"=== " + title + L" ===");
}