IssueLogger.cpp
Go to the documentation of this file.
1 #include "IssueLogger.h"
2 
6 #include "GaudiKernel/System.h"
7 #include "GaudiKernel/Time.h"
8 
9 #include <algorithm>
10 namespace {
11 
12  std::string getTraceBack() {
13  std::string stack;
14  constexpr int depth = 30;
15  constexpr int offset = 5;
16  System::backTrace(stack, depth, offset);
17  return stack;
18  }
19 
20  static const std::map<IssueSeverity::Level, MSG::Level> s_sevMsgMap =
33 
34  static const std::map<IssueSeverity::Level, std::string> s_levelTrans =
35  { { IssueSeverity::VERBOSE, "VERBOSE" },
36  { IssueSeverity::DEBUG, "DEBUG" },
37  { IssueSeverity::DEBUG1, "DEBUG1" },
38  { IssueSeverity::DEBUG2, "DEBUG2" },
39  { IssueSeverity::DEBUG3, "DEBUG3" },
40  { IssueSeverity::INFO, "INFO" },
41  { IssueSeverity::WARNING, "WARNING" },
42  { IssueSeverity::RECOVERABLE, "RECOVERABLE" },
43  { IssueSeverity::ERROR, "ERROR" },
44  { IssueSeverity::FATAL, "FATAL" },
45  { IssueSeverity::ALWAYS, "ALWAYS" } };
46 
47  static const std::map<std::string, IssueSeverity::Level> s_levelSTrans =
48  { { "VERBOSE", IssueSeverity::VERBOSE },
49  { "DEBUG", IssueSeverity::DEBUG },
50  { "DEBUG1", IssueSeverity::DEBUG1 },
51  { "DEBUG2", IssueSeverity::DEBUG2 },
52  { "DEBUG3", IssueSeverity::DEBUG3 },
53  { "INFO", IssueSeverity::INFO },
54  { "WARNING", IssueSeverity::WARNING },
55  { "RECOVERABLE", IssueSeverity::RECOVERABLE },
56  { "ERROR", IssueSeverity::ERROR },
57  { "FATAL", IssueSeverity::FATAL },
58  { "ALWAYS", IssueSeverity::ALWAYS } };
59 }
60 
62 
63 //*************************************************************************//
64 inline void toupper(std::string &s)
65 {
66  std::transform(s.begin(), s.end(), s.begin(),
67  (int(*)(int)) toupper);
68 }
69 
70 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
71 
73  : base_class(name, svc) {
74 
75  declareProperty ("Output", m_outputfile );
76  declareProperty ("ReportLevel", m_reportLevelS="WARNING");
77  declareProperty ("TracebackLevel", m_traceLevelS="ERROR");
78  declareProperty ("ShowTime", m_showTime=false);
79 
83 
86 
87 }
88 
89 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
90 
93 
95  if (st.isSuccess()) { setupDefaultLogger(); }
96  return st;
97 }
98 
99 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
100 
103 
104  warning() << "reinitialize not implemented" << endmsg;
105  return StatusCode::SUCCESS;
106 
107 }
108 
109 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
110 
113 
114  debug() << "IssueLogger::finalize" << endmsg;
116  [](logger_t& i)
117  { i.reset(); } );
118  return Service::finalize();
119 }
120 
121 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
122 
125 
126  auto loc = ident.find(" ");
127  using Parser = Gaudi::Utils::AttribStringParser;
128  // note: if loc == string::npos then loc + 1 == 0
129  for (auto attrib: Parser(ident.substr(loc + 1))) {
130  toupper(attrib.tag);
132  if (attrib.tag == "DEBUG") { level = IssueSeverity::DEBUG;
133  } else if ( attrib.tag == "INFO") { level = IssueSeverity::INFO;
134  } else if ( attrib.tag == "WARNING") { level = IssueSeverity::WARNING;
135  } else if ( attrib.tag == "RECOVERABLE") { level = IssueSeverity::RECOVERABLE;
136  } else if ( attrib.tag == "ERROR") { level = IssueSeverity::ERROR;
137  } else if ( attrib.tag == "FATAL") { level = IssueSeverity::FATAL;
138  } else {
139  error() << "Unknown output level \"" << attrib.tag << "\""
140  << endmsg;
141  continue;
142  }
143 
144  if (m_log[level]) {
145  info() << "closing stream " << m_log[level].name() << endmsg;
146  m_log[level].reset();
147  }
148 
149  if (attrib.value == "MsgSvc") {
150  m_log[level] = { new StreamLogger(msgSvc(), s_sevMsgMap.at(level)) , &StreamLogger::WriteToMsgSvc };
151  } else if (attrib.value == "STDERR") {
153  } else if (attrib.value == "STDOUT") {
155  } else { // A file
156  try {
157  m_log[level] = { new StreamLogger(attrib.value), &StreamLogger::WriteToStream };
158  }
159  catch (std::exception&) {
160  m_log[level].reset();
161  error() << "Unable to open file \"" << attrib.value
162  << "\" for writing issues at level " << attrib.tag << endmsg;
163  return StatusCode::FAILURE;
164  }
165  }
166  debug() << "Writing " << s_levelTrans.at(level)
167  << " issues to " << m_log[level].name() << endmsg;
168  }
169  return StatusCode::SUCCESS;
170 }
171 
172 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
173 
174 void
176  const std::string& org) {
177  if ( lev < m_reportLevel) return;
178  std::string msg = s_levelTrans.at(lev) + " " + org + " \"" + str + "\"";
179  if (m_showTime) msg += " [" + Gaudi::Time::current().format(true, "%H:%M:%S %Y/%m/%d %Z") +"]";
180  if (lev >= m_traceLevel) msg += "\n" + getTraceBack();
181  m_log[lev](msg);
182 }
183 
184 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
185 
186 void
188  report(err.getLevel(), err.getMsg(), err.getOrigin());
189 }
190 
191 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
192 
193 void
195 
196  StringProperty *sap = dynamic_cast<StringProperty*> (&prop);
197  if (!sap) {
198  error() << "Could not convert " << prop.name()
199  << "to a StringProperty (which it should be!)" << endmsg;
200  return;
201  }
202 
203  const std::string& val = sap->value();
204  auto set = [&](IssueSeverity::Level& key, IssueSeverity::Level def) {
205  if (s_levelSTrans.find(val) == s_levelSTrans.end()) {
206  key = def;
207  error() << "Option " << prop.name() << ": unknown Issue Severity level \""
208  << val << "\". Setting it " << s_levelTrans.at(def) << endmsg;
209  } else {
210  key = s_levelSTrans.at(val);
211  }
212  };
213 
214  if (prop.name() == "ReportLevel") {
216  } else if (prop.name() == "TracebackLevel") {
218  } else {
219  error() << "setting up unknown property \""
220  << prop.name() << "\"" << endmsg;
221  }
222 }
223 
224 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
225 
226 void
228 
229  StringArrayProperty *sap = dynamic_cast<StringArrayProperty*>( &prop );
230  if ( !sap ) {
231  error() << "Could not convert " << prop.name()
232  << "to a StringArrayProperty (which it should be!)" << endmsg;
233  return;
234  }
235  for (const auto& s : sap->value() ) {
236  if (connect(s).isFailure()) {
237  error() << "Could not setup stream " << s << endmsg;
238  }
239  }
240 }
241 
242 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
243 
244 void
246  for (int i=1; i<IssueSeverity::NUM_LEVELS; ++i) {
247  if (!m_log[i]) {
248  // default: dump to msgSvc
250  m_log[j] = { new StreamLogger(msgSvc(), s_sevMsgMap.at(j)) , &StreamLogger::WriteToMsgSvc };
251  debug() << "Writing " << s_levelTrans.at(j)
252  << " issues to " << m_log[j].name() << endmsg;
253  }
254  }
255 }
Parse attribute strings allowing iteration over the various attributes.
StatusCode initialize() override
Definition: Service.cpp:68
MsgStream & msg() const
shortcut for the method msgStream(MSG::INFO)
StatusCode connect(const std::string &)
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:25
StatusCode finalize() override
Definition: Service.cpp:193
std::string getOrigin() const
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
virtual Property & declareUpdateHandler(std::function< void(Property &)> fun)
set new callback for update
Definition: Property.cpp:72
const std::string & name() const
property name
Definition: Property.h:45
StatusCode finalize() override
void toupper(std::string &s)
Definition: IssueLogger.cpp:64
static Time current(void)
Returns the current time.
Definition: Time.cpp:113
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:76
StringArrayProperty m_outputfile
Definition: IssueLogger.h:30
STL namespace.
T end(T...args)
IssueSeverity::Level m_reportLevel
Definition: IssueLogger.h:33
STL class.
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:86
StringProperty m_reportLevelS
Definition: IssueLogger.h:31
GAUDI_API int backTrace(void **addresses, const int depth)
MsgStream & err() const
shortcut for the method msgStream(MSG::ERROR)
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:36
STL class.
T at(T...args)
void setupDefaultLogger()
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
StatusCode reinitialize() override
STL class.
const TYPE & value() const
explicit conversion
Definition: Property.h:341
std::array< logger_t, IssueSeverity::NUM_LEVELS > m_log
Definition: IssueLogger.h:47
T find(T...args)
Property base class allowing Property* collections to be "homogeneous".
Definition: Property.h:38
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
T begin(T...args)
void setupStreams(Property &prop)
void setupLevels(Property &prop)
StatusCode initialize() override
Definition: IssueLogger.cpp:92
string s
Definition: gaudirun.py:245
SmartIF< IMessageSvc > & msgSvc() const
The standard message service.
T substr(T...args)
void WriteToMsgSvc(const std::string &str)
Definition: StreamLogger.h:20
T transform(T...args)
Property * declareProperty(const std::string &name, T &property, const std::string &doc="none") const
Declare the named property.
Definition: Service.h:215
IssueSeverity::Level m_traceLevel
Definition: IssueLogger.h:33
T for_each(T...args)
BooleanProperty m_showTime
Definition: IssueLogger.h:32
list i
Definition: ana.py:128
IssueSeverity::Level getLevel() const
Definition: IssueSeverity.h:82
StringProperty m_traceLevelS
Definition: IssueLogger.h:31
void WriteToStream(const std::string &str)
Definition: StreamLogger.h:19
std::string getMsg() const
Definition: IssueSeverity.h:83
void report(IssueSeverity::Level level, const std::string &msg, const std::string &origin) override
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
std::string format(bool local, std::string spec="%c") const
Format the time using strftime.
Definition: Time.cpp:279
IssueLogger(const std::string &name, ISvcLocator *svc)
Definition: IssueLogger.cpp:72