-
Notifications
You must be signed in to change notification settings - Fork 1
/
log.h
153 lines (131 loc) · 3.7 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
#ifndef __LOGGER_H__
#define __LOGGER_H__
#include <iostream>
#include <fstream>
#include <sstream>
#include <ostream>
#include <time.h>
namespace LOGGER
{
enum class Severity
{
ERROR,
WARNNING,
DEBUG,
VERBOSE,
INFO,
};
enum class FileMode
{
OVERWRITE,
APPEND,
};
static const std::string SeverityStr[] = {"error", "warn", "debug", "verbose", "info"};
// out stream object
struct Logger
{
static std::ofstream fout;
static Severity level_basic;
static FileMode mode;
std::ostringstream stream;
Severity level;
std::string filename;
std::string function;
int line;
public:
~Logger() { fout.close(); }
Logger() : level(Severity::INFO) {}
Logger(Severity l) : level(l) {}
static const std::string &get_time()
{
static std::string timenow;
time_t rawtime;
struct tm *info;
static char buffer[80];
time(&rawtime);
info = localtime(&rawtime);
strftime(buffer, 80, "%Y-%m-%d %H:%M:%S", info);
timenow = buffer;
return timenow;
}
static void Init(const std::string &lf)
{
if (mode == FileMode::APPEND)
fout.open(lf, std::ios::app);
if (mode == FileMode::OVERWRITE)
fout.open(lf, std::ios::trunc);
fout << "\r\n\r\nnew log start from here, at " << get_time() << std::endl;
}
static void Init(const std::string &lf, FileMode m)
{
mode = m;
Init(lf);
}
static void Init(Severity l, const std::string &lf, FileMode m)
{
level_basic = l;
Init(lf, m);
}
Logger &operator()(Severity l, const std::string &fl, const std::string &func, int ln)
{
level = l;
filename = fl;
function = func;
line = ln;
return *this;
}
Logger &operator()(Severity l)
{
level = l;
return *this;
}
Logger &operator<<(const char *value)
{
stream << value;
return *this;
}
template <typename T>
Logger &operator<<(const T &value)
{
stream << value;
return *this;
}
Logger &operator<<(std::ostream &(*os)(std::ostream &))
{
if (static_cast<int>(level_basic) >= static_cast<int>(level))
{
if (filename.empty())
std::cerr << "[" << get_time() << "] " << SeverityStr[static_cast<int>(level)] << ": " << stream.str() << os;
else
std::cerr << "[" << get_time() << " " << filename << ":" << line << " " << function << "] "
<< SeverityStr[static_cast<int>(level)] << ": " << stream.str() << os;
}
if (filename.empty())
fout << "[" << get_time() << "] " << SeverityStr[static_cast<int>(level)] << ": " << stream.str() << os;
else
fout << "[" << get_time() << " " << filename << ":" << line << " " << function << "] "
<< SeverityStr[static_cast<int>(level)] << ": " << stream.str() << os;
level = Severity::INFO;
stream.str("");
filename.clear();
function.clear();
line = 0;
return *this;
}
};
extern Logger LOG;
#ifdef DEBUG_MODE
#define LOGI LOG(Severity::INFO, __FILE__, __func__, __LINE__)
#define LOGV LOG(Severity::VERBOSE, __FILE__, __func__, __LINE__)
#define LOGD LOG(Severity::DEBUG, __FILE__, __func__, __LINE__)
#define LOGW LOG(Severity::WARNNING, __FILE__, __func__, __LINE__)
#define LOGE LOG(Severity::ERROR, __FILE__, __func__, __LINE__)
#else
#define LOGI LOG(Severity::INFO)
#define LOGV LOG(Severity::VERBOSE)
#define LOGD LOG(Severity::DEBUG)
#define LOGW LOG(Severity::WARNNING)
#define LOGE LOG(Severity::ERROR)
#endif
} // namespace LOGGER
#endif //__LOGGER_H__