-
Notifications
You must be signed in to change notification settings - Fork 0
/
logger.hpp
156 lines (131 loc) · 4.24 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
146
147
148
149
150
151
152
153
154
155
156
/************************************************************************
Copyright 2018 [email protected]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
************************************************************************/
#ifndef __LOGGER_HPP__
#define __LOGGER_HPP__
#include <cstdio>
#include <iostream>
#include <memory>
#include <sstream>
#include <string>
#include <typeinfo>
#include <mutex>
#include "severity.hpp"
// color mocro
// #define CLEARSCREEN() printf("\033[H\033[2J")
#define INITCOLOR(color) \
std::string("\033[") + std::string(color) + std::string("m")
#define RED_COLOR "31"
#define GREEN_COLOR "32"
#define YELLOW_COLOR "33"
#define BLUE_COLOR "34"
#define ZERO_COLOR "0"
template <typename policy_type>
class Logger {
public:
static Logger& getLoggerInstance(std::string filename_or_addr) {
static Logger logger(filename_or_addr);
return logger;
}
Logger(const Logger&) = delete;
Logger& operator=(const Logger&) = delete;
// template<typename...Args>
template <severity_type severity, typename... Args>
void PrintLog(const Args&... args) {
// init p and ssp only once
if (!p) {
p = std::shared_ptr<policy_type>(new policy_type(this->filename_or_addr));
if (typeid(TerminalPolicy) == typeid(*p)) {
this->is_terminal = true;
}
}
if (!ssp) {
ssp = std::shared_ptr<std::stringstream>(new std::stringstream);
}
write_lock.lock();
(*ssp) << "[" << getCurrentTime() << "] ";
switch (severity) {
case severity_type::info:
if (this->is_terminal)
(*ssp) << INITCOLOR(GREEN_COLOR) << "<INFO>" << INITCOLOR(ZERO_COLOR)
<< ": "; // with color
else
(*ssp) << "<INFO>: "; // no color
break;
case severity_type::debug:
if (this->is_terminal)
(*ssp) << INITCOLOR(BLUE_COLOR) << "<DEBUG>" << INITCOLOR(ZERO_COLOR)
<< ": ";
else
(*ssp) << "<DEBUG>: ";
break;
case severity_type::warn:
if (this->is_terminal)
(*ssp) << INITCOLOR(YELLOW_COLOR) << "<WARN>" << INITCOLOR(ZERO_COLOR)
<< ": ";
else
(*ssp) << "<WARN>: ";
break;
case severity_type::error:
if (this->is_terminal)
(*ssp) << INITCOLOR(RED_COLOR) << "<ERROR>" << INITCOLOR(ZERO_COLOR)
<< ": ";
else
(*ssp) << "<ERROR>: ";
break;
};
this->print_impl(args...);
write_lock.unlock();
}
template <typename... Args>
void LOG_INFO(const Args&... args) {
this->PrintLog<severity_type::info>(args...);
}
template <typename... Args>
void LOG_DEBUG(const Args&... args) {
this->PrintLog<severity_type::debug>(args...);
}
template <typename... Args>
void LOG_WARN(const Args&... args) {
this->PrintLog<severity_type::warn>(args...);
}
template <typename... Args>
void LOG_ERROR(const Args&... args) {
this->PrintLog<severity_type::error>(args...);
}
private:
std::mutex write_lock;
// policy_type policy;
std::shared_ptr<policy_type> p;
std::string filename_or_addr;
std::shared_ptr<std::stringstream> ssp;
bool is_terminal = false;
void print_impl() { // Recursive termination function
p->write(ssp->str());
ssp->str(""); // ssp->empty(),ssp->clear() can not clean ssp
}
template <typename First, typename... Rest>
void print_impl(const First& parm1, const Rest&... parm) {
(*ssp) << parm1 << " ";
print_impl(parm...);
}
std::string getCurrentTime() {
time_t t;
time(&t);
struct tm* tmp_time = localtime(&t);
char s[100];
strftime(s, sizeof(s), "%04Y/%02m/%02d %H:%M:%S", tmp_time);
return static_cast<std::string>(s);
}
Logger(std::string& f) { this->filename_or_addr = f; }
};
#endif