-
Notifications
You must be signed in to change notification settings - Fork 4
/
log.h
220 lines (192 loc) · 7.69 KB
/
log.h
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
/**
* @file log.h
* @author Kunal Tyagi
* @brief Provides simple logging features, fast, and robust
* @copyright see LICENSE
*/
#ifndef _LOG_LOG_H_
#define _LOG_LOG_H_
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <cassert>
#include <cstdlib>
#include <iostream>
#include <iomanip>
#define __CHECK_FOR_COLOR__ false
#define __COLOR__ true
#define TEXT_FINE_DEBUG 0
enum CsiCode
{
// general attributes
ATTR_RESET = 0,
ATTR_TEXT_BOLD = 1,
ATTR_UNDERLINE = 4,
ATTR_BLINK = 5,
ATTR_REVERSE = 7,
ATTR_NO_UNDERLINE = 24,
ATTR_NO_BLINK = 25,
ATTR_NO_REVERSE = 27,
// foreground color
FG_BLACK = 30,
FG_RED = 31,
FG_GREEN = 32,
FG_YELLOW = 33,
FG_BLUE = 34,
FG_MAGENTA = 35,
FG_CYAN = 36,
FG_WHITE = 37,
FG_DEFAULT = 39,
// background color
BG_BLACK = 40,
BG_RED = 41,
BG_GREEN = 42,
BG_YELLOW = 43,
BG_BLUE = 44,
BG_MAGENTA = 45,
BG_CYAN = 46,
BG_WHITE = 47,
BG_DEFAULT = 49,
// decoration
DEC_FRAMED = 51,
DEC_ENCIRCLED = 52,
DEC_OVERLINED = 53,
DEC_NO_FRAMED = 54,
DEC_NO_ENCIRCLED = 54,
DEC_NO_OVERLINED = 55
};
int colorMap[5] = { FG_GREEN, FG_DEFAULT, FG_YELLOW, FG_RED, FG_RED };
int attributeMap[5] = { ATTR_RESET, ATTR_RESET, ATTR_RESET, ATTR_RESET, ATTR_TEXT_BOLD };
inline bool colorEnabled(bool color = __COLOR__)
{
#if __CHECK_FOR_COLOR__
char *term = getenv("TERM");
int erret = 0;
if (setupterm(NULL, 1, &erret) == ERR)
{
return false;
}
return has_colors();
#else
return color;
#endif
}
/**
* I use it for the following folder structure
* /home/username/workspace/-|
* |-src/project_name/auv_<package>/-|
* | |-src/*
* | |-include/*
* |-build/
*/
inline std::string getNormalHeader(std::string fullNamePath, int length = 4)
{
assert(length > -1);
std::vector<std::string> path;
std::stringstream stream;
stream << fullNamePath;
std::string str;
while (getline(stream, str, '/'))
{
path.push_back(str);
}
str = "";
std::vector<std::string> prefix, postfix;
prefix.push_back("<");
prefix.push_back("(");
prefix.push_back("[");
postfix.push_back(">");
postfix.push_back(")");
postfix.push_back("]");
for (int i = length; i != 0; --i)
{
if ("src" == path[path.size() - i] || "include" == path[path.size() - i])
{
continue;
}
if (path[path.size() - i].find("auv") != std::string::npos)
{
path[path.size() - i] = path[path.size() - i].substr(4, int(path[path.size() - i].size() - 4));
}
str += prefix.back() + path[path.size() - i] + postfix.back();
prefix.pop_back();
postfix.pop_back();
std::transform(str.begin(), str.end(),str.begin(), ::toupper);
}
return str;
}
inline std::string getDebugHeader(std::string filepath, std::string function, int line)
{
return getNormalHeader(filepath) + " {Function: " + function +
"() Line: " + std::to_string(line) + "}";
}
inline std::string getHeader(std::string filepath, std::string function, int line, int fineDebug = -1)
{
fineDebug = fineDebug == -1 ? TEXT_FINE_DEBUG : fineDebug;
return (fineDebug != 0) ? getDebugHeader(filepath, function, line) : getNormalHeader(filepath);
}
char *itoa (int value, char *result, int base = 10)
{
// check that the base if valid
if (base < 2 || base > 36) { *result = '\0'; return result; }
char* ptr = result, *ptr1 = result, tmp_char;
int tmp_value;
do {
tmp_value = value;
value /= base;
*ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
} while ( value );
// Apply negative sign
if (tmp_value < 0) *ptr++ = '-';
*ptr-- = '\0';
while (ptr1 < ptr) {
tmp_char = *ptr;
*ptr--= *ptr1;
*ptr1++ = tmp_char;
}
return result;
}
#define __DEBUG__ 0
#define __INFO__ 1
#define __WARN__ 2
#define __ERROR__ 3
#define __FATAL__ 4
#define __SECURE__(X) do { X; } while(false)
#define MACRO_NAME(X) #X
#define MACRO_VALUE(X) X
#define SECONDS() (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count())
#define NANO_SECONDS() (std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count()%1000000000)
#define __CSI_SINGLE_CODE__(X) __SECURE__(printf("\033[%dm", X))
#define __CSI_SINGLE_CODE_STREAM__(X) __SECURE__(std::cout << "\033[" << X << "m")
#define __CSI_CODE__(X, format, ...) __SECURE__(printf("\033[%dm" format "\033[%dm\n", X, ##__VA_ARGS__, ATTR_RESET))
#define __CSI_CODE_STREAM__(X, args) __SECURE__(std::cout << "\033[" << X << "m" << args << "\033[" << ATTR_RESET << "m" << std::endl)
#define LOG(LEVEL, VERBOSE, format, ...) __SECURE__(__CSI_SINGLE_CODE__(attributeMap[__##LEVEL##__]); __CSI_CODE__(colorMap[__##LEVEL##__], "[%5s ] [%11lu:%9lu] %s " format, #LEVEL, SECONDS(), NANO_SECONDS(), getHeader(__BASE_FILE__, __FUNCTION__, __LINE__, VERBOSE).c_str(), ##__VA_ARGS__))
#define LOG_STREAM(LEVEL, VERBOSE, args) __SECURE__(__CSI_SINGLE_CODE_STREAM__(attributeMap[__##LEVEL##__]); __CSI_CODE_STREAM__(colorMap[__##LEVEL##__], "[" << std::setw(5) << #LEVEL << " ] [" << std::setw(11) << SECONDS() << ":" << std::setw(9) << NANO_SECONDS() << "] " << getHeader(__BASE_FILE__, __FUNCTION__, __LINE__, VERBOSE) << " " << args))
#define LOG_DEBUG(format, ...) __SECURE__(LOG(DEBUG, 0, format, ##__VA_ARGS__))
#define LOG_INFO(format, ...) __SECURE__(LOG(INFO, 0, format, ##__VA_ARGS__))
#define LOG_WARN(format, ...) __SECURE__(LOG(WARN, 0, format, ##__VA_ARGS__))
#define LOG_ERROR(format, ...) __SECURE__(LOG(ERROR, 0, format, ##__VA_ARGS__))
#define LOG_FATAL(format, ...) __SECURE__(LOG(FATAL, 0, format, ##__VA_ARGS__))
#define LOG_DEBUG_STREAM(args) __SECURE__(LOG_STREAM(DEBUG, 0, args))
#define LOG_INFO_STREAM(args) __SECURE__(LOG_STREAM(INFO, 0, args))
#define LOG_WARN_STREAM(args) __SECURE__(LOG_STREAM(WARN, 0, args))
#define LOG_ERROR_STREAM(args) __SECURE__(LOG_STREAM(ERROR, 0, args))
#define LOG_FATAL_STREAM(args) __SECURE__(LOG_STREAM(FATAL, 0, args))
#define LOG_DEBUG_FINE(format, ...) __SECURE__(LOG(DEBUG, 1, format, ##__VA_ARGS__))
#define LOG_INFO_FINE(format, ...) __SECURE__(LOG(INFO, 1, format, ##__VA_ARGS__))
#define LOG_WARN_FINE(format, ...) __SECURE__(LOG(WARN, 1, format, ##__VA_ARGS__))
#define LOG_ERROR_FINE(format, ...) __SECURE__(LOG(ERROR, 1, format, ##__VA_ARGS__))
#define LOG_FATAL_FINE(format, ...) __SECURE__(LOG(FATAL, 1, format, ##__VA_ARGS__))
#define LOG_DEBUG_STREAM_FINE(args) __SECURE__(LOG_STREAM(DEBUG, 1, args))
#define LOG_INFO_STREAM_FINE(args) __SECURE__(LOG_STREAM(INFO, 1, args))
#define LOG_WARN_STREAM_FINE(args) __SECURE__(LOG_STREAM(WARN, 1, args))
#define LOG_ERROR_STREAM_FINE(args) __SECURE__(LOG_STREAM(ERROR, 1, args))
#define LOG_FATAL_STREAM_FINE(args) __SECURE__(LOG_STREAM(FATAL, 1, args))
//#define LOG_ONCE(LEVEL, format, ...)
//#define LOG_STREAM_ONCE(LEVEL, format, ...)
#define LOG_COND(LEVEL, cond, format, ...) __SECURE__(if(cond) LOG(LEVEL, 0, format, ##__VA_ARGS__))
#define LOG_STREAM_COND(LEVEL, cond, args) __SECURE__(if(cond) LOG_STREAM(LEVEL, 0, args))
#define LOG_COND_FINE(LEVEL, cond, format, ...) __SECURE__(if(cond) LOG(LEVEL, 1, format, ##__VA_ARGS__))
#define LOG_STREAM_COND_FINE(LEVEL, cond, args) __SECURE__(if(cond) LOG_STREAM(LEVEL, 1, args))
#endif // _LOG_LOG_H_