ChimeraTK-ApplicationCore 04.06.00
Loading...
Searching...
No Matches
Logger.cc
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
2// SPDX-License-Identifier: LGPL-3.0-or-later
3#include "Logger.h"
4
5#include <iostream>
6
7namespace ChimeraTK {
8
9 /********************************************************************************************************************/
10
12 if(_mainLoopThread.joinable()) {
13 retry:
14 try {
15 _mainLoopThread.interrupt();
16
17 // try joining the thread
18 do {
19 // it may not suffice to send interrupt() once, as the exception might get
20 // overwritten in the queue, thus we repeat this until the thread was
21 // joined.
22 _messageQueue.push_exception(std::make_exception_ptr(boost::thread_interrupted()));
23 } while(!_mainLoopThread.try_join_for(boost::chrono::milliseconds(10)));
24 }
25 catch(boost::thread_interrupted&) {
26 // ignore interruptions at this point
27 goto retry;
28 }
29 catch(std::system_error& e) {
30 std::cerr << "std::system_error caught: " << e.what() << std::endl;
31 std::terminate();
32 }
33 catch(...) {
34 std::cerr << "unknown exception caught." << std::endl;
35 std::terminate();
36 }
37 }
38 assert(!_mainLoopThread.joinable());
39 }
40
41 /********************************************************************************************************************/
42
44 return {this, severity, std::move(context)};
45 }
46
47 /********************************************************************************************************************/
48
49 Logger::StreamProxy::StreamProxy(Logger* logger, Severity severity, std::string context)
50 : std::ostream(severity >= logger->_minSeverity ? &_buf : nullptr), _severity(severity), _context(std::move(context)),
51 _logger(*logger) {}
52
53 /********************************************************************************************************************/
54
56 // Send out the log message
57 _logger.log(_severity, std::move(_context), _buf.str());
58 }
59
60 /********************************************************************************************************************/
61
62 void Logger::log(Logger::Severity severity, std::string context, std::string message) noexcept {
63 try {
64 _messageQueue.push({severity, std::move(context), std::move(message)});
65 }
66 catch(std::system_error& e) {
67 std::cerr << "std::system_error caught: " << e.what() << std::endl;
68 std::terminate();
69 }
70 }
71
72 /********************************************************************************************************************/
73
74 std::string Logger::severityToString(Severity severity) {
75 switch(severity) {
77 return "t";
79 return "d";
81 return "i";
83 return "W";
85 return "E";
86 }
87 return "?";
88 }
89
90 /********************************************************************************************************************/
91
92 void Logger::mainLoop() {
93 while(true) {
94 LogMessage message;
95 _messageQueue.pop_wait(message);
96
97 auto* stream = &std::cout;
98 if(message.severity >= Severity::warning) {
99 stream = &std::cerr;
100 }
101
102 // Prefix with time stamp, source and severity. This format matches the DOOCS format (except that we added the
103 // severity).
104 auto t = std::time(nullptr);
105 auto tm = *std::localtime(&t);
106 std::stringstream prefix;
107 prefix.setf(std::ios::left, std::ios::adjustfield);
108 prefix << std::put_time(&tm, "%Y-%m-%dT%H:%M:%S") << " " << std::setw(20) << message.context.substr(0, 20) << " ["
109 << severityToString(message.severity) << "] ";
110
111 // print text line by line with prefix to stream
112 std::stringstream ss(message.text);
113 std::string line;
114 while(std::getline(ss, line, '\n')) {
115 *stream << prefix.str() << line << "\n";
116 }
117 *stream << std::flush;
118 }
119 }
120
121 /********************************************************************************************************************/
122
123} // namespace ChimeraTK
Proxy for output stream, handed out to the log sources by the Logger::Module.
Definition Logger.h:39
StreamProxy(Logger *logger, Severity severity, std::string context)
Definition Logger.cc:49
Severity
Severity levels used by the Logger.
Definition Logger.h:27
StreamProxy getStream(Severity severity, std::string context)
Return an output stream object for the given severity.
Definition Logger.cc:43
InvalidityTracer application module.
Logger::StreamProxy logger(Logger::Severity severity, std::string context)
Convenience function to obtain the logger stream.
Definition Logger.h:124