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
Janik Zikovsky
committed
* @param name :: The class name invoking this logger
Gigg, Martyn Anthony
committed
*/
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
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
*
Janik Zikovsky
committed
* @param enabled :: true - logging is enabled, false - all messages are ignored.
Gigg, Martyn Anthony
committed
*/
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.
*
Janik Zikovsky
committed
* @param msg :: The message to log.
Gigg, Martyn Anthony
committed
*/
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.
*
Janik Zikovsky
committed
* @param msg :: The message to log.
Gigg, Martyn Anthony
committed
*/
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.
*
Janik Zikovsky
committed
* @param msg :: The message to log.
Gigg, Martyn Anthony
committed
*/
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.
*
Janik Zikovsky
committed
* @param msg :: The message to log.
Gigg, Martyn Anthony
committed
*/
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.
*
Janik Zikovsky
committed
* @param msg :: The message to log.
Gigg, Martyn Anthony
committed
*/
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.
*
Janik Zikovsky
committed
* @param msg :: The message to log.
Gigg, Martyn Anthony
committed
*/
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
*
Janik Zikovsky
committed
* @param msg :: The message to log
* @param buffer :: the binary data to log
* @param length :: The length of the binaary data to log
Gigg, Martyn Anthony
committed
*/
void Logger::dump(const std::string& msg, const void* buffer, std::size_t length)
{
if(m_enabled)
{
try
Gigg, Martyn Anthony
committed
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.
Janik Zikovsky
committed
* @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)
Gigg, Martyn Anthony
committed
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
*/
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.
///
Janik Zikovsky
committed
/// @param level :: Valid values are: fatal, critical, error, warning, notice, information, debug
Gigg, Martyn Anthony
committed
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
* 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.
*
Janik Zikovsky
committed
* @param logger :: The logger to destroy.
Gigg, Martyn Anthony
committed
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
*/
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.
*
Janik Zikovsky
committed
* @param name :: The name of the logger to use - this is usually the class name.
Gigg, Martyn Anthony
committed
*/
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
Janik Zikovsky
committed
* @param message :: The message to log
* @param priority :: The priority level
Gigg, Martyn Anthony
committed
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
439
440
*/
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