ATLAS Offline Software
TMsgLogger.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 /**********************************************************************************
6  * Class : TMsgLogger *
7  * *
8  * Authors (alphabetical): *
9  * Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch> - CERN, Switzerland *
10  **********************************************************************************/
11 
12 // STL include(s):
13 #include <iomanip>
14 #include <iostream>
15 #include <stdlib.h>
16 
17 // ROOT include(s):
18 #include "TObject.h"
19 #include "TString.h"
20 
21 // Local include(s):
23 
24 using namespace std;
25 
26 
27 //ClassImp(Root::TMsgLogger)
28 
29 
30 // uncomment this line to inhibit colored output
31 #define USE_COLORED_CONSOLE
32 
33 // this is the hard-coded maximum length of the source names
34 static const string::size_type MAXIMUM_SOURCE_NAME_LENGTH = 20;
35 // this is the hardcoded prefix
36 static const string PREFIX = "--- ";
37 // this is the hardcoded suffix
38 static const string SUFFIX = ": ";
39 
40 std::atomic<Root::TMsgLevel> Root::TMsgLogger::m_minLevel = kINFO;
41 
42 Root::TMsgLogger::TMsgLogger( const TObject* source, TMsgLevel /* minLevel */ )
43  : m_objSource( source ),
44  m_strSource( "" ),
45  m_prefix( PREFIX ),
46  m_suffix( SUFFIX ),
47  m_activeLevel( kINFO ),
48  m_maxSourceSize( MAXIMUM_SOURCE_NAME_LENGTH )
49 {
50  // constructor
51  InitMaps();
52 }
53 
54 Root::TMsgLogger::TMsgLogger( const string& source, TMsgLevel /* minLevel */ )
55  : m_objSource( 0 ),
56  m_strSource( source ),
57  m_prefix( PREFIX ),
58  m_suffix( SUFFIX ),
59  m_activeLevel( kINFO ),
60  m_maxSourceSize( MAXIMUM_SOURCE_NAME_LENGTH )
61 {
62  // constructor
63  InitMaps();
64 }
65 
67  : m_objSource( 0 ),
68  m_strSource( "Unknown" ),
69  m_prefix( PREFIX ),
70  m_suffix( SUFFIX ),
71  m_activeLevel( kINFO ),
72  m_maxSourceSize( MAXIMUM_SOURCE_NAME_LENGTH )
73 {
74  // constructor
75  InitMaps();
76 }
77 
79  : basic_ios< TMsgLogger::char_type, TMsgLogger::traits_type >(),
80  ostringstream(),
81  TObject(),
82  m_prefix( PREFIX ),
83  m_suffix( SUFFIX ),
84  m_maxSourceSize( MAXIMUM_SOURCE_NAME_LENGTH )
85 {
86  InitMaps();
87  *this = parent;
88 }
89 
91 {}
92 
94 {
95  if (this != &parent) {
96  m_objSource = parent.m_objSource;
97  m_strSource = parent.m_strSource;
98  m_activeLevel = parent.m_activeLevel;
99  }
100 
101  return *this;
102 }
103 
105 {
106  // make sure the source name is no longer than m_maxSourceSize:
107  string source_name;
108  if (m_objSource) source_name = m_objSource->GetName();
109  else source_name = m_strSource;
110 
111  if (source_name.size() > m_maxSourceSize) {
112  source_name.resize(m_maxSourceSize - 3 );
113  source_name += "...";
114  }
115 
116  return source_name;
117 }
118 
120 {
121  // the full logger prefix
122  string source_name = GetFormattedSource();
123  if (source_name.size() < m_maxSourceSize)
124  for (string::size_type i=source_name.size(); i<m_maxSourceSize; i++) source_name.push_back( ' ' );
125 
126  return m_prefix + source_name + m_suffix;
127 }
128 
130 {
131  // activates the logger writer
132 
133  // make sure the source name is no longer than m_maxSourceSize:
134  string source_name = GetFormattedSource();
135 
136  string message = this->str();
137  string::size_type previous_pos = 0, current_pos = 0;
138 
139  // slice the message into lines:
140  for (;;) {
141  current_pos = message.find( '\n', previous_pos );
142  string line = message.substr( previous_pos, current_pos - previous_pos );
143 
144  ostringstream message_to_send;
145  // must call the modifiers like this, otherwise g++ get's confused with the operators...
146  message_to_send.setf( ios::adjustfield, ios::left );
147  message_to_send.width( m_maxSourceSize );
148  message_to_send << source_name << m_suffix << line;
149  this->WriteMsg( m_activeLevel, message_to_send.str() );
150 
151  if (current_pos == message.npos) break;
152  previous_pos = current_pos + 1;
153  }
154 
155  // reset the stream buffer:
156  this->str( "" );
157  return;
158 }
159 
160 void Root::TMsgLogger::WriteMsg( TMsgLevel mlevel, const std::string& line ) const
161 {
162  if (mlevel < GetMinLevel()) return;
163  map<TMsgLevel, std::string>::const_iterator slevel;
164  if ((slevel = m_levelMap.find( mlevel )) == m_levelMap.end()) return;
165 #ifdef USE_COLORED_CONSOLE
166  // no text for INFO
167  if (mlevel == kINFO)
168  cout << m_colorMap.find( mlevel )->second << m_prefix << line << "\033[0m" << endl;
169  else
170  cout << m_colorMap.find( mlevel )->second << m_prefix
171  << "<" << slevel->second << "> " << line << "\033[0m" << endl;
172 #else
173  if (mlevel == kINFO)
174  cout << m_prefix << line << endl;
175  else
176  cout << m_prefix << "<" << slevel->second << "> " << line << endl;
177 #endif // USE_COLORED_CONSOLE
178 
179  // take decision to stop if fatal error
180  if (mlevel == kFATAL) { cout << "***> abort program execution" << endl; std::abort(); }
181 }
182 
184 {
185  // end line
186  logger.Send();
187  return logger;
188 }
189 
190 Root::TMsgLevel Root::TMsgLogger::MapLevel( const TString& instr ) const
191 {
192  TString ins = instr; // need to copy
193  ins.ToUpper();
194 
195  // find the corresponding key
196  std::map<TMsgLevel, std::string>::const_iterator it = m_levelMap.begin();
197  for (; it != m_levelMap.end(); ++it) if (ins == it->second) return it->first;
198 
199  // not found --> fatal error
200  TString line( Form( "fatal error in <TMsgLogger::MapLevel> unknown output level: %s ==> abort", ins.Data() ) );
201  cout << m_colorMap.find( kFATAL )->second << m_prefix << line << "\033[0m" << endl;
202  abort();
203 
204  return kFATAL;
205 }
206 
208 {
209  m_levelMap[kVERBOSE] = "VERBOSE";
210  m_levelMap[kDEBUG] = "DEBUG";
211  m_levelMap[kINFO] = "INFO";
212  m_levelMap[kWARNING] = "WARNING";
213  m_levelMap[kERROR] = "ERROR";
214  m_levelMap[kFATAL] = "FATAL";
215  m_levelMap[kALWAYS] = "ALWAYS";
216 
217  m_colorMap[kVERBOSE] = "\033[1;34m";
218  m_colorMap[kDEBUG] = "\033[34m";
219  m_colorMap[kINFO] = "";
220  m_colorMap[kWARNING] = "\033[1;31m";
221  m_colorMap[kERROR] = "\033[1;31m";
222  m_colorMap[kFATAL] = "\033[37;41;1m";
223  m_colorMap[kALWAYS] = "\033[30m";
224 }
Root::TMsgLogger::Send
void Send()
Definition: TMsgLogger.cxx:129
Root::TMsgLogger::WriteMsg
void WriteMsg(TMsgLevel level, const std::string &line) const
Definition: TMsgLogger.cxx:160
Root::kWARNING
@ kWARNING
Definition: TMsgLogger.h:51
checkFileSG.line
line
Definition: checkFileSG.py:75
skel.it
it
Definition: skel.GENtoEVGEN.py:396
Root::kERROR
@ kERROR
Definition: TMsgLogger.h:52
Root::TMsgLogger::GetPrintedSource
std::string GetPrintedSource() const
Definition: TMsgLogger.cxx:119
Root::kVERBOSE
@ kVERBOSE
Definition: TMsgLogger.h:48
ReweightUtils.message
message
Definition: ReweightUtils.py:15
Root::kALWAYS
@ kALWAYS
Definition: TMsgLogger.h:54
Root::TMsgLogger::GetFormattedSource
std::string GetFormattedSource() const
Definition: TMsgLogger.cxx:104
Root::kDEBUG
@ kDEBUG
Definition: TMsgLogger.h:49
Root::TMsgLogger::MapLevel
TMsgLevel MapLevel(const TString &instr) const
Definition: TMsgLogger.cxx:190
lumiFormat.i
int i
Definition: lumiFormat.py:85
Root::kINFO
@ kINFO
Definition: TMsgLogger.h:50
Root::TMsgLevel
TMsgLevel
Definition: TMsgLogger.h:42
test_pyathena.parent
parent
Definition: test_pyathena.py:15
Root::TMsgLogger::~TMsgLogger
virtual ~TMsgLogger()
Definition: TMsgLogger.cxx:90
Root::TMsgLogger::m_minLevel
static std::atomic< TMsgLevel > m_minLevel
Definition: TMsgLogger.h:103
Root::TMsgLogger::TMsgLogger
TMsgLogger(const TObject *source, TMsgLevel minLevel=kINFO)
Definition: TMsgLogger.cxx:42
Root::TMsgLogger::endmsg
static TMsgLogger & endmsg(TMsgLogger &logger)
Definition: TMsgLogger.cxx:183
Root::TMsgLogger::operator=
TMsgLogger & operator=(const TMsgLogger &parent)
Definition: TMsgLogger.cxx:93
python.CaloScaleNoiseConfig.str
str
Definition: CaloScaleNoiseConfig.py:78
TMsgLogger.h
Root::TMsgLogger::InitMaps
void InitMaps()
Definition: TMsgLogger.cxx:207
copySelective.source
string source
Definition: copySelective.py:32
Root::TMsgLogger
Definition: TMsgLogger.h:52
Root::kFATAL
@ kFATAL
Definition: TMsgLogger.h:53
python.iconfTool.gui.pad.logger
logger
Definition: pad.py:14