-
Notifications
You must be signed in to change notification settings - Fork 0
/
logger.hpp
145 lines (118 loc) · 4.12 KB
/
logger.hpp
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#ifndef _LOGGER_HPP
#define _LOGGER_HPP
#include <boost/thread.hpp>
#include <cerrno>
#include <cstring>
#include <ctime>
#include <fstream>
#include <iostream>
#include <ostream>
#include <regex>
#include <string>
#include <type_traits>
#include <unordered_map>
#ifndef TIMEBUF_SIZE
#define TIMEBUF_SIZE 128
#else
#define TIMEBUF_SIZE_DEFINED
#endif
enum class LogLevel : unsigned int {
Error = 0b1,
Warning = 0b10,
Info = 0b100,
Debug = 0b1000,
};
inline LogLevel operator|(LogLevel lhs, LogLevel rhs) {
return static_cast<LogLevel>(
static_cast<std::underlying_type<LogLevel>::type>(lhs) |
static_cast<std::underlying_type<LogLevel>::type>(rhs));
}
inline LogLevel operator&(LogLevel lhs, LogLevel rhs) {
return static_cast<LogLevel>(
static_cast<std::underlying_type<LogLevel>::type>(lhs) &
static_cast<std::underlying_type<LogLevel>::type>(rhs));
}
inline LogLevel operator^(LogLevel lhs, LogLevel rhs) {
return static_cast<LogLevel>(
static_cast<std::underlying_type<LogLevel>::type>(lhs) ^
static_cast<std::underlying_type<LogLevel>::type>(rhs));
}
inline LogLevel operator~(LogLevel rhs) {
return static_cast<LogLevel>(
~static_cast<std::underlying_type<LogLevel>::type>(rhs));
}
inline LogLevel& operator|=(LogLevel& lhs, LogLevel rhs) {
lhs = static_cast<LogLevel>(
static_cast<std::underlying_type<LogLevel>::type>(lhs) |
static_cast<std::underlying_type<LogLevel>::type>(rhs));
return lhs;
}
inline LogLevel& operator&=(LogLevel& lhs, LogLevel rhs) {
lhs = static_cast<LogLevel>(
static_cast<std::underlying_type<LogLevel>::type>(lhs) &
static_cast<std::underlying_type<LogLevel>::type>(rhs));
return lhs;
}
inline LogLevel& operator^=(LogLevel& lhs, LogLevel rhs) {
lhs = static_cast<LogLevel>(
static_cast<std::underlying_type<LogLevel>::type>(lhs) ^
static_cast<std::underlying_type<LogLevel>::type>(rhs));
return lhs;
}
class Logger {
private:
boost::mutex mutex;
static std::string filter(const std::string& str) {
const static std::regex ansi_escape_code_re(R"(\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~]))");
return std::regex_replace(str, ansi_escape_code_re, {});
}
void log(std::string message, bool filter_message = false) {
if (filter_message) message = filter(message);
time_t rawtime;
struct tm* timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime);
char timef[TIMEBUF_SIZE];
strftime(timef, TIMEBUF_SIZE, "%c", timeinfo);
boost::unique_lock<boost::mutex> lock(this->mutex);
std::ofstream logfile(this->logfile_name, std::ios::app);
if (logfile.is_open()) {
logfile << "[" << timef << "] " << message << std::endl;
logfile.close();
} else {
std::cerr << "Logging error: " << strerror(errno) << std::endl;
}
}
public:
std::string logfile_name;
LogLevel log_level;
Logger(const std::string& logfile_name, LogLevel log_level = LogLevel::Error | LogLevel::Warning | LogLevel::Info | LogLevel::Debug):
logfile_name(logfile_name),
log_level(log_level) {}
inline void error(const std::string& message, bool filter_message = false) {
if (static_cast<bool>(log_level & LogLevel::Error)) {
log("Error: " + message, filter_message);
}
}
inline void warn(const std::string& message, bool filter_message = false) {
if (static_cast<bool>(log_level & LogLevel::Warning)) {
log("Warning: " + message, filter_message);
}
}
inline void info(const std::string& message, bool filter_message = false) {
if (static_cast<bool>(log_level & LogLevel::Info)) {
log("Info: " + message, filter_message);
}
}
inline void debug(const std::string& message, bool filter_message = false) {
if (static_cast<bool>(log_level & LogLevel::Debug)) {
log("Debug: " + message, filter_message);
}
}
};
#ifndef TIMEBUF_SIZE_DEFINED
#undef TIMEBUF_SIZE
#else
#undef TIMEBUF_SIZE_DEFINED
#endif
#endif