ChimeraTK-ApplicationCore 04.08.00
Loading...
Searching...
No Matches
Logger.h
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#pragma once
4
5#include <ChimeraTK/cppext/future_queue.hpp>
6
7#include <boost/algorithm/string.hpp>
8#include <boost/thread.hpp>
9
10#include <expected>
11#include <sstream>
12
13namespace ChimeraTK {
14
15 /********************************************************************************************************************/
16
17 class Logger {
18 public:
22 static Logger& getInstance();
23
29 class Severity {
30 public:
32
33 // NOLINTNEXTLINE(google-explicit-constructor)
34 constexpr Severity(const Value& value) : _value(value) {}
35
36 // NOLINTNEXTLINE(google-explicit-constructor)
37 [[nodiscard]] constexpr operator Value() { return _value; }
38
40 [[nodiscard]] constexpr std::string_view toString() const;
41
42 [[nodiscard]] constexpr auto operator<=>(const Severity& other) const = default;
43 [[nodiscard]] constexpr auto operator<=>(const Severity::Value& other) const { return _value <=> other; }
44
49 constexpr static std::expected<Logger::Severity, std::string> fromString(const std::string& string);
50
51 private:
52 Value _value;
53 };
54
60 void setMinSeverity(Severity minSeverity) { _minSeverity = minSeverity; }
61
65 class StreamProxy : public std::ostream {
66 public:
67 StreamProxy(Logger* logger, Severity severity, std::string context);
68 ~StreamProxy() override;
69
70 private:
71 std::stringbuf _buf;
72 Severity _severity;
73 std::string _context;
74 Logger& _logger;
75 };
76
95 StreamProxy getStream(Severity severity, std::string context);
96
97 ~Logger();
98
99 private:
100 Logger() = default;
101
107 static std::shared_ptr<Logger>& getSharedPtr();
108
115 void log(Severity severity, std::string context, std::string message) noexcept;
116
117 // The mainLoop() is executed in a dedicated thread waits for incoming log messages and prints them
118 void mainLoop();
119
120 // Convert Severity to string
121 static std::string severityToString(Severity severity);
122
123 // Struct with all arguments of log(), to be placed on to the _messageQueue
124 struct LogMessage {
125 Severity severity{Severity::info};
126 std::string context;
127 std::string text;
128 };
129
130 // This queue is filled in log() and read in mainLoop()
131 cppext::future_queue<LogMessage> _messageQueue{10};
132
133 // Minimum severity to be sent to the queue. This allows filtering lower severity messages at sender side, even
134 // before the message text has been (fully) composed.
135 std::atomic<Severity> _minSeverity{defaultSeverityFromEnv()};
136
137 // Thread executing mainLoop().
138 // Note: The thread must be started only after all other data members have been initialised, so this line must
139 // come last (or the thread must be only started in the constructor body).
140 boost::thread _mainLoopThread{[this] { mainLoop(); }};
141
146 static Severity defaultSeverityFromEnv();
147
148 friend class Application;
149 };
150
151 /********************************************************************************************************************/
152
156 inline Logger::StreamProxy logger(Logger::Severity severity, std::string context) {
157 return Logger::getInstance().getStream(severity, std::move(context));
158 }
159
160 /********************************************************************************************************************/
161
163 return *getSharedPtr();
164 }
165
166 /********************************************************************************************************************/
167
168 inline std::shared_ptr<Logger>& Logger::getSharedPtr() {
169 static std::shared_ptr<Logger> instance(new Logger());
170 return instance;
171 }
172
173 /********************************************************************************************************************/
174 /********************************************************************************************************************/
175
176 constexpr std::string_view Logger::Severity::toString() const {
177 switch(_value) {
178 case trace:
179 return "trace";
180 case debug:
181 return "debug";
182 case info:
183 return "info";
184 case warning:
185 return "warning";
186 case error:
187 return "error";
188 }
189 std::unreachable();
190 }
191
192 /********************************************************************************************************************/
193
194 constexpr std::expected<Logger::Severity, std::string> Logger::Severity::fromString(const std::string& string) {
195 auto stringLower = boost::algorithm::to_lower_copy(std::string(string));
196 if(stringLower == "trace") {
197 return trace;
198 }
199 if(stringLower == "debug") {
200 return debug;
201 }
202 if(stringLower == "info") {
203 return info;
204 }
205 if(stringLower == "warning") {
206 return warning;
207 }
208 if(stringLower == "error") {
209 return error;
210 }
211 return std::unexpected("Valid values are: trace, debug, info, warning, error.");
212 }
213
214 /********************************************************************************************************************/
215
216} // namespace ChimeraTK
Severity levels used by the Logger.
Definition Logger.h:29
static constexpr std::expected< Logger::Severity, std::string > fromString(const std::string &string)
Set Severity from string.
Definition Logger.h:194
constexpr auto operator<=>(const Severity::Value &other) const
Definition Logger.h:43
constexpr std::string_view toString() const
Convert Severity into string.
Definition Logger.h:176
constexpr Severity(const Value &value)
Definition Logger.h:34
constexpr auto operator<=>(const Severity &other) const =default
Proxy for output stream, handed out to the log sources by the Logger::Module.
Definition Logger.h:65
void setMinSeverity(Severity minSeverity)
Set the minimum severity level to be passed to the logger.
Definition Logger.h:60
StreamProxy getStream(Severity severity, std::string context)
Return an output stream object for the given severity.
Definition Logger.cc:64
static Logger & getInstance()
Obtain global instance of Logger singleton.
Definition Logger.h:162
InvalidityTracer application module.
Logger::StreamProxy logger(Logger::Severity severity, std::string context)
Convenience function to obtain the logger stream.
Definition Logger.h:156