Logo ROOT  
Reference Guide
MsgLogger.cxx
Go to the documentation of this file.
1 // @(#)root/tmva $Id$
2 // Author: Attila Krasznahorkay, Andreas Hoecker, Joerg Stelzer, Eckhard von Toerne
3 
4 /**********************************************************************************
5  * Project: TMVA - a Root-integrated toolkit for multivariate data analysis *
6  * Package: TMVA *
7  * Class : MsgLogger *
8  * Web : http://tmva.sourceforge.net *
9  * *
10  * Description: *
11  * Implementation (see header for description) *
12  * *
13  * Author: *
14  * Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch> - CERN, Switzerland *
15  * Andreas Hoecker <Andreas.Hocker@cern.ch> - CERN, Switzerland *
16  * Joerg Stelzer <stelzer@cern.ch> - DESY, Germany *
17  * Eckhard v. Toerne <evt@uni-bonn.de> - U of Bonn, Germany *
18  * *
19  * Copyright (c) 2005-2011: *
20  * CERN, Switzerland *
21  * U. of Victoria, Canada *
22  * MPI-K Heidelberg, Germany *
23  * U. of Bonn, Germany *
24  * *
25  * Redistribution and use in source and binary forms, with or without *
26  * modification, are permitted according to the terms listed in LICENSE *
27  * (http://tmva.sourceforge.net/LICENSE) *
28  **********************************************************************************/
29 
30 /*! \class TMVA::MsgLogger
31 \ingroup TMVA
32 ostringstream derivative to redirect and format output
33 */
34 
35 // Local include(s):
36 #include "TMVA/MsgLogger.h"
37 
38 #include "TMVA/Config.h"
39 #include "TMVA/Types.h"
40 
41 // ROOT include(s):
42 #include "Rtypes.h"
43 #include "TObject.h"
44 
45 // STL include(s):
46 #include <cassert>
47 #include <cstdlib>
48 #include <iostream>
49 #include <memory>
50 
51 
53 
54 // declaration of global variables
55 // this is the hard-coded maximum length of the source names
57 
58 const std::string TMVA::MsgLogger::fgPrefix = "";
59 const std::string TMVA::MsgLogger::fgSuffix = ": ";
60 #if __cplusplus > 199711L
61 std::atomic<Bool_t> TMVA::MsgLogger::fgInhibitOutput{kFALSE};
62 std::atomic<const std::map<TMVA::EMsgType, std::string>*> TMVA::MsgLogger::fgTypeMap{0};
63 std::atomic<const std::map<TMVA::EMsgType, std::string>*> TMVA::MsgLogger::fgColorMap{0};
64 #else
66 const std::map<TMVA::EMsgType, std::string>* TMVA::MsgLogger::fgTypeMap = 0;
67 const std::map<TMVA::EMsgType, std::string>* TMVA::MsgLogger::fgColorMap = 0;
68 #endif
69 static std::unique_ptr<const std::map<TMVA::EMsgType, std::string> > gOwnTypeMap;
70 static std::unique_ptr<const std::map<TMVA::EMsgType, std::string> > gOwnColorMap;
71 
72 
74 void TMVA::MsgLogger::EnableOutput() { fgInhibitOutput = kFALSE; }
75 ////////////////////////////////////////////////////////////////////////////////
76 /// constructor
77 
78 TMVA::MsgLogger::MsgLogger( const TObject* source, EMsgType minType )
79  : fObjSource ( source ),
80  fStrSource ( "" ),
81  fActiveType( kINFO ),
82  fMinType ( minType )
83 {
84  InitMaps();
85 }
86 
87 ////////////////////////////////////////////////////////////////////////////////
88 /// constructor
89 
90 TMVA::MsgLogger::MsgLogger( const std::string& source, EMsgType minType )
91  : fObjSource ( 0 ),
92  fStrSource ( source ),
93  fActiveType( kINFO ),
94  fMinType ( minType )
95 {
96  InitMaps();
97 }
98 
99 ////////////////////////////////////////////////////////////////////////////////
100 /// constructor
101 
102 TMVA::MsgLogger::MsgLogger( EMsgType minType )
103  : fObjSource ( 0 ),
104  fStrSource ( "Unknown" ),
105  fActiveType( kINFO ),
106  fMinType ( minType )
107 {
108  InitMaps();
109 }
110 
111 ////////////////////////////////////////////////////////////////////////////////
112 /// copy constructor
113 
115  : std::basic_ios<MsgLogger::char_type, MsgLogger::traits_type>(),
116  std::ostringstream(),
117  TObject(),
118  fObjSource(0)
119 {
120  InitMaps();
121  *this = parent;
122 }
123 
124 ////////////////////////////////////////////////////////////////////////////////
125 /// destructor
126 
128 {
129 }
130 
131 ////////////////////////////////////////////////////////////////////////////////
132 /// assignment operator
133 
135 {
136  if (&parent != this) {
137  fObjSource = parent.fObjSource;
138  fStrSource = parent.fStrSource;
139  fActiveType = parent.fActiveType;
140  fMinType = parent.fMinType;
141  }
142 
143  return *this;
144 }
145 
146 ////////////////////////////////////////////////////////////////////////////////
147 /// make sure the source name is no longer than fgMaxSourceSize:
148 
150 {
151  std::string source_name;
152  if (fActiveType == kHEADER)
153  {
154  source_name = fStrSource;
155  }
156  if (fActiveType == kWARNING)
157  {
158  source_name ="<WARNING>";
159  }
160  if (source_name.size() > fgMaxSourceSize) {
161  source_name = source_name.substr( 0, fgMaxSourceSize - 3 );
162  source_name += "...";
163  }
164 
165  return source_name;
166 }
167 
168 ////////////////////////////////////////////////////////////////////////////////
169 /// returns the maximum source size
170 
172 {
173  return static_cast<UInt_t>(fgMaxSourceSize);
174 }
175 
176 ////////////////////////////////////////////////////////////////////////////////
177 /// the full logger prefix
178 
180 {
181  std::string source_name = GetFormattedSource();
182  if (source_name.size() < fgMaxSourceSize)
183  for (std::string::size_type i=source_name.size(); i<fgMaxSourceSize; i++) source_name.push_back( ' ' );
184 
185  return fgPrefix + source_name + fgSuffix;
186 }
187 
188 ////////////////////////////////////////////////////////////////////////////////
189 /// activates the logger writer
190 
192 {
193  // make sure the source name is no longer than fgMaxSourceSize:
194  std::string source_name = GetFormattedSource();
195 
196  std::string message = this->str();
197  std::string::size_type previous_pos = 0, current_pos = 0;
198 
199  // slice the message into lines:
200  while (kTRUE) {
201  current_pos = message.find( '\n', previous_pos );
202  std::string line = message.substr( previous_pos, current_pos - previous_pos );
203 
204  std::ostringstream message_to_send;
205  // must call the modifiers like this, otherwise g++ get's confused with the operators...
206  message_to_send.setf( std::ios::adjustfield, std::ios::left );
207  message_to_send.width( fgMaxSourceSize );
208  message_to_send << source_name << fgSuffix << line;
209  std::string msg = message_to_send.str();
210  this->WriteMsg( fActiveType, msg );
211 
212  if (current_pos == message.npos) break;
213  previous_pos = current_pos + 1;
214  }
215 
216  // reset the stream buffer:
217  this->str( "" );
218  fActiveType = kINFO; // To always print messages that have no level specified...
219  return;
220 }
221 
222 ////////////////////////////////////////////////////////////////////////////////
223 /// putting the output string, the message type, and the color
224 /// switcher together into a single string
225 
226 void TMVA::MsgLogger::WriteMsg( EMsgType type, const std::string& line ) const
227 {
228  if ( (type < fMinType || fgInhibitOutput) && type!=kFATAL ) return; // no output
229 
230  std::map<EMsgType, std::string>::const_iterator stype;
231 
232  if ((stype = fgTypeMap.load()->find( type )) != fgTypeMap.load()->end()) {
233  if (!gConfig().IsSilent() || type==kFATAL) {
234  if (gConfig().UseColor()) {
235  // no text for INFO or VERBOSE
236  if (type == kHEADER || type ==kWARNING)
237  std::cout << fgPrefix << line << std::endl;
238  else if (type == kINFO || type == kVERBOSE)
239  //std::cout << fgPrefix << line << std::endl; // no color for info
240  std::cout << line << std::endl;
241  else{
242  //std::cout<<"prefix='"<<fgPrefix<<"'"<<std::endl;
243  std::cout << fgColorMap.load()->find( type )->second << "<" << stype->second << ">" << line << "\033[0m" << std::endl;
244 }
245  }
246 
247  else {
248  if (type == kINFO) std::cout << fgPrefix << line << std::endl;
249  else std::cout << fgPrefix << "<" << stype->second << "> " << line << std::endl;
250  }
251  }
252  }
253 
254  // take decision to stop if fatal error
255  if (type == kFATAL) {
256  std::cout << "***> abort program execution" << std::endl;
257  throw std::runtime_error("FATAL error");
258 
259  //std::exit(1);
260  //assert(false);
261  }
262 }
263 
264 ////////////////////////////////////////////////////////////////////////////////
265 /// end line
266 
268 {
269  logger.Send();
270  return logger;
271 }
272 
273 ////////////////////////////////////////////////////////////////////////////////
274 /// Create the message type and color maps
275 
277 {
278  if(!fgTypeMap) {
279  std::map<TMVA::EMsgType, std::string>*tmp = new std::map<TMVA::EMsgType, std::string>();
280 
281  (*tmp)[kVERBOSE] = std::string("VERBOSE");
282  (*tmp)[kDEBUG] = std::string("DEBUG");
283  (*tmp)[kINFO] = std::string("INFO");
284  (*tmp)[kWARNING] = std::string("WARNING");
285  (*tmp)[kERROR] = std::string("ERROR");
286  (*tmp)[kFATAL] = std::string("FATAL");
287  (*tmp)[kSILENT] = std::string("SILENT");
288  (*tmp)[kHEADER] = std::string("HEADER");
289  const std::map<TMVA::EMsgType, std::string>* expected=0;
290  if(fgTypeMap.compare_exchange_strong(expected,tmp)) {
291  //Have the global own this
292  gOwnTypeMap.reset(tmp);
293  } else {
294  //Another thread beat us in creating the instance
295  delete tmp;
296  }
297  }
298 
299  if(!fgColorMap) {
300  std::map<TMVA::EMsgType, std::string>*tmp = new std::map<TMVA::EMsgType, std::string>();
301 
302  (*tmp)[kVERBOSE] = std::string("");
303  (*tmp)[kDEBUG] = std::string("\033[34m");
304  (*tmp)[kINFO] = std::string("");
305  (*tmp)[kWARNING] = std::string("\033[1;31m");
306  (*tmp)[kERROR] = std::string("\033[31m");
307  (*tmp)[kFATAL] = std::string("\033[37;41;1m");
308  (*tmp)[kSILENT] = std::string("\033[30m");
309 
310  const std::map<TMVA::EMsgType, std::string>* expected=0;
311  if(fgColorMap.compare_exchange_strong(expected,tmp)) {
312  //Have the global own this
313  gOwnColorMap.reset(tmp);
314  } else {
315  //Another thread beat us in creating the instance
316  delete tmp;
317  }
318  }
319 }
TMVA::MsgLogger::fgPrefix
static const std::string fgPrefix
Definition: MsgLogger.h:112
TMVA::MsgLogger::GetMaxSourceSize
static UInt_t GetMaxSourceSize()
returns the maximum source size
Definition: MsgLogger.cxx:171
kTRUE
const Bool_t kTRUE
Definition: RtypesCore.h:91
TMVA::MsgLogger::Send
void Send()
activates the logger writer
Definition: MsgLogger.cxx:191
gOwnTypeMap
static std::unique_ptr< const std::map< TMVA::EMsgType, std::string > > gOwnTypeMap
Definition: MsgLogger.cxx:69
ClassImp
#define ClassImp(name)
Definition: Rtypes.h:364
TMVA::MsgLogger::fMinType
EMsgType fMinType
Definition: MsgLogger.h:129
TMVA::MsgLogger::InhibitOutput
static void InhibitOutput()
Definition: MsgLogger.cxx:73
TMVA::MsgLogger::operator=
MsgLogger & operator=(const MsgLogger &parent)
assignment operator
Definition: MsgLogger.cxx:134
Bool_t
bool Bool_t
Definition: RtypesCore.h:63
TMVA::MsgLogger::fObjSource
const TObject * fObjSource
Definition: MsgLogger.h:110
TMVA::MsgLogger::fgMaxSourceSize
static const UInt_t fgMaxSourceSize
Definition: MsgLogger.h:115
TMVA::MsgLogger::fgInhibitOutput
static Bool_t fgInhibitOutput
Definition: MsgLogger.h:124
TMVA::MsgLogger::GetPrintedSource
std::string GetPrintedSource() const
the full logger prefix
Definition: MsgLogger.cxx:179
TMVA::MsgLogger::fActiveType
EMsgType fActiveType
Definition: MsgLogger.h:114
TMVA::MsgLogger::fgTypeMap
static const std::map< EMsgType, std::string > * fgTypeMap
Definition: MsgLogger.h:126
MsgLogger.h
TMVA::MsgLogger::fStrSource
std::string fStrSource
Definition: MsgLogger.h:111
TMVA::gConfig
Config & gConfig()
kFALSE
const Bool_t kFALSE
Definition: RtypesCore.h:92
TMVA::MsgLogger::fgColorMap
static const std::map< EMsgType, std::string > * fgColorMap
Definition: MsgLogger.h:127
UInt_t
unsigned int UInt_t
Definition: RtypesCore.h:46
TMVA::MsgLogger::MsgLogger
MsgLogger(const TObject *source, EMsgType minType=kINFO)
constructor
Definition: MsgLogger.cxx:78
Types.h
line
TLine * line
Definition: entrylistblock_figure1.C:235
TMVA::MsgLogger::WriteMsg
void WriteMsg(EMsgType type, const std::string &line) const
putting the output string, the message type, and the color switcher together into a single string
Definition: MsgLogger.cxx:226
Config.h
unsigned int
gOwnColorMap
static std::unique_ptr< const std::map< TMVA::EMsgType, std::string > > gOwnColorMap
Definition: MsgLogger.cxx:70
TMVA::MsgLogger::InitMaps
void InitMaps()
Create the message type and color maps.
Definition: MsgLogger.cxx:276
TMVA::MsgLogger::fgSuffix
static const std::string fgSuffix
Definition: MsgLogger.h:113
TMVA::MsgLogger::EnableOutput
static void EnableOutput()
Definition: MsgLogger.cxx:74
TMVA::MsgLogger
ostringstream derivative to redirect and format output
Definition: MsgLogger.h:59
TObject.h
TObject
Mother of all ROOT objects.
Definition: TObject.h:37
TMVA::MsgLogger::GetFormattedSource
std::string GetFormattedSource() const
make sure the source name is no longer than fgMaxSourceSize:
Definition: MsgLogger.cxx:149
TMVA::MsgLogger::Endmsg
static MsgLogger & Endmsg(MsgLogger &logger)
end line
Definition: MsgLogger.cxx:267
type
int type
Definition: TGX11.cxx:121
Rtypes.h
TMVA::MsgLogger::~MsgLogger
~MsgLogger()
destructor
Definition: MsgLogger.cxx:127