Skip to content
This repository was archived by the owner on Feb 21, 2024. It is now read-only.

Commit 1357941

Browse files
committed
Merge branch 'develop' into 'master'
Develop v1.3 See merge request Asteomount/Logger!3
2 parents 276d4e9 + 7f467e4 commit 1357941

File tree

7 files changed

+784
-166
lines changed

7 files changed

+784
-166
lines changed

C++/logger/Logger.cpp

+91-17
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22

33
std::ofstream Logger::file("");
44

5-
int Logger::nbWrite = 0;
5+
std::vector<std::ostream *> Logger::additionalStreams = std::vector<std::ostream *>();
6+
7+
int Logger::nbLog = 0;
68

79
pthread_mutex_t Logger::mutex;
810

911
LoggerOption Logger::verbose = FILE_AND_CONSOLE;
1012

11-
bool Logger::showTrace = true;
12-
1313
std::vector<LoggerType> Logger::showTypes = {INFO, SUCCESS, ERROR, WARNING, DEBUG};
1414

1515

@@ -93,10 +93,9 @@ std::string Logger::getTypeName(LoggerType type) {
9393
}
9494
}
9595

96-
void Logger::init(LoggerOption verboseP, bool showTraceP, const std::vector<LoggerType> &showTypesP) {
96+
void Logger::init(LoggerOption verboseP, const std::vector<LoggerType> &showTypesP) {
9797
if (!file.is_open()) {
9898
verbose = verboseP;
99-
showTrace = showTraceP;
10099
showTypes = showTypesP;
101100

102101
bool dirCreated = false;
@@ -107,7 +106,7 @@ void Logger::init(LoggerOption verboseP, bool showTraceP, const std::vector<Logg
107106
std::string fileName = (LOG_PATH "/" PROJECT_NAME "_log_") + getDate() + ".log";
108107
file.open(fileName, std::ios::out);
109108

110-
nbWrite = 0;
109+
nbLog = 0;
111110

112111
if (pthread_mutex_init(&mutex, nullptr) != 0)
113112
ERROR_LOG(CONSOLE_ONLY, "Error mutex : %d\n", errno);
@@ -129,35 +128,110 @@ void Logger::exit() {
129128
ERROR_LOG(CONSOLE_ONLY, "Please init before exit\n");
130129
}
131130

131+
void Logger::addOutputStream(std::ostream *os) {
132+
additionalStreams.push_back(os);
133+
}
134+
132135
void Logger::genericLog(const std::string &function, const std::string &message, LoggerType type, LoggerOption option) {
133136
std::string t = message;
134137

135-
if (showTrace) {
136-
t = "[" + function + "]\t" + message;
137-
}
138-
139138
if (t[t.length() - 1] != '\n') {
140139
t += "\n";
141140
}
142141

143142
if (option != FILE_ONLY && verbose != FILE_ONLY &&
144143
std::find(showTypes.begin(), showTypes.end(), type) != showTypes.end())
145-
std::cout << getTypeColor(type) << t << getColor(DEFAULT);
144+
std::cout << getTypeColor(type) << constructMessage(t, function, getTypeName(type), CONSOLE_FORMAT)
145+
<< getColor(DEFAULT);
146146

147147
if (option != CONSOLE_ONLY && verbose != CONSOLE_ONLY) {
148148
pthread_mutex_lock(&mutex);
149-
writeToFile(t, type);
149+
writeToFile(constructMessage(t, function, getTypeName(type), FILE_FORMAT));
150150
pthread_mutex_unlock(&mutex);
151151
}
152+
153+
if (option != CONSOLE_ONLY && option != FILE_ONLY && verbose == FILE_AND_CONSOLE) {
154+
for (const auto &os: additionalStreams) {
155+
std::string m = constructMessage(t, function, getTypeName(type), ADDITIONAL_FORMAT);
156+
os->write(m.c_str(), (long) m.length());
157+
os->flush();
158+
}
159+
}
160+
161+
nbLog++;
162+
}
163+
164+
std::string Logger::constructMessage(const std::string &message, const std::string &trace, const std::string &logType,
165+
const std::string &format) {
166+
std::string res;
167+
168+
int i = 0;
169+
while (i < format.length()) {
170+
char c = format[i];
171+
if (c == '%') {
172+
i++;
173+
c = format[i];
174+
175+
struct timespec now{};
176+
clock_gettime(CLOCK_REALTIME, &now);
177+
struct tm *t = localtime(&now.tv_sec);
178+
switch (c) {
179+
case 'Y':
180+
res += std::to_string(t->tm_year + 1900);
181+
break;
182+
case 'M':
183+
res += std::to_string(t->tm_mon + 1);
184+
break;
185+
case 'D':
186+
res += std::to_string(t->tm_mday);
187+
break;
188+
case 'H':
189+
res += std::to_string(t->tm_hour);
190+
break;
191+
case 'm':
192+
res += std::to_string(t->tm_min);
193+
break;
194+
case 'S':
195+
res += std::to_string(t->tm_sec);
196+
break;
197+
case 'N':
198+
res += std::to_string(now.tv_nsec);
199+
break;
200+
case 'd':
201+
res += getDate();
202+
break;
203+
case 'h':
204+
res += getHour();
205+
break;
206+
case 'T':
207+
res += trace;
208+
break;
209+
case 'C':
210+
res += message;
211+
break;
212+
case 'n':
213+
res += std::to_string(nbLog);
214+
break;
215+
case 't':
216+
res += logType;
217+
break;
218+
default:
219+
break;
220+
}
221+
} else {
222+
res += c;
223+
}
224+
225+
i++;
226+
}
227+
228+
return res;
152229
}
153230

154-
void Logger::writeToFile(const std::string &message, LoggerType type) {
231+
void Logger::writeToFile(const std::string &message) {
155232
if (file.is_open()) {
156-
std::string toPrint =
157-
"[" + std::to_string(nbWrite) + "-" + getHour() + "-" + getTypeName(type) + "]\t" + message;
158-
file << toPrint;
233+
file << message;
159234
file.flush();
160-
nbWrite++;
161235
} else
162236
ERROR_LOG(CONSOLE_ONLY, "Please init logger\n");
163237
}

C++/logger/Logger.hpp

+81-14
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@
1212
#include <vector>
1313
#include <algorithm>
1414

15-
/**
15+
/*
1616
* Logger
17-
* <p>
17+
*
1818
* Use Logger::init() to start the logger and Logger::exit() to close the logger
19-
* <p>
19+
*
2020
* Simple usage :
2121
* DEBUG_LOG(FILE_AND_CONSOLE, "Is it simple ? YES");
2222
* Write 'Is it simple ? YES' (without the quote) in the console and the file
23-
* <p>
23+
*
2424
* Complex usage :
2525
* INFO_LOG(CONSOLE_ONLY, "Not too complex ? ", "Maybe");
2626
* Write 'Not toot complex ? Maybe' (without the quote) only in the console
@@ -41,6 +41,40 @@
4141
*/
4242
#define PROJECT_NAME "project"
4343

44+
/*
45+
* Different rules for the formats :
46+
* %Y -> Year
47+
* %M -> Month
48+
* %D -> Day
49+
* %H -> Hour
50+
* %m -> Minute
51+
* %S -> Second
52+
* %N -> Nano second
53+
* %d -> Date (%Y-%M-%D@%H-%m-%S)
54+
* %h -> Hour (%H:%m:%S:%N)
55+
* %T -> Trace
56+
* %C -> Content message
57+
* %n -> Log number
58+
* %t -> Log type
59+
*/
60+
61+
/**
62+
* Format for console log
63+
*/
64+
#define CONSOLE_FORMAT "[%T]\t%C"
65+
66+
/**
67+
* Format for log file
68+
*/
69+
#define FILE_FORMAT "[%n-%h-%t]\t[%T]\t%C"
70+
71+
/**
72+
* Format for additional output stream
73+
*/
74+
#define ADDITIONAL_FORMAT "[%n-%t]\t[%T]\t%C"
75+
76+
// _.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-.
77+
4478
/**
4579
* Log colors
4680
* Use DEFAULT for reset color
@@ -87,6 +121,8 @@ typedef enum LoggerOption {
87121
FILE_AND_CONSOLE
88122
} LoggerOption;
89123

124+
// _.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-.
125+
90126
class Logger {
91127
private:
92128
/**
@@ -115,14 +151,18 @@ class Logger {
115151
* Initialisation
116152
*/
117153
static void init(LoggerOption verboseP = FILE_AND_CONSOLE,
118-
bool showTraceP = true,
119154
const std::vector<LoggerType> &showTypesP = {INFO, SUCCESS, ERROR, WARNING, DEBUG});
120155

121156
/**
122157
* Quit the log and close the writer
123158
*/
124159
static void exit();
125160

161+
/**
162+
* Add a new output for the logs
163+
*/
164+
static void addOutputStream(std::ostream *os);
165+
126166
public:
127167
/**
128168
* Info
@@ -192,14 +232,41 @@ class Logger {
192232
* @param type LoggerType
193233
* @param option LoggerOption
194234
*/
195-
static void genericLog(const std::string &function, const std::string &message, LoggerType type, LoggerOption option);
235+
static void
236+
genericLog(const std::string &function, const std::string &message, LoggerType type, LoggerOption option);
237+
238+
/**
239+
* Construct the message from the format
240+
* Different rules for the formats :
241+
* %Y -> Year
242+
* %M -> Month
243+
* %D -> Day
244+
* %H -> Hour
245+
* %m -> Minute
246+
* %S -> Second
247+
* %N -> Nano second
248+
* %d -> Date (%Y-%M-%D@%H-%m-%S)
249+
* %h -> Hour (%H:%m:%S:%N)
250+
* %T -> Trace
251+
* %C -> Content message
252+
* %n -> Log number
253+
* %t -> Log type
254+
*
255+
* @param message
256+
* @param trace
257+
* @param logType
258+
* @param format
259+
* @return
260+
*/
261+
static std::string
262+
constructMessage(const std::string &message, const std::string &trace, const std::string &logType,
263+
const std::string &format);
196264

197265
/**
198266
* Write the log into the file
199267
* @param message std::string
200-
* @param type LoggerType
201268
*/
202-
static void writeToFile(const std::string &message, LoggerType type);
269+
static void writeToFile(const std::string &message);
203270

204271
/**
205272
* The log's hour
@@ -211,7 +278,7 @@ class Logger {
211278
/**
212279
* The log's date
213280
* yyyy-mm-dd@hh-mm-ss
214-
* @return
281+
* @return std::string
215282
*/
216283
static std::string getDate();
217284

@@ -220,10 +287,14 @@ class Logger {
220287
* The log file
221288
*/
222289
static std::ofstream file;
290+
/**
291+
* Additional output for the logs
292+
*/
293+
static std::vector<std::ostream *> additionalStreams;
223294
/**
224295
* The number of log
225296
*/
226-
static int nbWrite;
297+
static int nbLog;
227298
/**
228299
* A mutex for writeToFile(), to be thread-safe
229300
*/
@@ -232,10 +303,6 @@ class Logger {
232303
* The type of verbose
233304
*/
234305
static LoggerOption verbose;
235-
/**
236-
* Show trace or not
237-
*/
238-
static bool showTrace;
239306
/**
240307
* The types of logs that be shown
241308
*/

0 commit comments

Comments
 (0)