Belle II Software development
LogVariableStream.h
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#pragma once
10
11#include <framework/logging/LogConfig.h>
12
13#include <sstream>
14#include <vector>
15#include <string>
16#include <map>
17#include <type_traits>
18#include <boost/lexical_cast.hpp>
19
24class LogVar {
25public:
32 template<class TVarType>
33 LogVar(const std::string& name, const TVarType& v) : m_name(name)
34 {
35 if constexpr(std::is_enum_v<TVarType>) {
36 // Convert an enum to its underlying integer type (int, short, etc.).
37 // This avoids problematic boost::is_signed checks on the enum itself.
38 auto underlying_value = static_cast<typename std::underlying_type_t<TVarType>>(v);
39 m_value = std::to_string(underlying_value);
40 } else {
41 m_value = boost::lexical_cast<std::string>(v);
42 }
43 }
44
48 std::string getValue() const
49 {
50 return m_value;
51 }
52
56 std::string getName() const
57 {
58 return m_name;
59 }
60
64 bool operator==(const LogVar& lv) const
65 {
66 return (lv.m_name == this->m_name) && (lv.m_value == this->m_value);
67 }
68
69private:
72 std::string m_name;
73
76 std::string m_value;
77};
78
118
134public:
135
137 typedef std::basic_ostream<std::stringstream::char_type, std::stringstream::traits_type > __basic_ostream_type;
138
140 LogVariableStream() = default;
141
146
151 {
152 // copy manually because stringstream has no copy-constructor
153 m_stringStream << other.m_stringStream.str();
154 }
155
160 explicit LogVariableStream(std::string const& text, std::map<std::string, std::string> variables = {})
161 {
162 m_stringStream << text;
163 for (auto const& kv : variables) {
164 m_variables.emplace_back(LogVar(kv.first, kv.second));
165 }
166 }
167
172 // cppcheck-suppress constParameter ; no, this cannot be const otherwise e.g. std::endl doesn't work
174 {
175 // execute provided function on the string stream
176 __pf(m_stringStream);
177 return *this;
178 }
179
185 {
186 m_variables.push_back(var);
187 return *this;
188 }
189
194
199 template<class TText>
200 typename std::enable_if<not std::is_fundamental<TText>::value, LogVariableStream&>::type operator<<(TText const& text)
201 {
202 this->m_stringStream << text;
203 return *this;
204 }
205
211 template<class PODTYPE>
212 typename std::enable_if<std::is_fundamental<PODTYPE>::value, LogVariableStream&>::type operator<<(PODTYPE pod)
213 {
214 this->m_stringStream << pod;
215 return *this;
216 }
217
221 bool operator==(const LogVariableStream& lvs) const
222 {
223 return (lvs.m_variables == this->m_variables) && (lvs.m_stringStream.str() == this->m_stringStream.str());
224 }
225
230 {
231 this->m_stringStream = std::stringstream();
232 this->m_stringStream << lvs.m_stringStream.str();
233 this->m_variables = lvs.m_variables;
234 return *this;
235 }
236
241 std::string str(bool showVariables = true) const
242 {
243 // little optimization, so we don't need to copy the whole string
244 // in the cases where there are no variables ...
245 if (m_variables.size() == 0 or !showVariables) {
246 return m_stringStream.str();
247 }
248
249 std::stringstream tmpBuffer;
250 // put the string first
251 tmpBuffer << m_stringStream.str();
252 for (auto const& v : m_variables) {
253 tmpBuffer << std::endl << "\t" << v.getName() << " = " << v.getValue();
254 }
255 return tmpBuffer.str();
256 }
257
259 std::string getMessage() const
260 {
261 return m_stringStream.str();
262 }
263
265 const std::vector<LogVar>& getVariables() const
266 {
267 return m_variables;
268 }
269
272 {
274 logLevel = m_logLevelOverride;
275 }
276 }
277
278private:
279
281 std::stringstream m_stringStream;
282
284 std::vector<LogVar> m_variables;
285
288};
ELogLevel
Definition of the supported log levels.
Definition LogConfig.h:26
@ c_Default
Default: use globally configured log level.
Definition LogConfig.h:32
ELogRealm
Definition of the supported execution realms.
Definition LogConfig.h:48
Class to modify the log level dependent on the execution realm.
Belle2::LogConfig::ELogLevel getLogLevel() const
Returns the log level.
Belle2::LogConfig::ELogRealm m_realm
Realm for the conditional log level.
Belle2::LogConfig::ELogRealm getRealm() const
Returns the realm.
LogModRealm(Belle2::LogConfig::ELogRealm realm, Belle2::LogConfig::ELogLevel logLevel)
Constructor of a realm dependent modification of the log level.
Belle2::LogConfig::ELogLevel m_logLevel
Realm dependent log level.
Class to store variables with their name which were sent to the logging service.
std::string getValue() const
Returns the value stored for this variable.
LogVar(const std::string &name, const TVarType &v)
Constructor which accepts any type as value and relies on boost lexical cast.
bool operator==(const LogVar &lv) const
Custom comparison operator.
std::string getName() const
Returns the name stored for this variable.
std::string m_value
String conversion of the value.
std::string m_name
Stores the name of the variable.
Specialized implementation of an ostream-like class where the << operator can be used to insert value...
const std::vector< LogVar > & getVariables() const
Return the list of all defined variables.
std::string getMessage() const
Return the constant message part without the variables.
LogVariableStream(std::string const &text, std::map< std::string, std::string > variables={})
Constructor which sets an initial text for this stream.
Belle2::LogConfig::ELogLevel m_logLevelOverride
Adjusted log level.
std::vector< LogVar > m_variables
List of LogVars which were accepted so far.
LogVariableStream(LogVariableStream &&)=default
Provide default move constructor.
LogVariableStream & operator<<(__basic_ostream_type &(*__pf)(__basic_ostream_type &))
operator override for ostream modifier functions like std::endl who are directly applied to the under...
LogVariableStream & operator<<(LogVar const &var)
Operator override which stores the LogVar information instead of putting it directly in the sstream.
LogVariableStream(const LogVariableStream &other)
Implement custom copy-constructor, because stringstream's one is deleted.
void adjustLogLevel(Belle2::LogConfig::ELogLevel &logLevel) const
Adjust the log level in case of a realm dependent modification.
std::stringstream m_stringStream
All non-LogVar items are directly forwarded to this stringstream.
std::basic_ostream< std::stringstream::char_type, std::stringstream::traits_type > __basic_ostream_type
basic_ofstream which is used with ostream's utility functions
LogVariableStream()=default
Default constructor with empty text and no variables.
std::enable_if< std::is_fundamental< PODTYPE >::value, LogVariableStream & >::type operator<<(PODTYPE pod)
Templated operator which will be used for POD types (especially integers) and uses by-value.
LogVariableStream & operator=(const LogVariableStream &lvs)
Custom assignment-operator, thanks to stringsream's non-copy policy.
std::enable_if< notstd::is_fundamental< TText >::value, LogVariableStream & >::type operator<<(TText const &text)
Templated operator which will be used for all non-fundamental types.
std::string str(bool showVariables=true) const
Return the content of the stream as string.
bool operator==(const LogVariableStream &lvs) const
Custom comparison operator.