Mantid
Loading...
Searching...
No Matches
Logger.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
8
9#include <Poco/Logger.h>
10#include <Poco/NullStream.h>
11
12#include <algorithm>
13#include <exception>
14#include <iostream>
15#include <sstream>
16
17namespace Mantid::Kernel {
18namespace {
19// We only need a single NullStream object
20Poco::NullOutputStream NULL_STREAM;
21
22int fixLevel(const int level) {
23 if (level < 0)
24 return 0;
25 else if (level >= int(Logger::PriorityNames.size()))
26 return int(Logger::PriorityNames.size()) - 1;
27 else
28 return level;
29}
30
31int toLevel(const std::string &level) {
32 // convert the string to uppercase
33 std::string lowercase(level); // make sure space is allocated
34 std::transform(level.cbegin(), level.cend(), lowercase.begin(), [](unsigned char c) { return std::tolower(c); });
35
36 // see if it is an alias for "none"
37 if (lowercase == "not_used") {
38 lowercase = "none";
39 }
40
41 // look for it in the list already
42 const auto iter = std::find(Logger::PriorityNames.cbegin(), Logger::PriorityNames.cend(), lowercase);
43 if (iter != Logger::PriorityNames.cend()) {
44 return int(std::distance(Logger::PriorityNames.cbegin(), iter));
45 }
46
47 // didn't find it so error out
48 std::stringstream msg;
49 msg << "Do not know how to convert \"" << level << "\" to an integer level";
50 throw std::runtime_error(msg.str());
51}
52
53} // anonymous namespace
54
55// "none" effectively turns off logging
56const std::array<std::string, 9> Logger::PriorityNames{"none", "fatal", "critical", "error", "warning",
57 "notice", "information", "debug", "trace"};
58
62Logger::Logger(const std::string &name)
63 : m_log(&Poco::Logger::get(name)), m_logStream(std::make_unique<ThreadSafeLogStream>(*m_log)), m_levelOffset(0),
64 m_enabled(true) {}
65
69void Logger::setName(const std::string &name) {
70 auto *logger = &Poco::Logger::get(name);
71 auto logStream = std::make_unique<ThreadSafeLogStream>(*logger); // don't swap if this throws
72
73 using std::swap;
74 swap(m_log, logger);
75 swap(m_logStream, logStream);
76}
77
83bool Logger::getEnabled() const { return m_enabled; }
84
90void Logger::setEnabled(const bool enabled) { m_enabled = enabled; }
91
99void Logger::fatal(const std::string &msg) { log(msg, Poco::Message::PRIO_FATAL); }
100
108void Logger::error(const std::string &msg) { log(msg, Poco::Message::PRIO_ERROR); }
109
117void Logger::warning(const std::string &msg) { log(msg, Poco::Message::PRIO_WARNING); }
118
126void Logger::notice(const std::string &msg) { log(msg, Poco::Message::PRIO_NOTICE); }
127
136void Logger::information(const std::string &msg) { log(msg, Poco::Message::PRIO_INFORMATION); }
137
145void Logger::debug(const std::string &msg) { log(msg, Poco::Message::PRIO_DEBUG); }
146
160void Logger::dump(const std::string &msg, const void *buffer, std::size_t length) {
161 if (m_enabled) {
162 try {
163 m_log->dump(msg, buffer, length);
164 } catch (std::exception &e) {
165 // failures in logging are not allowed to throw exceptions out of the
166 // logging class
167 std::cerr << e.what();
168 }
169 }
170}
171
177bool Logger::is(int level) const {
178 bool retVal = false;
179 try {
180 retVal = m_log->is(level);
181 } catch (std::exception &e) {
182 // failures in logging are not allowed to throw exceptions out of the
183 // logging class
184 std::cerr << e.what();
185 }
186 return retVal;
187}
188
189bool Logger::isDebug() const { return this->is(Priority::PRIO_DEBUG); }
190
191void Logger::setLevel(int level) {
192 try {
193 const int levelActual = fixLevel(level);
194 m_log->setLevel(levelActual);
195 } catch (std::exception &e) {
196 // failures in logging are not allowed to throw exceptions out of the
197 // logging class
198 std::cerr << e.what() << "\n";
199 }
200}
201
206void Logger::setLevel(const std::string &level) {
207 try {
208 const int int_level = toLevel(level);
209 m_log->setLevel(int_level);
210 } catch (std::exception &e) {
211 // failures in logging are not allowed to throw exceptions out of the
212 // logging class
213 std::cerr << e.what() << "\n";
214 }
215}
216
217int Logger::getLevel() const { return m_log->getLevel(); }
218
219std::string Logger::getLevelName() const {
220 const auto level = std::size_t(this->getLevel());
221 return Logger::PriorityNames[level];
222}
223
231std::ostream &Logger::fatal() { return getLogStream(Priority::PRIO_FATAL); }
232
240std::ostream &Logger::error() { return getLogStream(Priority::PRIO_ERROR); }
241
250std::ostream &Logger::warning() { return getLogStream(Priority::PRIO_WARNING); }
251
260std::ostream &Logger::notice() { return getLogStream(Priority::PRIO_NOTICE); }
261
270std::ostream &Logger::information() { return getLogStream(Priority::PRIO_INFORMATION); }
271
279std::ostream &Logger::debug() { return getLogStream(Priority::PRIO_DEBUG); }
280
285void Logger::accumulate(const std::string &msg) { m_logStream->accumulate(msg); }
286
291
296void Logger::flush(Priority priority) { log(m_logStream->flush(), priority); }
297
299void Logger::flushDebug() { flush(Poco::Message::PRIO_DEBUG); }
300
302void Logger::flushInformation() { flush(Poco::Message::PRIO_INFORMATION); }
303
305void Logger::flushNotice() { flush(Poco::Message::PRIO_NOTICE); }
306
308void Logger::flushWarning() { flush(Poco::Message::PRIO_WARNING); }
309
311void Logger::flushError() { flush(Poco::Message::PRIO_ERROR); }
312
314void Logger::flushFatal() { flush(Poco::Message::PRIO_FATAL); }
315
317void Logger::purge() { m_logStream->flush(); }
318
323 try {
324 // Release the POCO loggers
325 Poco::Logger::shutdown();
326 } catch (std::exception &e) {
327 // failures in logging are not allowed to throw exceptions out of the
328 // logging class
329 std::cerr << e.what();
330 }
331}
332
337void Logger::setLevelForAll(const int level) {
338 const int levelActual = fixLevel(level);
339
340 try {
341 // "" is the root logger
342 Poco::Logger::setLevel("", levelActual);
343 } catch (std::exception &e) {
344 // failures in logging are not allowed to throw exceptions out of the
345 // logging class
346 std::cerr << e.what();
347 }
348}
349
350void Logger::setLevelForAll(const std::string &level) {
351 int intLevel = toLevel(level);
352 setLevelForAll(intLevel);
353}
354
359void Logger::log(const std::string &message, const Logger::Priority &priority) {
360 if (!m_enabled)
361 return;
362
363 try {
364 switch (applyLevelOffset(priority)) {
365 case Poco::Message::PRIO_FATAL:
366 m_log->fatal(message);
367 break;
368 case Poco::Message::PRIO_CRITICAL:
369 m_log->critical(message);
370 break;
371 case Poco::Message::PRIO_ERROR:
372 m_log->error(message);
373 break;
374 case Poco::Message::PRIO_WARNING:
375 m_log->warning(message);
376 break;
377 case Poco::Message::PRIO_NOTICE:
378 m_log->notice(message);
379 break;
380 case Poco::Message::PRIO_INFORMATION:
381 m_log->information(message);
382 break;
383 case Poco::Message::PRIO_DEBUG:
384 m_log->debug(message);
385 break;
386 case Poco::Message::PRIO_TRACE:
387 m_log->trace(message);
388 break;
389 default:
390 break;
391 }
392 } catch (std::exception &e) {
393 // Failures in logging are not allowed to throw exceptions out of the
394 // logging class
395 std::cerr << "Error in logging framework: " << e.what();
396 }
397}
398
404std::ostream &Logger::getLogStream(const Logger::Priority &priority) {
405 if (!m_enabled)
406 return NULL_STREAM;
407
408 switch (applyLevelOffset(priority)) {
409 case Poco::Message::PRIO_FATAL:
410 return m_logStream->fatal();
411 break;
412 case Poco::Message::PRIO_CRITICAL:
413 return m_logStream->critical();
414 break;
415 case Poco::Message::PRIO_ERROR:
416 return m_logStream->error();
417 break;
418 case Poco::Message::PRIO_WARNING:
419 return m_logStream->warning();
420 break;
421 case Poco::Message::PRIO_NOTICE:
422 return m_logStream->notice();
423 break;
424 case Poco::Message::PRIO_INFORMATION:
425 return m_logStream->information();
426 break;
427 case Poco::Message::PRIO_DEBUG:
428 return m_logStream->debug();
429 break;
430 default:
431 return NULL_STREAM;
432 }
433}
434
441 int retVal = proposedLevel;
442 // fast exit if offset is 0
443 if (m_levelOffset == 0) {
444 return proposedLevel;
445 } else {
446 retVal += m_levelOffset;
447 if (retVal < static_cast<int>(Priority::PRIO_FATAL)) {
448 retVal = Priority::PRIO_FATAL;
449 } else if (retVal > static_cast<int>(Priority::PRIO_TRACE)) {
450 retVal = Priority::PRIO_TRACE;
451 }
452 }
453 // Logger::Priority p(retVal);
454 return static_cast<Logger::Priority>(retVal);
455}
456
461void Logger::setLevelOffset(int level) { m_levelOffset = level; }
462
468
469} // namespace Mantid::Kernel
std::string name
Definition Run.cpp:60
The Logger class is in charge of the publishing messages from the framework through various channels.
Definition Logger.h:51
void flushInformation()
flushes the accumulated message with information priority
Definition Logger.cpp:302
void flushFatal()
flushes the accumulated message with fatal priority
Definition Logger.cpp:314
void dump(const std::string &msg, const void *buffer, std::size_t length)
Logs the given message at debug level, followed by the data in buffer.
Definition Logger.cpp:160
void setName(const std::string &name)
Update the name of the logger.
Definition Logger.cpp:69
std::ostream & error()
Logs at error level.
Definition Logger.cpp:240
int getLevelOffset() const
Gets the Logger's log offset level.
Definition Logger.cpp:467
static void setLevelForAll(const int level)
Sets the log level for all Loggers created so far, including the root logger.
Definition Logger.cpp:337
bool m_enabled
The state of this logger, disabled loggers send no messages.
Definition Logger.h:167
static void shutdown()
Shuts down the logging framework and releases all Loggers.
Definition Logger.cpp:322
void flushDebug()
flushes the accumulated message with debug priority
Definition Logger.cpp:299
Priority applyLevelOffset(Priority proposedLevel)
Return a log stream set with the given priority.
Definition Logger.cpp:440
std::string getLevelName() const
Definition Logger.cpp:219
void setEnabled(const bool enabled)
set if the logging is enabled
Definition Logger.cpp:90
void flushError()
flushes the accumulated message with error priority
Definition Logger.cpp:311
bool isDebug() const
Returns true if log level is at least debug.
Definition Logger.cpp:189
Poco::Message::Priority Priority
Definition Logger.h:54
void log(const std::string &message, const Priority &priority)
Log a message at a given priority.
Definition Logger.cpp:359
void setLevel(int level)
Sets the Logger's log level.
Definition Logger.cpp:191
std::ostream & getLogStream(const Priority &priority)
gets the correct log stream for a priority
Definition Logger.cpp:404
Poco::Logger * m_log
Internal handle to third party logging objects.
Definition Logger.h:160
int getLevel() const
Returns the Logger's log level.
Definition Logger.cpp:217
bool getEnabled() const
returns true if the log is enabled
Definition Logger.cpp:83
std::ostream & warning()
Logs at warning level.
Definition Logger.cpp:250
bool is(int level) const
Returns true if at least the given log level is set.
Definition Logger.cpp:177
std::ostream & debug()
Logs at debug level.
Definition Logger.cpp:279
void setLevelOffset(int level)
Sets the Logger's log offset level.
Definition Logger.cpp:461
std::ostream & notice()
Logs at notice level.
Definition Logger.cpp:260
std::ostream & information()
Logs at information level.
Definition Logger.cpp:270
std::unique_ptr< ThreadSafeLogStream > m_logStream
Allows stream operators for a logger.
Definition Logger.h:162
std::ostream & fatal()
Logs at Fatal level.
Definition Logger.cpp:231
static const std::array< std::string, 9 > PriorityNames
Definition Logger.h:56
void purge()
flushes the accumulated messages without logging them
Definition Logger.cpp:317
void flush()
flushes accumulated messages to the current level
Definition Logger.cpp:290
void flushWarning()
flushes the accumulated message with warning priority
Definition Logger.cpp:308
int m_levelOffset
The offset of the logger.
Definition Logger.h:165
void flushNotice()
flushes the accumulated message with notice priority
Definition Logger.cpp:305
void accumulate(const std::string &msg)
accumulates a message
Definition Logger.cpp:285
The main log stream class implementing an ostream interface to a Logger.
void swap(MultiFileValidator &obj1, MultiFileValidator &obj2)
STL namespace.