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 /// the full logger prefix
170 
172 {
173  std::string source_name = GetFormattedSource();
174  if (source_name.size() < fgMaxSourceSize)
175  for (std::string::size_type i=source_name.size(); i<fgMaxSourceSize; i++) source_name.push_back( ' ' );
176 
177  return fgPrefix + source_name + fgSuffix;
178 }
179 
180 ////////////////////////////////////////////////////////////////////////////////
181 /// activates the logger writer
182 
184 {
185  // make sure the source name is no longer than fgMaxSourceSize:
186  std::string source_name = GetFormattedSource();
187 
188  std::string message = this->str();
189  std::string::size_type previous_pos = 0, current_pos = 0;
190 
191  // slice the message into lines:
192  while (kTRUE) {
193  current_pos = message.find( '\n', previous_pos );
194  std::string line = message.substr( previous_pos, current_pos - previous_pos );
195 
196  std::ostringstream message_to_send;
197  // must call the modifiers like this, otherwise g++ get's confused with the operators...
198  message_to_send.setf( std::ios::adjustfield, std::ios::left );
199  message_to_send.width( fgMaxSourceSize );
200  message_to_send << source_name << fgSuffix << line;
201  std::string msg = message_to_send.str();
202  this->WriteMsg( fActiveType, msg );
203 
204  if (current_pos == message.npos) break;
205  previous_pos = current_pos + 1;
206  }
207 
208  // reset the stream buffer:
209  this->str( "" );
210  fActiveType = kINFO; // To always print messages that have no level specified...
211  return;
212 }
213 
214 ////////////////////////////////////////////////////////////////////////////////
215 /// putting the output string, the message type, and the color
216 /// switcher together into a single string
217 
218 void TMVA::MsgLogger::WriteMsg( EMsgType type, const std::string& line ) const
219 {
220  if ( (type < fMinType || fgInhibitOutput) && type!=kFATAL ) return; // no output
221 
222  std::map<EMsgType, std::string>::const_iterator stype;
223 
224  if ((stype = fgTypeMap.load()->find( type )) != fgTypeMap.load()->end()) {
225  if (!gConfig().IsSilent() || type==kFATAL) {
226  if (gConfig().UseColor()) {
227  // no text for INFO or VERBOSE
228  if (type == kHEADER || type ==kWARNING)
229  std::cout << fgPrefix << line << std::endl;
230  else if (type == kINFO || type == kVERBOSE)
231  //std::cout << fgPrefix << line << std::endl; // no color for info
232  std::cout << line << std::endl;
233  else{
234  //std::cout<<"prefix='"<<fgPrefix<<"'"<<std::endl;
235  std::cout << fgColorMap.load()->find( type )->second << "<" << stype->second << ">" << line << "\033[0m" << std::endl;
236 }
237  }
238 
239  else {
240  if (type == kINFO) std::cout << fgPrefix << line << std::endl;
241  else std::cout << fgPrefix << "<" << stype->second << "> " << line << std::endl;
242  }
243  }
244  }
245 
246  // take decision to stop if fatal error
247  if (type == kFATAL) {
248  std::cout << "***> abort program execution" << std::endl;
249  throw std::runtime_error("FATAL error");
250 
251  //std::exit(1);
252  //assert(false);
253  }
254 }
255 
256 ////////////////////////////////////////////////////////////////////////////////
257 /// end line
258 
260 {
261  logger.Send();
262  return logger;
263 }
264 
265 ////////////////////////////////////////////////////////////////////////////////
266 /// Create the message type and color maps
267 
269 {
270  if(!fgTypeMap) {
271  std::map<TMVA::EMsgType, std::string>*tmp = new std::map<TMVA::EMsgType, std::string>();
272 
273  (*tmp)[kVERBOSE] = std::string("VERBOSE");
274  (*tmp)[kDEBUG] = std::string("DEBUG");
275  (*tmp)[kINFO] = std::string("INFO");
276  (*tmp)[kWARNING] = std::string("WARNING");
277  (*tmp)[kERROR] = std::string("ERROR");
278  (*tmp)[kFATAL] = std::string("FATAL");
279  (*tmp)[kSILENT] = std::string("SILENT");
280  (*tmp)[kHEADER] = std::string("HEADER");
281  const std::map<TMVA::EMsgType, std::string>* expected=0;
282  if(fgTypeMap.compare_exchange_strong(expected,tmp)) {
283  //Have the global own this
284  gOwnTypeMap.reset(tmp);
285  } else {
286  //Another thread beat us in creating the instance
287  delete tmp;
288  }
289  }
290 
291  if(!fgColorMap) {
292  std::map<TMVA::EMsgType, std::string>*tmp = new std::map<TMVA::EMsgType, std::string>();
293 
294  (*tmp)[kVERBOSE] = std::string("");
295  (*tmp)[kDEBUG] = std::string("\033[34m");
296  (*tmp)[kINFO] = std::string("");
297  (*tmp)[kWARNING] = std::string("\033[1;31m");
298  (*tmp)[kERROR] = std::string("\033[31m");
299  (*tmp)[kFATAL] = std::string("\033[37;41;1m");
300  (*tmp)[kSILENT] = std::string("\033[30m");
301 
302  const std::map<TMVA::EMsgType, std::string>* expected=0;
303  if(fgColorMap.compare_exchange_strong(expected,tmp)) {
304  //Have the global own this
305  gOwnColorMap.reset(tmp);
306  } else {
307  //Another thread beat us in creating the instance
308  delete tmp;
309  }
310  }
311 }
TMVA::MsgLogger::fgPrefix
static const std::string fgPrefix
Definition: MsgLogger.h:160
kTRUE
const Bool_t kTRUE
Definition: RtypesCore.h:91
TMVA::MsgLogger::Send
void Send()
activates the logger writer
Definition: MsgLogger.cxx:183
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:177
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:158
TMVA::MsgLogger::fgMaxSourceSize
static const UInt_t fgMaxSourceSize
Definition: MsgLogger.h:163
TMVA::MsgLogger::fgInhibitOutput
static Bool_t fgInhibitOutput
Definition: MsgLogger.h:172
TMVA::MsgLogger::GetPrintedSource
std::string GetPrintedSource() const
the full logger prefix
Definition: MsgLogger.cxx:171
TMVA::MsgLogger::fActiveType
EMsgType fActiveType
Definition: MsgLogger.h:162
TMVA::MsgLogger::fgTypeMap
static const std::map< EMsgType, std::string > * fgTypeMap
Definition: MsgLogger.h:174
MsgLogger.h
TMVA::MsgLogger::fStrSource
std::string fStrSource
Definition: MsgLogger.h:159
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:175
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:218
Config.h
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:268
TMVA::MsgLogger::fgSuffix
static const std::string fgSuffix
Definition: MsgLogger.h:161
TMVA::MsgLogger::EnableOutput
static void EnableOutput()
Definition: MsgLogger.cxx:74
TMVA::MsgLogger
Definition: MsgLogger.h:83
TObject.h
TObject
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:259
type
int type
Definition: TGX11.cxx:121
Rtypes.h
TMVA::MsgLogger::~MsgLogger
~MsgLogger()
destructor
Definition: MsgLogger.cxx:127