Newer
Older
Gigg, Martyn Anthony
committed
#include "MantidKernel/ThreadSafeLogStream.h"
Gigg, Martyn Anthony
committed
#include <Poco/Message.h>
Nick Draper
committed
#include <iostream>
Russell Taylor
committed
{
Gigg, Martyn Anthony
committed
namespace Kernel
{
Logger::LoggerList* Logger::m_loggerList = NULL;
Poco::NullOutputStream* Logger::m_nullStream = NULL;
/** Constructor
* @param name The class name invoking this logger
*/
Logger::Logger(const std::string& name) : m_enabled(true)
{
m_name = name;
m_log=&Poco::Logger::get(m_name);
m_logStream = new Mantid::Kernel::ThreadSafeLogStream(*m_log);
}
/// Destructor
Logger::~Logger()
{
delete (m_logStream);
}
/// Sets the Loggername to a new value.
Gigg, Martyn Anthony
committed
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
void Logger::setName(std::string newName)
{
//delete the log stream
delete (m_logStream);
//reassign m_log
m_name = newName;
m_log = &Poco::Logger::get(m_name);
//create a new Logstream
m_logStream = new Mantid::Kernel::ThreadSafeLogStream(*m_log);
}
/** Returns true if the log is enabled
*
* @retval true - logging is enabled
* @retval false - all messages are ignored.
*/
bool Logger::getEnabled() const
{
return m_enabled;
}
/** set if the logging is enabled
*
* @param enabled true - logging is enabled, false - all messages are ignored.
*/
void Logger::setEnabled(const bool enabled)
{
m_enabled = enabled;
}
/** If the Logger's log level is at least PRIO_FATAL, creates a Message with
* priority PRIO_FATAL and the given message text and sends it to the attached channel.
*
* @param msg The message to log.
*/
void Logger::fatal(const std::string& msg)
{
log(msg, PRIO_FATAL);
}
/** If the Logger's log level is at least PRIO_ERROR, creates a Message with priority
* PRIO_ERROR and the given message text and sends it to the attached channel.
*
* @param msg The message to log.
*/
void Logger::error(const std::string& msg)
{
log(msg, PRIO_ERROR);
}
/** If the Logger's log level is at least PRIO_WARNING, creates a Message with
* priority PRIO_WARNING and the given message text and sends it to the attached channel.
*
* @param msg The message to log.
*/
void Logger::warning(const std::string& msg)
{
log(msg, PRIO_WARNING);
}
/** If the Logger's log level is at least PRIO_NOTICE, creates a Message with
* priority PRIO_NOTICE and the given message text and sends it to the attached channel.
*
* @param msg The message to log.
*/
void Logger::notice(const std::string& msg)
{
log(msg, PRIO_NOTICE);
}
/** If the Logger's log level is at least PRIO_INFORMATION, creates a Message with
* priority PRIO_INFORMATION and the given message text and sends it to the
* attached channel.
*
* @param msg The message to log.
*/
void Logger::information(const std::string& msg)
{
log(msg, PRIO_INFORMATION);
}
/** If the Logger's log level is at least PRIO_DEBUG, creates a Message with priority
* PRIO_DEBUG and the given message text and sends it to the attached channel.
*
* @param msg The message to log.
*/
void Logger::debug(const std::string& msg)
{
log(msg, PRIO_DEBUG);
}
/** Logs the given message at debug level, followed by the data in buffer.
*
* The data in buffer is written in canonical hex+ASCII form:
* Offset (4 bytes) in hexadecimal, followed by sixteen space-separated,
* two column, hexadecimal bytes, followed by the same sixteen bytes as
* ASCII characters.
* For bytes outside the range 32 .. 127, a dot is printed.
* Note all Dump messages go out at Debug message level
*
* @param msg The message to log
* @param buffer the binary data to log
* @param length The length of the binaary data to log
*/
void Logger::dump(const std::string& msg, const void* buffer, std::size_t length)
{
if(m_enabled)
{
try
Gigg, Martyn Anthony
committed
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
m_log->dump(msg,buffer,length);
}
catch (std::exception& e)
{
//failures in logging are not allowed to throw exceptions out of the logging class
std::cerr << e.what();
}
}
}
/** Returns true if at least the given log level is set.
* @param level The logging level it is best to use the Logger::Priority enum (7=debug, 6=information, 4=warning, 3=error, 2=critical, 1=fatal)
*/
bool Logger::is(int level) const
{
bool retVal = false;
try
{
retVal = m_log->is(level);
}
catch (std::exception& e)
{
//failures in logging are not allowed to throw exceptions out of the logging class
std::cerr << e.what();
}
return retVal;
}
void Logger::setLevel(int level)
{
try
{
m_log->setLevel(level);
}
catch (std::exception& e)
{
//failures in logging are not allowed to throw exceptions out of the logging class
std::cerr << e.what();
}
}
/// Sets the Logger's log level using a symbolic value.
///
/// @param level Valid values are: fatal, critical, error, warning, notice, information, debug
void Logger::setLevel(const std::string& level)
{
try
{
m_log->setLevel(level);
}
catch (std::exception& e)
{
//failures in logging are not allowed to throw exceptions out of the logging class
std::cerr << e.what();
}
}
int Logger::getLevel() const
{
return m_log->getLevel();
}
/** This class implements an ostream interface to the Logger for fatal messages.
*
* The stream's buffer appends all characters written to it
* to a string. As soon as a CR or LF (std::endl) is written,
Gigg, Martyn Anthony
committed
* the string is sent to the Logger.
* @returns an std::ostream reference.
*/
std::ostream& Logger::fatal()
{
if (m_enabled)
{
return m_logStream->fatal();
}
else
{
return *m_nullStream;
}
}
/** This class implements an ostream interface to the Logger for error messages.
*
* The stream's buffer appends all characters written to it
* to a string. As soon as a CR or LF (std::endl) is written,
Gigg, Martyn Anthony
committed
* the string is sent to the Logger.
* @returns an std::ostream reference.
*/
std::ostream& Logger::error()
{
if (m_enabled)
{
return m_logStream->error();
}
else
{
return *m_nullStream;
}
}
/** This class implements an ostream interface to the Logger for warning messages.
*
* The stream's buffer appends all characters written to it
* to a string. As soon as a CR or LF (std::endl) is written,
Gigg, Martyn Anthony
committed
* the string is sent to the Logger.
* @returns an std::ostream reference.
*/
std::ostream& Logger::warning()
{
if (m_enabled)
{
return m_logStream->warning();
}
else
{
return *m_nullStream;
}
}
/** This class implements an ostream interface to the Logger for notice messages.
*
* The stream's buffer appends all characters written to it
* to a string. As soon as a CR or LF (std::endl) is written,
Gigg, Martyn Anthony
committed
* the string is sent to the Logger.
* @returns an std::ostream reference.
*/
std::ostream& Logger::notice()
{
if (m_enabled)
{
return m_logStream->notice();
}
else
{
return *m_nullStream;
}
}
/** This class implements an ostream interface to the Logger for information messages.
*
* The stream's buffer appends all characters written to it
* to a string. As soon as a CR or LF (std::endl) is written,
Gigg, Martyn Anthony
committed
* the string is sent to the Logger.
* @returns an std::ostream reference.
*/
std::ostream& Logger::information()
{
if (m_enabled)
{
return m_logStream->information();
}
else
{
return *m_nullStream;
}
}
/** This class implements an ostream interface to the Logger for debug messages.
*
* The stream's buffer appends all characters written to it
* to a string. As soon as a CR or LF (std::endl) is written,
Gigg, Martyn Anthony
committed
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
* the string is sent to the Logger.
* @returns an std::ostream reference.
*/
std::ostream& Logger::debug()
{
if (m_enabled)
{
return m_logStream->debug();
}
else
{
return *m_nullStream;
}
}
/** releases resources and deletes this object.
*/
void Logger::release()
{
destroy(*this);
}
/** Deletes the logger and clears it from the cache.
*
* @param logger The logger to destroy.
*/
void Logger::destroy(Logger& logger)
{
if (m_loggerList)
{
LoggerList::iterator it = m_loggerList->find(&logger);
if (it != m_loggerList->end())
{
delete(*it);
m_loggerList->erase(it);
}
}
}
/// Shuts down the logging framework and releases all Loggers.
void Logger::shutdown()
{
try
{
//first release the POCO loggers
Poco::Logger::shutdown();
//now delete our static cache of loggers
if (m_loggerList)
{
for (LoggerList::iterator it = m_loggerList->begin(); it != m_loggerList->end(); ++it)
{
delete(*it);
}
delete m_loggerList;
m_loggerList = 0;
}
//delete the NullChannel
if (m_nullStream)
{
delete(m_nullStream);
m_nullStream=0;
}
}
catch (std::exception& e)
{
//failures in logging are not allowed to throw exceptions out of the logging class
std::cerr << e.what();
}
}
/** Returns a reference to the Logger with the given name.
* This logger is stored until in a static list until it is destroyed, released or Logger::shutdown is called.
*
* @param name The name of the logger to use - this is usually the class name.
*/
Logger& Logger::get(const std::string& name)
{
Logger* pLogger = new Logger(name);
//assert the nullSteam
if(!m_nullStream)
{
m_nullStream = new Poco::NullOutputStream;
}
//assert the loggerlist
if (!m_loggerList)
{
m_loggerList = new LoggerList;
}
//insert the newly created logger
m_loggerList->insert(pLogger);
return *pLogger;
}
/**
* Log a given message at a given priority
* @param message The message to log
* @param priority The priority level
*/
void Logger::log(const std::string message, Logger::Priority priority)
{
if( !m_enabled ) return;
try
{
switch( priority )
{
case PRIO_FATAL: m_log->fatal(message);
break;
case PRIO_ERROR: m_log->error(message);
break;
case PRIO_WARNING: m_log->warning(message);
break;
case PRIO_NOTICE: m_log->notice(message);
break;
case PRIO_INFORMATION: m_log->information(message);
break;
case PRIO_DEBUG: m_log->debug(message);
break;
default:
break;
}
}
catch(std::exception& e)
{
// Failures in logging are not allowed to throw exceptions out of the logging class
std::cerr << e.what();
}
}
} // namespace Kernel
Russell Taylor
committed
} // Namespace Mantid