Belle II Software  release-08-01-10
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 
24 class LogVar {
25 public:
32  template<class TVarType>
33  LogVar(const std::string& name, const TVarType& v) :
34  m_name(name),
35  m_value(boost::lexical_cast<std::string>(v))
36  {
37  }
38 
42  std::string getValue() const
43  {
44  return m_value;
45  }
46 
50  std::string getName() const
51  {
52  return m_name;
53  }
54 
58  bool operator==(const LogVar& lv) const
59  {
60  return (lv.m_name == this->m_name) && (lv.m_value == this->m_value);
61  }
62 
63 private:
66  std::string m_name;
67 
70  std::string m_value;
71 };
72 
76 class LogModRealm {
77 public:
84  m_realm(realm),
85  m_logLevel(logLevel)
86  {
87  }
88 
93  {
94  return m_realm;
95  }
96 
101  {
102  return m_logLevel;
103  }
104 
105 private:
108 
111 };
112 
128 public:
129 
131  typedef std::basic_ostream<std::stringstream::char_type, std::stringstream::traits_type > __basic_ostream_type;
132 
134  LogVariableStream() = default;
135 
140 
145  {
146  // copy manually because stringstream has no copy-constructor
147  m_stringStream << other.m_stringStream.str();
148  }
149 
154  explicit LogVariableStream(std::string const& text, std::map<std::string, std::string> variables = {})
155  {
156  m_stringStream << text;
157  for (auto const& kv : variables) {
158  m_variables.emplace_back(LogVar(kv.first, kv.second));
159  }
160  }
161 
166  // cppcheck-suppress constParameter ; no, this cannot be const otherwise e.g. std::endl doesn't work
168  {
169  // execute provided function on the string stream
170  __pf(m_stringStream);
171  return *this;
172  }
173 
179  {
180  m_variables.push_back(var);
181  return *this;
182  }
183 
188 
193  template<class TText>
194  typename std::enable_if<not std::is_fundamental<TText>::value, LogVariableStream&>::type operator<<(TText const& text)
195  {
196  this->m_stringStream << text;
197  return *this;
198  }
199 
205  template<class PODTYPE>
206  typename std::enable_if<std::is_fundamental<PODTYPE>::value, LogVariableStream&>::type operator<<(PODTYPE pod)
207  {
208  this->m_stringStream << pod;
209  return *this;
210  }
211 
215  bool operator==(const LogVariableStream& lvs) const
216  {
217  return (lvs.m_variables == this->m_variables) && (lvs.m_stringStream.str() == this->m_stringStream.str());
218  }
219 
224  {
225  this->m_stringStream = std::stringstream();
226  this->m_stringStream << lvs.m_stringStream.str();
227  this->m_variables = lvs.m_variables;
228  return *this;
229  }
230 
235  std::string str(bool showVariables = true) const
236  {
237  // little optimization, so we don't need to copy the whole string
238  // in the cases where there are no variables ...
239  if (m_variables.size() == 0 or !showVariables) {
240  return m_stringStream.str();
241  }
242 
243  std::stringstream tmpBuffer;
244  // put the string first
245  tmpBuffer << m_stringStream.str();
246  for (auto const& v : m_variables) {
247  tmpBuffer << std::endl << "\t" << v.getName() << " = " << v.getValue();
248  }
249  return tmpBuffer.str();
250  }
251 
253  std::string getMessage() const
254  {
255  return m_stringStream.str();
256  }
257 
259  const std::vector<LogVar>& getVariables() const
260  {
261  return m_variables;
262  }
263 
266  {
268  logLevel = m_logLevelOverride;
269  }
270  }
271 
272 private:
273 
275  std::stringstream m_stringStream;
276 
278  std::vector<LogVar> m_variables;
279 
282 };
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...
LogVariableStream & operator<<(LogVar const &var)
Operator override which stores the LogVar information instead of putting it directly in the sstream.
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.
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.
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 & operator<<(__basic_ostream_type &(*__pf)(__basic_ostream_type &))
operator override for ostream modifier functions like std::endl who are directly applied to the under...
const std::vector< LogVar > & getVariables() const
Return the list of all defined variables.
LogVariableStream()=default
Default constructor with empty text and no variables.
std::string str(bool showVariables=true) const
Return the content of the stream as string.
bool operator==(const LogVariableStream &lvs) const
Custom comparison operator.
std::enable_if< not std::is_fundamental< TText >::value, LogVariableStream & >::type operator<<(TText const &text)
Templated operator which will be used for all non-fundamental types.