All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 <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 
72 IssueLogger::IssueLogger( const std::string& name, ISvcLocator* svc )
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  MsgStream log ( msgSvc(), name() );
105  log << MSG::WARNING << "reinitialize not implemented" << endmsg;
106  return StatusCode::SUCCESS;
107 
108 }
109 
110 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
111 
114 
115  MsgStream log ( msgSvc(), name() );
116  log << MSG::DEBUG << "IssueLogger::finalize" << endmsg;
117  std::for_each( std::begin(m_log), std::end(m_log),
118  [](logger_t& i)
119  { i.reset(); } );
120  return Service::finalize();
121 }
122 
123 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
124 
126 IssueLogger::connect(const std::string& ident) {
127 
128  MsgStream log ( msgSvc(), name() );
129 
130  auto loc = ident.find(" ");
131  using Parser = Gaudi::Utils::AttribStringParser;
132  // note: if loc == string::npos then loc + 1 == 0
133  for (auto attrib: Parser(ident.substr(loc + 1))) {
134  toupper(attrib.tag);
136  if (attrib.tag == "DEBUG") { level = IssueSeverity::DEBUG;
137  } else if ( attrib.tag == "INFO") { level = IssueSeverity::INFO;
138  } else if ( attrib.tag == "WARNING") { level = IssueSeverity::WARNING;
139  } else if ( attrib.tag == "RECOVERABLE") { level = IssueSeverity::RECOVERABLE;
140  } else if ( attrib.tag == "ERROR") { level = IssueSeverity::ERROR;
141  } else if ( attrib.tag == "FATAL") { level = IssueSeverity::FATAL;
142  } else {
143  log << MSG::ERROR << "Unknown output level \"" << attrib.tag << "\""
144  << endmsg;
145  continue;
146  }
147 
148  if (m_log[level]) {
149  log << MSG::INFO << "closing stream " << m_log[level].name() << endmsg;
150  m_log[level].reset();
151  }
152 
153  if (attrib.value == "MsgSvc") {
154  m_log[level] = { new StreamLogger(msgSvc(), s_sevMsgMap.at(level)) , &StreamLogger::WriteToMsgSvc };
155  } else if (attrib.value == "STDERR") {
156  m_log[level] = { new StreamLogger(std::cerr), &StreamLogger::WriteToStream };
157  } else if (attrib.value == "STDOUT") {
158  m_log[level] = { new StreamLogger(std::cout), &StreamLogger::WriteToStream };
159  } else { // A file
160  try {
161  m_log[level] = { new StreamLogger(attrib.value), &StreamLogger::WriteToStream };
162  }
163  catch (std::exception&) {
164  m_log[level].reset();
165  log << MSG::ERROR << "Unable to open file \"" << attrib.value
166  << "\" for writing issues at level " << attrib.tag << endmsg;
167  return StatusCode::FAILURE;
168  }
169  }
170  log << MSG::DEBUG << "Writing " << s_levelTrans.at(level)
171  << " issues to " << m_log[level].name() << endmsg;
172  }
173  return StatusCode::SUCCESS;
174 }
175 
176 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
177 
178 void
179 IssueLogger::report(IssueSeverity::Level lev, const std::string& str,
180  const std::string& org) {
181  if ( lev < m_reportLevel) return;
182  std::string msg = s_levelTrans.at(lev) + " " + org + " \"" + str + "\"";
183  if (m_showTime) msg += " [" + Gaudi::Time::current().format(true, "%H:%M:%S %Y/%m/%d %Z") +"]";
184  if (lev >= m_traceLevel) msg += "\n" + getTraceBack();
185  m_log[lev](msg);
186 }
187 
188 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
189 
190 void
192  report(err.getLevel(), err.getMsg(), err.getOrigin());
193 }
194 
195 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
196 
197 void
199 
200  StringProperty *sap = dynamic_cast<StringProperty*> (&prop);
201  if (!sap) {
202  MsgStream log ( msgSvc(), name() );
203  log << MSG::ERROR << "Could not convert " << prop.name()
204  << "to a StringProperty (which it should be!)" << endmsg;
205  return;
206  }
207 
208  const std::string& val = sap->value();
209  auto set = [&](IssueSeverity::Level& key, IssueSeverity::Level def) {
210  if (s_levelSTrans.find(val) == s_levelSTrans.end()) {
211  key = def;
212  MsgStream log ( this->msgSvc(), this->name() );
213  log << MSG::ERROR << "Option " << prop.name() << ": unknown Issue Severity level \""
214  << val << "\". Setting it " << s_levelTrans.at(def) << endmsg;
215  } else {
216  key = s_levelSTrans.at(val);
217  }
218  };
219 
220  if (prop.name() == "ReportLevel") {
222  } else if (prop.name() == "TracebackLevel") {
224  } else {
225  MsgStream log ( msgSvc(), name() );
226  log << MSG::ERROR << "setting up unknown property \""
227  << prop.name() << "\"" << endmsg;
228  }
229 }
230 
231 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
232 
233 void
235 
236  StringArrayProperty *sap = dynamic_cast<StringArrayProperty*>( &prop );
237  if ( !sap ) {
238  MsgStream log ( msgSvc(), name() );
239  log << MSG::ERROR << "Could not convert " << prop.name()
240  << "to a StringArrayProperty (which it should be!)" << endmsg;
241  return;
242  }
243  for (const auto& s : sap->value() ) {
244  if (connect(s).isFailure()) {
245  MsgStream log ( msgSvc(), name() );
246  log << MSG::ERROR << "Could not setup stream " << s << endmsg;
247  }
248  }
249 }
250 
251 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
252 
253 void
255  for (int i=1; i<IssueSeverity::NUM_LEVELS; ++i) {
256  if (!m_log[i]) {
257  // default: dump to msgSvc
259  m_log[j] = { new StreamLogger(msgSvc(), s_sevMsgMap.at(j)) , &StreamLogger::WriteToMsgSvc };
260  MsgStream log ( msgSvc(), name() );
261  log << MSG::DEBUG << "Writing " << s_levelTrans.at(j)
262  << " issues to " << m_log[j].name() << endmsg;
263  }
264  }
265 }
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
StatusCode initialize() override
Definition: Service.cpp:63
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
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
StatusCode finalize() override
Definition: Service.cpp:188
std::string getOrigin() const
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
auto begin(reverse_wrapper< T > &w)
Definition: reverse.h:45
StringArrayProperty m_outputfile
Definition: IssueLogger.h:29
STL namespace.
IssueSeverity::Level m_reportLevel
Definition: IssueLogger.h:32
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:86
StringProperty m_reportLevelS
Definition: IssueLogger.h:30
GAUDI_API int backTrace(void **addresses, const int depth)
void setupDefaultLogger()
auto end(reverse_wrapper< T > &w)
Definition: reverse.h:47
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:36
StatusCode reinitialize() override
const TYPE & value() const
explicit conversion
Definition: Property.h:341
std::array< logger_t, IssueSeverity::NUM_LEVELS > m_log
Definition: IssueLogger.h:46
Property base class allowing Property* collections to be "homogeneous".
Definition: Property.h:38
Base class used to extend a class implementing other interfaces.
Definition: extends.h:10
void setupStreams(Property &prop)
void setupLevels(Property &prop)
StatusCode initialize() override
Definition: IssueLogger.cpp:92
string s
Definition: gaudirun.py:245
void WriteToMsgSvc(const std::string &str)
Definition: StreamLogger.h:20
IssueSeverity::Level m_traceLevel
Definition: IssueLogger.h:32
BooleanProperty m_showTime
Definition: IssueLogger.h:31
list i
Definition: ana.py:128
IssueSeverity::Level getLevel() const
Definition: IssueSeverity.h:82
StringProperty m_traceLevelS
Definition: IssueLogger.h:30
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
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