GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: tmp_project/StringUtils/src/PLog.cpp Lines: 157 162 96.9 %
Date: 2024-12-09 15:30:52 Branches: 100 114 87.7 %

Line Branch Exec Source
1
/***************************************
2
	Auteur : Pierre Aubert
3
	Mail : pierre.aubert@lapp.in2p3.fr
4
	Licence : CeCILL-C
5
****************************************/
6
7
#include "convertToString.h"
8
#include "string_filename.h"
9
#include "string_system.h"
10
11
#include "PLog.h"
12
13
///Convert the log level into a string
14
/**	@param logLevel : log level to be converted
15
 * 	@return corresponding string
16
*/
17
107
std::string phoenix_logLevelToStr(PLog::Level logLevel){
18

107
	switch(logLevel){
19
38
		case PLog::INFO:
20
38
			return "INFO";
21
5
		case PLog::WARNING:
22
5
			return "WARNING";
23
5
		case PLog::ERROR:
24
5
			return "ERROR";
25
5
		case PLog::CRITICAL:
26
5
			return "CRITICAL";
27
50
		case PLog::ALWAYS:
28
50
			return "ALWAYS";
29
4
		default:
30
4
			return "DEBUG";
31
	}
32
}
33
34
///Convert a string into a log level
35
/**	@param str : string ot be converted
36
 * 	@return corresponding PLog::Level
37
*/
38
6
PLog::Level phoenix_strToLogLevel(const std::string & str){
39
6
	if(str == "DEBUG"){return PLog::DEBUG;}
40
5
	else if(str == "WARNING"){return PLog::WARNING;}
41
4
	else if(str == "ERROR"){return PLog::ERROR;}
42
3
	else if(str == "CRITICAL"){return PLog::CRITICAL;}
43
2
	else if(str == "ALWAYS"){return PLog::ALWAYS;}
44
1
	else{return PLog::INFO;}
45
}
46
47
///Default constructor of PLog
48
12
PLog::PLog(){
49
12
	initialisationPLog();
50
12
}
51
52
///Destructor of PLog
53
32
PLog::~PLog(){
54
24
	close();
55
24
	clear();
56
24
	delete p_nullStream;
57
32
}
58
59
///Set the output filename of the current PLog
60
/**	@param fileName : output filename of the current PLog
61
*/
62
11
void PLog::setFileName(const std::string & fileName){
63
11
	p_fileName = fileName;
64
11
}
65
66
///Set the mode of the current PLog
67
/**	@param mode : mode of the current PLog
68
*/
69
9
void PLog::setMode(PLog::Mode mode){
70
9
	p_mode = mode;
71
9
}
72
73
///Set the log level of the current PLog
74
/**	@param logLevel : log level of the current PLog
75
*/
76
6
void PLog::setLogLevel(PLog::Level logLevel){
77
6
	p_logLevel = logLevel;
78
6
}
79
80
///Set the thread index of the current PLog
81
/**	@param threadIndex : thread index of the current PLog
82
*/
83
2
void PLog::setThreadIndex(size_t threadIndex){
84
2
	p_threadIndex = threadIndex;
85
2
}
86
87
///Resize the number of cihldren log file
88
/**	@param nbThread : number of sub log files to be created (typically the number of threads of a program)
89
*/
90
1
void PLog::resize(size_t nbThread){
91
1
	clear();
92
1
	p_vecLog.resize(nbThread);
93
2
	std::string baseFileName(eraseExtension(p_fileName));
94
2
	std::string extention(getExtention(p_fileName));
95
5
	for(size_t i(0lu); i < nbThread; ++i){
96
4
		p_vecLog[i] = new PLog;
97

4
		p_vecLog[i]->setFileName(baseFileName + "_" + convertToString(i) + "." + extention);
98
4
		p_vecLog[i]->setMode(p_mode);
99
4
		p_vecLog[i]->setLogLevel(p_logLevel);
100
	}
101
1
}
102
103
///Open the current PLog and its children
104
/**	@return true on success, false otherwise
105
*/
106
12
bool PLog::open(){
107
12
	bool b(true);
108
12
	b &= streamOpen();
109
12
	p_isOpen = b;
110
12
	if(b){
111
12
		getLogAlways() << "[UTC][Date][ThreadIndex][LogLevel] : log message" << std::endl;
112
12
		getLogAlways() << "Start logging at " << phoenix_getDate() << std::endl;
113
12
		getLogAlways() << "Current logging level '"<<phoenix_logLevelToStr(getLogLevel())<<"'" << std::endl;
114
	}
115
16
	for(std::vector<PLog*>::iterator it(p_vecLog.begin()); it != p_vecLog.end(); ++it){
116
4
		PLog* log = *it;
117
4
		if(log != NULL){
118
4
			b &= log->open();
119
		}
120
	}
121
12
	return b;
122
}
123
124
///Close the current PLog and its children
125
21
void PLog::close(){
126

21
	if(p_stream != NULL && p_isOpen){
127
12
		getLogAlways() << "Close Log File at " << phoenix_getDate() << std::endl;
128
	}
129
21
	if(p_logFile.is_open()){
130
9
		p_logFile.close();
131
	}
132
// 	if(p_mode == PLog::STRING_ONLY){
133
// 		p_logString.close();
134
// 	}
135
21
	if(p_oldStdCerrBuffer != NULL){
136
2
		std::cerr.rdbuf(p_oldStdCerrBuffer);	//Let's get back to previous std::cerr buffer
137
	}
138
21
	if(p_oldStdCoutBuffer != NULL){
139
2
		std::cout.rdbuf(p_oldStdCoutBuffer);	//Let's get back to previous std::cout buffer
140
	}
141
21
	if(p_stream != NULL){
142
12
		delete p_stream;
143
12
		p_stream = NULL;
144
	}
145
21
	p_isOpen = false;
146
25
	for(std::vector<PLog*>::iterator it(p_vecLog.begin()); it != p_vecLog.end(); ++it){
147
4
		PLog* log = *it;
148
4
		if(log != NULL){
149
4
			log->close();
150
		}
151
	}
152
21
}
153
154
///Clear the children of the current PLog
155
13
void PLog::clear(){
156
13
	if(p_vecLog.size() != 0lu){
157
5
		for(std::vector<PLog*>::iterator it(p_vecLog.begin()); it != p_vecLog.end(); ++it){
158
4
			PLog* log = *it;
159
4
			if(log != NULL){
160
4
				delete log;
161
			}
162
		}
163
1
		p_vecLog.clear();
164
	}
165
13
}
166
167
///Append the log (STRING_ONLY mode) into an other log
168
/**	@param str : log string to be appended
169
*/
170
1
void PLog::appendLog(std::stringstream & str){
171
1
	getLog(PLog::ALWAYS) << "Append log" << std::endl << str.str();
172
1
}
173
174
///Get the PLog at given index
175
/**	@return PLog at Index
176
*/
177
4
PLog & PLog::getLog(size_t threadIndex){
178
4
	return *(p_vecLog[threadIndex]);
179
}
180
181
///Get the current log file
182
/**	@return current log file
183
*/
184
std::ofstream & PLog::getLogFile(){
185
	return p_logFile;
186
}
187
188
///Get the log string
189
/**	@return log string
190
*/
191
1
std::stringstream & PLog::getLogString(){
192
1
	return p_logString;
193
}
194
195
///Write log into the PLog
196
/**	@param logLevel : log level of the current line
197
 * 	@return ofstream to be written
198
*/
199
91
std::ostream & PLog::getLog(PLog::Level logLevel){
200
91
	if(logLevel >= p_logLevel){
201

89
		*p_stream << "[" << phoenix_getTime() << "][" << phoenix_getDateCompact() << "][" << p_threadIndex << "]["<<phoenix_logLevelToStr(logLevel)<<"] : ";
202
89
		return *p_stream;
203
	}else{
204
2
		return *p_nullStream;
205
	}
206
}
207
208
///Write debug message into the PLog
209
/**	@return ofstream to be written
210
*/
211
2
std::ostream & PLog::getLogDebug(){
212
2
	return getLog(PLog::DEBUG);
213
}
214
215
///Write info message into the PLog
216
/**	@return ofstream to be written
217
*/
218
6
std::ostream & PLog::getLogInfo(){
219
6
	return getLog(PLog::INFO);
220
}
221
222
///Write warning message into the PLog
223
/**	@return ofstream to be written
224
*/
225
2
std::ostream & PLog::getLogWarning(){
226
2
	return getLog(PLog::WARNING);
227
}
228
229
///Write error message into the PLog
230
/**	@return ofstream to be written
231
*/
232
2
std::ostream & PLog::getLogError(){
233
2
	return getLog(PLog::ERROR);
234
}
235
236
///Write critical message into the PLog
237
/**	@return ofstream to be written
238
*/
239
2
std::ostream & PLog::getLogCritical(){
240
2
	return getLog(PLog::CRITICAL);
241
}
242
243
///Write always message into the PLog
244
/**	@return ofstream to be written
245
*/
246
48
std::ostream & PLog::getLogAlways(){
247
48
	return getLog(PLog::ALWAYS);
248
}
249
250
251
///Get the filename of the current log
252
/**	@return filename of the current log
253
*/
254
2
const std::string & PLog::getFileName() const{
255
2
	return p_fileName;
256
}
257
258
///Get the mode of the current PLog
259
/**	@return mode of the current PLog
260
*/
261
PLog::Mode PLog::getMode() const{
262
	return p_mode;
263
}
264
265
///Get the log level of the current PLog
266
/**	@return log level of the current PLog
267
*/
268
12
PLog::Level PLog::getLogLevel() const{
269
12
	return p_logLevel;
270
}
271
272
///Get the thread index of the current  PLog
273
/**	@return thread index of the current  PLog
274
*/
275
1
size_t PLog::getThreadIndex() const{
276
1
	return p_threadIndex;
277
}
278
279
///Initialisation function of the class PLog
280
12
void PLog::initialisationPLog(){
281
12
	p_mode = PLog::FILE_ONLY;
282
12
	p_logLevel = PLog::INFO;
283
12
	p_oldStdCerrBuffer = NULL;
284
12
	p_oldStdCoutBuffer = NULL;
285
12
	p_isOpen = false;
286
12
	p_stream = NULL;
287
12
	p_nullStream = new std::ostream(NULL);
288
12
	p_threadIndex = 0lu;
289
12
}
290
291
///Allocate the stream
292
/**	@param buffer : buffer to be used
293
*/
294
12
void PLog::allocateStream(std::streambuf* buffer){
295
12
	if(p_stream != NULL){
296
		delete p_stream;
297
	}
298
12
	p_stream = new std::ostream(buffer);
299
12
}
300
301
///Open the streams
302
/**	@return true on success, false otherwise
303
*/
304
12
bool PLog::streamOpen(){
305
12
	bool b(true);
306
12
	if(p_mode == PLog::FILE_ONLY){
307
8
		p_logFile.open(p_fileName);
308
8
		b &= p_logFile.is_open();
309
8
		if(b){
310
8
			allocateStream(p_logFile.rdbuf());
311
		}
312
4
	}else if(p_mode == PLog::STRING_ONLY){
313
1
		std::cerr << "PLog::streamOpen : p_logString.rdbuf() = " << p_logString.rdbuf() << std::endl;
314
1
		allocateStream(p_logString.rdbuf());
315
3
	}else if(p_mode == PLog::FILE_CAPTURE_STDOUT_STDERR){
316
1
		p_logFile.open(p_fileName);
317
1
		b &= p_logFile.is_open();
318
1
		if(b){
319
1
			p_oldStdCerrBuffer = std::cerr.rdbuf(p_logFile.rdbuf());
320
1
			p_oldStdCoutBuffer = std::cout.rdbuf(p_logFile.rdbuf());
321
1
			allocateStream(p_logFile.rdbuf());
322
		}
323
2
	}else if(p_mode == PLog::STDOUT_ONLY){
324
1
		allocateStream(std::cout.rdbuf());
325
1
	}else if(p_mode == PLog::DISABLE){
326
1
		allocateStream(NULL);
327
	}
328
12
	return b;
329
}
330
331
332
333