Belle II Software  release-05-02-19
LogMessage.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2010-2018 Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Andreas Moll, Thomas Kuhr, Thomas Hauth *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 
11 #include <framework/logging/LogMessage.h>
12 
13 #include <framework/utilities/Utils.h>
14 #include <framework/gearbox/Unit.h>
15 #include <framework/pcore/ProcHandler.h>
16 
17 #include <boost/property_tree/json_parser.hpp>
18 #include <ostream>
19 #include <utility>
20 
21 using namespace std;
22 using namespace Belle2;
23 
24 LogMessage::LogMessage(LogConfig::ELogLevel logLevel, const std::string& message, const char* package,
25  std::string function, std::string file, unsigned int line, int debugLevel) :
26  m_logLevel(logLevel),
27  m_message(message),
28  m_module(""),
29  m_package(package ? package : ""),
30  m_function(std::move(function)),
31  m_file(std::move(file)),
32  m_line(line),
33  m_debugLevel(debugLevel),
34  m_logInfo(0)
35 {
36 }
37 
38 LogMessage::LogMessage(LogConfig::ELogLevel logLevel, LogVariableStream&& messageStream, const char* package,
39  std::string function, std::string file, unsigned int line, int debugLevel) :
40  m_logLevel(logLevel),
41  m_message(std::move(messageStream)),
42  m_module(""),
43  m_package(package ? package : ""),
44  m_function(std::move(function)),
45  m_file(std::move(file)),
46  m_line(line),
47  m_debugLevel(debugLevel),
48  m_logInfo(0)
49 {
50 }
51 
52 
53 bool LogMessage::operator==(const LogMessage& message) const
54 {
55  return ((m_logLevel == message.m_logLevel) &&
56  (m_line == message.m_line) &&
57  (m_message == message.m_message) &&
58  (m_module == message.m_module) &&
59  (m_package == message.m_package) &&
60  (m_function == message.m_function) &&
61  (m_file == message.m_file));
62 }
63 
64 std::string LogMessage::toJSON(bool complete) const
65 {
66  using namespace boost::property_tree::json_parser;
67  std::stringstream buffer;
68  static const double startClock = Utils::getClock();
69  double time = (Utils::getClock() - startClock) / Unit::s;
70  int logInfo = (m_logInfo and not complete) ? m_logInfo :
73  // in JSON we always output level, independent of what the log info says, otherwise it is hard to parse
74  buffer << R"({"level":")" << LogConfig::logLevelToString(m_logLevel) << '"';
75  if (logInfo & LogConfig::c_Message) {
76  buffer << R"(,"message":")" << create_escapes(m_message.getMessage()) << '"';
77  const auto& vars = m_message.getVariables();
78  if ((vars.size() > 0 or complete) and !(logInfo & LogConfig::c_NoVariables)) {
79  buffer << ",\"variables\":{";
80  bool first{true};
81  for (const auto& v : vars) {
82  if (!first) buffer << ",";
83  buffer << '"' << create_escapes(v.getName()) << "\":\"" << create_escapes(v.getValue()) << '"';
84  first = false;
85  }
86  buffer << '}';
87  }
88  }
89  if (logInfo & LogConfig::c_Module)
90  buffer << R"(,"module":")" << create_escapes(m_module) << '"';
91  if (logInfo & LogConfig::c_Package)
92  buffer << R"(,"package":")" << create_escapes(m_package) << '"';
93  if (logInfo & LogConfig::c_Function)
94  buffer << R"(,"function":")" << create_escapes(m_function) << '"';
95  if (logInfo & LogConfig::c_File)
96  buffer << R"(,"file":")" << create_escapes(m_file) << '"';
97  if (logInfo & LogConfig::c_Line)
98  buffer << ",\"line\":" << m_line;
99  if (logInfo & LogConfig::c_Timestamp)
100  buffer << ",\"timestamp\":" << std::fixed << std::setprecision(3) << time;
101  if (ProcHandler::EvtProcID() != -1 or complete)
102  buffer << ",\"proc\":" << ProcHandler::EvtProcID();
103  //variables ...
104  buffer << "}\n";
105  return buffer.str();
106 }
107 
108 std::ostream& LogMessage::print(std::ostream& out) const
109 {
110  int logInfo = m_logInfo ? m_logInfo :
113  if (logInfo & LogConfig::c_Timestamp) {
114  static const double startClock = Utils::getClock();
115  const auto flags = out.flags();
116  const int oldprecision = out.precision(3);
117  out << std::fixed << (Utils::getClock() - startClock) / Unit::s << ": ";
118  out.precision(oldprecision);
119  out.flags(flags);
120  }
121  if (logInfo & LogConfig::c_Level) {
122  const std::string debugLevel = (m_logLevel == LogConfig::c_Debug) ? (":" + std::to_string(m_debugLevel)) : "";
123  out << "[" << LogConfig::logLevelToString(m_logLevel) << debugLevel << "] ";
124  }
125  if (ProcHandler::EvtProcID() != -1) {
126  //which process is this?
127  out << "(" << ProcHandler::EvtProcID() << ") ";
128  }
129  if (logInfo & LogConfig::c_Message) {
130  out << m_message.str(!(logInfo & LogConfig::c_NoVariables));
131  }
132  // if there is no module or package or similar there's no need to print them
133  if (m_module.empty()) logInfo &= ~LogConfig::c_Module;
134  if (m_package.empty()) logInfo &= ~LogConfig::c_Package;
135  if (m_function.empty()) logInfo &= ~LogConfig::c_Function;
136  // line number without filename is useless as well so disable both in one go
137  if (m_file.empty()) logInfo &= ~(LogConfig::c_File | LogConfig::c_Line);
138  // is there any location string left to print?
139  bool printLocation = logInfo & (LogConfig::c_Module | LogConfig::c_Package | LogConfig::c_Function |
141  if (printLocation) {
142  out << " {";
143  }
144  if (logInfo & LogConfig::c_Module) {
145  out << " module: " << m_module;
146  }
147  if (logInfo & LogConfig::c_Package) {
148  out << " package: " << m_package;
149  }
150  if (logInfo & LogConfig::c_Function) {
151  out << " function: " << m_function;
152  }
153  if (logInfo & LogConfig::c_File) {
154  out << " @" << m_file;
155  }
156  if (logInfo & LogConfig::c_Line) {
157  out << ":" << m_line;
158  }
159  if (printLocation) {
160  out << " }";
161  }
162  out << endl;
163  return out;
164 }
165 
166 
167 ostream& operator<< (ostream& out, const LogMessage& logMessage)
168 {
169  return logMessage.print(out);
170 }
Belle2::Unit::s
static const double s
[second]
Definition: Unit.h:105
LogVariableStream::getMessage
std::string getMessage() const
Return the constant message part without the variables.
Definition: LogVariableStream.h:207
Belle2::operator<<
std::ostream & operator<<(std::ostream &output, const IntervalOfValidity &iov)
Definition: IntervalOfValidity.cc:196
LogVariableStream
Specialized implementation of an ostream-like class where the << operator can be used to insert value...
Definition: LogVariableStream.h:87
Belle2::LogMessage::m_debugLevel
int m_debugLevel
The debug level for messages with level=c_Debug.
Definition: LogMessage.h:168
Belle2::LogConfig::logLevelToString
static const char * logLevelToString(ELogLevel logLevelType)
Converts a log level type to a string.
Definition: LogConfig.cc:44
Belle2::LogMessage::m_message
LogVariableStream m_message
The message stream which should be sent.
Definition: LogMessage.h:162
Belle2::LogConfig::c_NoVariables
@ c_NoVariables
If set don't output any variables that are part of the message.
Definition: LogConfig.h:54
Belle2::LogMessage::operator==
bool operator==(const LogMessage &message) const
Compares two messages.
Definition: LogMessage.cc:53
Belle2::LogMessage::m_package
std::string m_package
The package name where the message was sent from.
Definition: LogMessage.h:164
Belle2::LogConfig::c_File
@ c_File
Source file in which the message was emitted.
Definition: LogConfig.h:51
LogVariableStream::str
std::string str(bool showVariables=true) const
Return the content of the stream as string.
Definition: LogVariableStream.h:189
Belle2::LogConfig::ELogLevel
ELogLevel
Definition of the supported log levels.
Definition: LogConfig.h:36
Belle2::LogMessage::LogMessage
LogMessage(LogConfig::ELogLevel logLevel, const std::string &message, const char *package, std::string function, std::string file, unsigned int line, int debugLevel=0)
The LogMessage constructor.
Definition: LogMessage.cc:24
Belle2::LogConfig::c_Package
@ c_Package
Package in which the message was emitted.
Definition: LogConfig.h:49
Belle2::LogConfig::c_Line
@ c_Line
Line in source file in which the message was emitted.
Definition: LogConfig.h:52
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::LogMessage::m_logInfo
unsigned int m_logInfo
kind of information to show (ORed combination of LogConfig::ELogInfo flags).
Definition: LogMessage.h:170
Belle2::LogConfig::c_Level
@ c_Level
Log level of the message.
Definition: LogConfig.h:46
Belle2::LogMessage::m_function
std::string m_function
The function name where the message was sent from.
Definition: LogMessage.h:165
LogVariableStream::getVariables
const std::vector< LogVar > & getVariables() const
Return the list of all defined variables.
Definition: LogVariableStream.h:213
Belle2::LogMessage::m_logLevel
LogConfig::ELogLevel m_logLevel
The log level of the message.
Definition: LogMessage.h:161
Belle2::LogMessage::m_module
std::string m_module
The module name where the message was sent from.
Definition: LogMessage.h:163
Belle2::ProcHandler::EvtProcID
static int EvtProcID()
Return ID of the current process.
Definition: ProcHandler.cc:243
Belle2::LogMessage::toJSON
std::string toJSON(bool complete) const
Return a json string for the log message.
Definition: LogMessage.cc:64
Belle2::LogConfig::c_Function
@ c_Function
Function in which the message was emitted.
Definition: LogConfig.h:50
Belle2::Utils::getClock
double getClock()
Return current value of the real-time clock.
Definition: Utils.cc:58
Belle2::LogConfig::c_Message
@ c_Message
Log message text.
Definition: LogConfig.h:47
Belle2::LogConfig::c_Debug
@ c_Debug
Debug: for code development.
Definition: LogConfig.h:36
Belle2::LogMessage::m_file
std::string m_file
The file name where the message was sent from.
Definition: LogMessage.h:166
Belle2::LogConfig
The LogConfig class.
Definition: LogConfig.h:32
Belle2::LogMessage
The LogMessage class.
Definition: LogMessage.h:39
Belle2::LogMessage::m_line
unsigned int m_line
The line number in the source code where the message was sent from.
Definition: LogMessage.h:167
Belle2::LogConfig::c_Timestamp
@ c_Timestamp
Time at which the message was emitted.
Definition: LogConfig.h:53
Belle2::LogMessage::print
std::ostream & print(std::ostream &out) const
Generate output stream.
Definition: LogMessage.cc:108
Belle2::LogConfig::c_Module
@ c_Module
Module in which the message was emitted.
Definition: LogConfig.h:48