-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLogger.h
More file actions
128 lines (106 loc) · 3.96 KB
/
Copy pathLogger.h
File metadata and controls
128 lines (106 loc) · 3.96 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
// logger.h - C++20 версия с удобным синтаксисом
#pragma once
#include <iostream>
#include <string>
#include <string_view>
#include <unordered_map>
#include <unordered_set>
#include <mutex>
#include <array>
#include <concepts>
namespace Color {
constexpr const char* RESET = "\033[0m";
constexpr const char* WHITE = "\033[37m";
constexpr const char* BRIGHT_RED = "\033[1;31m";
constexpr const char* BRIGHT_GREEN = "\033[1;32m";
constexpr const char* BRIGHT_YELLOW = "\033[1;33m";
constexpr const char* BRIGHT_BLUE = "\033[1;34m";
constexpr const char* BRIGHT_MAGENTA = "\033[1;35m";
constexpr const char* BRIGHT_CYAN = "\033[1;36m";
constexpr const char* BRIGHT_WHITE = "\033[1;37m";
}
class Logger {
public:
static Logger& instance() {
static Logger instance;
return instance;
}
void enableTag(std::string_view tag, bool enabled = true) {
std::lock_guard lock(_mutex);
if (enabled)
_disabledTags.erase(std::string(tag));
else
_disabledTags.insert(std::string(tag));
}
// Основной метод с variadic templates
template<typename... Tags>
void log(std::string_view message, Tags&&... tags) {
std::lock_guard lock(_mutex);
// Проверяем, все ли теги включены
if (((_disabledTags.count(std::forward<Tags>(tags)) > 0) || ...)) {
return;
}
// Выводим теги
(printTag(std::forward<Tags>(tags)), ...);
// Выводим сообщение
std::cout << Color::WHITE << message << Color::RESET << std::endl;
}
private:
void printTag(std::string_view tag) {
std::cout << getTagColor(tag) << "[" << tag << "]" << Color::RESET << " ";
}
const char* getTagColor(std::string_view tag) {
std::string tagStr(tag);
auto it = _tagColors.find(tagStr);
if (it != _tagColors.end())
return it->second;
const std::array<const char*, 7> colors = {
Color::BRIGHT_RED, Color::BRIGHT_GREEN, Color::BRIGHT_YELLOW,
Color::BRIGHT_BLUE, Color::BRIGHT_MAGENTA, Color::BRIGHT_CYAN,
Color::BRIGHT_WHITE
};
size_t hash = std::hash<std::string>{}(tagStr);
const char* color = colors[hash % colors.size()];
_tagColors[tagStr] = color;
return color;
}
void formatString(std::ostream& os, std::string_view format) {
os << format;
}
template<typename T, typename... Args>
void formatString(std::ostream& os, std::string_view format, T&& arg, Args&&... args) {
size_t pos = format.find("{}");
if (pos == std::string_view::npos) {
os << format;
return;
}
os << format.substr(0, pos) << arg;
formatString(os, format.substr(pos + 2), std::forward<Args>(args)...);
}
private:
std::mutex _mutex;
std::unordered_set<std::string> _disabledTags;
std::unordered_map<std::string, const char*> _tagColors;
};
// Удобный макрос для сокращения
#define LOG(...) Logger::instance().log(__VA_ARGS__)
// Пример использования:
/*
int main() {
auto& logger = Logger::instance();
// Самый простой и понятный синтаксис
logger.log("Сообщение 1", "Scrambler", "msg_processing");
logger.log("Сообщение 2", "Network", "TCP");
logger.log("Сообщение 3", "Scrambler");
// С макросом
LOG("Кратко", "Test");
// С форматированием
LOGF("Значение: {}", "Scrambler", 42);
LOGF("{} + {} = {}", "Math", 10, 20, 30);
// Отключение тегов
logger.enableTag("Scrambler", false);
LOG("Не выведется", "Scrambler");
LOG("Выведется", "Other");
return 0;
}
*/