IssueLogger.cpp
Go to the documentation of this file.
1 #include "IssueLogger.h"
2 
3 #include "GaudiKernel/ISvcLocator.h"
4 #include "GaudiKernel/MsgStream.h"
5 #include "GaudiKernel/AttribStringParser.h"
6 #include "GaudiKernel/System.h"
7 #include "GaudiKernel/Time.h"
8 
9 #include <sstream>
10 #include <streambuf>
11 #include <algorithm>
12 
13 #include "boost/bind.hpp"
14 
15 using namespace std;
16 
18 
19 //*************************************************************************//
20 inline void toupper(std::string &s)
21 {
22  std::transform(s.begin(), s.end(), s.begin(),
23  (int(*)(int)) toupper);
24 }
25 
26 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
27 
28 IssueLogger::IssueLogger( const std::string& name, ISvcLocator* svc )
29  : base_class(name, svc) {
30 
31  declareProperty ("Output", m_outputfile );
32  declareProperty ("ReportLevel", m_reportLevelS="WARNING");
33  declareProperty ("TracebackLevel", m_traceLevelS="ERROR");
34  declareProperty ("ShowTime", m_showTime=false);
35 
39 
42 
43  for (int i=0; i<IssueSeverity::NUM_LEVELS; ++i) {
44  m_logger[i] = 0;
45  }
46 
55 
68 
80 
92 
93 
94 }
95 
96 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
97 
99 
100 }
101 
102 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
103 
106 
108  if (st.isFailure()) { return st; }
109 
111 
112  return st;
113 
114 }
115 
116 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
117 
120 
121  MsgStream log ( msgSvc(), name() );
122  log << MSG::WARNING << "reinitialize not implemented" << endmsg;
123 
124 
125  return StatusCode::SUCCESS;
126 
127 }
128 
129 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
130 
133 
134  MsgStream log ( msgSvc(), name() );
135  log << MSG::DEBUG << "IssueLogger::finalize" << endmsg;
136 
137  for (int i=0; i<IssueSeverity::NUM_LEVELS; ++i) {
139  delete m_logger[j];
140  }
141 
142  return Service::finalize();
143 }
144 
145 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
146 
147 void
148 IssueLogger::getTraceBack(std::string& stack) {
149  const int depth = 30;
150  const int offset = 5;
151  System::backTrace(stack, depth, offset);
152 }
153 
154 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
155 
157 IssueLogger::connect(const std::string& ident) {
158 
159  MsgStream log ( msgSvc(), name() );
160 
161  string::size_type loc = ident.find(" ");
162 // string stream = ident.substr(0,loc); // icc remark #177: variable "stream" was declared but never referenced
163 // typedef std::pair<std::string,std::string> Prop;
164 // std::vector<Prop> props;
165 
166  using Parser = Gaudi::Utils::AttribStringParser;
167  // note: if loc == string::npos then loc + 1 == 0
168  for (auto attrib: Parser(ident.substr(loc + 1))) {
169  toupper(attrib.tag);
170 
172 
173  if (attrib.tag == "DEBUG") {
174  level = IssueSeverity::DEBUG;
175  } else if ( attrib.tag == "INFO") {
176  level = IssueSeverity::INFO;
177  } else if ( attrib.tag == "WARNING") {
178  level = IssueSeverity::WARNING;
179  } else if ( attrib.tag == "RECOVERABLE") {
181  } else if ( attrib.tag == "ERROR") {
182  level = IssueSeverity::ERROR;
183  } else if ( attrib.tag == "FATAL") {
184  level = IssueSeverity::FATAL;
185  } else {
186  log << MSG::ERROR << "Unknown output level \"" << attrib.tag << "\""
187  << endmsg;
188  continue;
189  }
190 
191  if (m_logger[level] != 0) {
192  log << MSG::INFO << "closing stream " << m_logger[level]->name()
193  << endmsg;
194  delete m_logger[level];
195  m_logger[level] = 0;
196  }
197 
198  if (attrib.value == "MsgSvc") {
199  m_logger[level] = new StreamLogger(msgSvc(), m_sevMsgMap[level]);
200  m_log[level] =
201  boost::bind(&StreamLogger::WriteToMsgSvc, m_logger[level],
202  _1);
203  } else if (attrib.value == "STDERR") {
204  m_logger[level] = new StreamLogger(std::cerr);
205  m_log[level] =
206  boost::bind(&StreamLogger::WriteToStream, m_logger[level],
207  _1);
208  } else if (attrib.value == "STDOUT") {
209  m_logger[level] = new StreamLogger(std::cout);
210  m_log[level] =
211  boost::bind(&StreamLogger::WriteToStream, m_logger[level],
212  _1);
213  } else { // A file
214  try {
215  m_logger[level] = new StreamLogger(attrib.value.c_str());
216  }
217  catch (std::exception&) {
218  m_logger[level] = 0;
219  log << MSG::ERROR << "Unable to open file \"" << attrib.value
220  << "\" for writing issues at level " << attrib.tag << endmsg;
221  return StatusCode::FAILURE;
222  }
223  m_log[level] =
224  boost::bind(&StreamLogger::WriteToStream, m_logger[level], _1);
225  }
226  log << MSG::DEBUG << "Writing " << m_levelTrans[level]
227  << " issues to " << m_logger[level]->name() << endmsg;
228 
229  }
230 
231  return StatusCode::SUCCESS;
232 }
233 
234 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
235 
236 void
237 IssueLogger::report(IssueSeverity::Level lev, const std::string& str,
238  const std::string& org) {
239 
240  if ( lev < m_reportLevel) return;
241 
242  std::string msg = m_levelTrans[lev] + " " + org + " \"" + str + "\"";
243 
244  if (m_showTime) {
245  msg += " [" + Gaudi::Time::current().format(true, "%H:%M:%S %Y/%m/%d %Z") +"]";
246  }
247 
248  if (lev >= m_traceLevel) {
249  std::string stack;
250  getTraceBack(stack);
251  msg += "\n" + stack;
252  }
253 
254 
255  m_log[lev](msg);
256 
257 
258 }
259 
260 
261 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
262 
263 
264 void
266 
267  report(err.getLevel(), err.getMsg(), err.getOrigin());
268 
269 }
270 
271 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
272 
273 void
275 
276 
277  StringProperty *sap = dynamic_cast<StringProperty*> (&prop);
278  if (sap == 0) {
279  MsgStream log ( msgSvc(), name() );
280  log << MSG::ERROR << "Could not convert " << prop.name()
281  << "to a StringProperty (which it should be!)" << endmsg;
282  return;
283  }
284 
285  std::string val = sap->value();
286 
287  if (prop.name() == "ReportLevel") {
288  if (m_levelSTrans.find(val) == m_levelSTrans.end()) {
289  MsgStream log ( msgSvc(), name() );
290  log << MSG::ERROR
291  << "Option ReportLevel: unknown Issue Severity level \""
292  << val << "\". Setting it WARNING" << endmsg;
294  return;
295  } else {
297  }
298  } else if (prop.name() == "TracebackLevel") {
299  if (m_levelSTrans.find(val) == m_levelSTrans.end()) {
300  MsgStream log ( msgSvc(), name() );
301  log << MSG::ERROR
302  << "Option TracebackLevel: unknown Issue Severity level \""
303  << val << "\". Setting it to ERROR" << endmsg;
305  return;
306  } else {
308  }
309  } else {
310  MsgStream log ( msgSvc(), name() );
311  log << MSG::ERROR << "setting up unknown property \"" << prop.name()
312  << "\"" << endmsg;
313  return;
314  }
315 
316 }
317 
318 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
319 
320 void
322 
323  StringArrayProperty *sap = dynamic_cast<StringArrayProperty*>( &prop );
324  if (sap == 0) {
325  MsgStream log ( msgSvc(), name() );
326  log << MSG::ERROR << "Could not convert " << prop.name()
327  << "to a StringArrayProperty (which it should be!)" << endmsg;
328  return;
329  }
330 
331  vector<string>::const_iterator itr;
332  for (itr = sap->value().begin(); itr != sap->value().end(); ++itr) {
333  if (connect(*itr).isFailure()) {
334  MsgStream log ( msgSvc(), name() );
335  log << MSG::ERROR << "Could not setup stream " << *itr << endmsg;
336  }
337  }
338 
339  return;
340 
341 }
342 
343 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
344 
345 void
347  for (int i=1; i<IssueSeverity::NUM_LEVELS; ++i) {
348  if (m_logger[i] == 0) {
349  // default: dump to msgSvc
351 
352  m_logger[j] = new StreamLogger(msgSvc(), m_sevMsgMap[j]);
353  m_log[j] = boost::bind(&StreamLogger::WriteToMsgSvc, m_logger[j],
354  _1);
355 
356  MsgStream log ( msgSvc(), name() );
357  log << MSG::DEBUG << "Writing " << m_levelTrans[j]
358  << " issues to " << m_logger[j]->name() << endmsg;
359 
360  }
361  }
362 }
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
std::map< IssueSeverity::Level, std::string > m_levelTrans
Definition: IssueLogger.h:46
StatusCode connect(const std::string &)
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:26
std::string getOrigin() const
const std::string & name() const
property name
Definition: Property.h:47
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
void toupper(std::string &s)
Definition: IssueLogger.cpp:20
SmartIF< IMessageSvc > & msgSvc() const
The standard message service.
static Time current(void)
Returns the current time.
Definition: Time.cpp:114
void report(IssueSeverity::Level level, const std::string &msg, const std::string &origin)
std::map< std::string, IssueSeverity::Level > m_levelSTrans
Definition: IssueLogger.h:47
virtual StatusCode finalize()
Finalize (from INITIALIZED to CONFIGURED).
StringArrayProperty m_outputfile
Definition: IssueLogger.h:35
STL namespace.
IssueSeverity::Level m_reportLevel
Definition: IssueLogger.h:39
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:85
StringProperty m_reportLevelS
Definition: IssueLogger.h:36
GAUDI_API int backTrace(void **addresses, const int depth)
MsgStream & msg() const
shortcut for the method msgStream(MSG::INFO)
void setupDefaultLogger()
virtual void declareUpdateHandler(PropertyCallbackFunctor *pf)
set new callback for update
Definition: Property.cpp:141
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:36
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:30
StreamLogger * m_logger[IssueSeverity::NUM_LEVELS]
Definition: IssueLogger.h:41
const TYPE & value() const
explicit conversion
Definition: Property.h:355
virtual const std::string & name() const
Retrieve name of the service.
Definition: Service.cpp:329
Property base class allowing Property* collections to be "homogeneous".
Definition: Property.h:43
void getTraceBack(std::string &stack)
virtual StatusCode initialize()
Initialization (from CONFIGURED to INITIALIZED).
Definition: Service.cpp:72
void setupStreams(Property &prop)
void setupLevels(Property &prop)
virtual StatusCode reinitialize()
Initialization (from INITIALIZED or RUNNING to INITIALIZED, via CONFIGURED).
string s
Definition: gaudirun.py:244
Templated class to add the standard messaging functionalities.
virtual StatusCode initialize()
Initialization (from CONFIGURED to INITIALIZED).
void WriteToMsgSvc(const std::string &str)
Definition: StreamLogger.h:22
boost::function< void(const std::string &)> m_log[IssueSeverity::NUM_LEVELS]
Definition: IssueLogger.h:42
std::string name() const
Property * declareProperty(const std::string &name, T &property, const std::string &doc="none") const
Declare the named property.
Definition: Service.h:212
IssueSeverity::Level m_traceLevel
Definition: IssueLogger.h:39
std::map< IssueSeverity::Level, MSG::Level > m_sevMsgMap
Definition: IssueLogger.h:45
BooleanProperty m_showTime
Definition: IssueLogger.h:37
list i
Definition: ana.py:128
std::map< MSG::Level, IssueSeverity::Level > m_msgSevMap
Definition: IssueLogger.h:44
IssueSeverity::Level getLevel() const
Definition: IssueSeverity.h:82
virtual ~IssueLogger()
Definition: IssueLogger.cpp:98
StringProperty m_traceLevelS
Definition: IssueLogger.h:36
virtual StatusCode finalize()
Finalize (from INITIALIZED to CONFIGURED).
Definition: Service.cpp:197
void WriteToStream(const std::string &str)
Definition: StreamLogger.h:21
std::string getMsg() const
Definition: IssueSeverity.h:83
std::string format(bool local, std::string spec="%c") const
Format the time using strftime.
Definition: Time.cpp:280
IssueLogger(const std::string &name, ISvcLocator *svc)
Definition: IssueLogger.cpp:28