ATLAS Offline Software
Loading...
Searching...
No Matches
TMsgLogger.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 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
24using 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
34static const string::size_type MAXIMUM_SOURCE_NAME_LENGTH = 20;
35// this is the hardcoded prefix
36static const string PREFIX = "--- ";
37// this is the hardcoded suffix
38static const string SUFFIX = ": ";
39
40std::atomic<Root::TMsgLevel> Root::TMsgLogger::m_minLevel = kINFO;
41
42Root::TMsgLogger::TMsgLogger( const TObject* source, TMsgLevel /* minLevel */ )
43 : m_objSource( source ),
44 m_strSource( "" ),
45 m_prefix( PREFIX ),
46 m_suffix( SUFFIX ),
49{
50 // constructor
51 InitMaps();
52}
53
54Root::TMsgLogger::TMsgLogger( const string& source, TMsgLevel /* minLevel */ )
55 : m_objSource( 0 ),
56 m_strSource( source ),
57 m_prefix( PREFIX ),
58 m_suffix( SUFFIX ),
61{
62 // constructor
63 InitMaps();
64}
65
67 : m_objSource( 0 ),
68 m_strSource( "Unknown" ),
69 m_prefix( PREFIX ),
70 m_suffix( SUFFIX ),
73{
74 // constructor
75 InitMaps();
76}
77
79 : basic_ios< TMsgLogger::char_type, TMsgLogger::traits_type >(),
80 ostringstream(),
81 TObject(),
82 m_prefix( PREFIX ),
85{
86 InitMaps();
87 *this = parent;
88}
89
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
160void Root::TMsgLogger::WriteMsg( TMsgLevel mlevel, const std::string& line ) const
161{
162 if (mlevel < GetMinLevel()) return;
164 if ((slevel = m_levelMap.find( mlevel )) == m_levelMap.end()) return;
165#ifdef USE_COLORED_CONSOLE
166 // no text for INFO
167 std::string col;
168 auto it = m_colorMap.find( mlevel );
169 if (it != m_colorMap.end()) {
170 col = it->second;
171 }
172 if (mlevel == kINFO)
173 cout << col << m_prefix << line << "\033[0m" << endl;
174 else
175 cout << col << m_prefix
176 << "<" << slevel->second << "> " << line << "\033[0m" << endl;
177#else
178 if (mlevel == kINFO)
179 cout << m_prefix << line << endl;
180 else
181 cout << m_prefix << "<" << slevel->second << "> " << line << endl;
182#endif // USE_COLORED_CONSOLE
183
184 // take decision to stop if fatal error
185 if (mlevel == kFATAL) { cout << "***> abort program execution" << endl; std::abort(); }
186}
187
189{
190 // end line
191 logger.Send();
192 return logger;
193}
194
195Root::TMsgLevel Root::TMsgLogger::MapLevel( const TString& instr ) const
196{
197 TString ins = instr; // need to copy
198 ins.ToUpper();
199
200 // find the corresponding key
201 std::map<TMsgLevel, std::string>::const_iterator it = m_levelMap.begin();
202 for (; it != m_levelMap.end(); ++it) if (ins == it->second) return it->first;
203
204 // not found --> fatal error
205 TString line( Form( "fatal error in <TMsgLogger::MapLevel> unknown output level: %s ==> abort", ins.Data() ) );
206 std::string col;
207 auto colit = m_colorMap.find( kFATAL );
208 if (colit != m_colorMap.end()) {
209 col = colit->second;
210 }
211 cout << col << m_prefix << line << "\033[0m" << endl;
212 abort();
213
214 return kFATAL;
215}
216
218{
219 m_levelMap[kVERBOSE] = "VERBOSE";
220 m_levelMap[kDEBUG] = "DEBUG";
221 m_levelMap[kINFO] = "INFO";
222 m_levelMap[kWARNING] = "WARNING";
223 m_levelMap[kERROR] = "ERROR";
224 m_levelMap[kFATAL] = "FATAL";
225 m_levelMap[kALWAYS] = "ALWAYS";
226
227 m_colorMap[kVERBOSE] = "\033[1;34m";
228 m_colorMap[kDEBUG] = "\033[34m";
229 m_colorMap[kINFO] = "";
230 m_colorMap[kWARNING] = "\033[1;31m";
231 m_colorMap[kERROR] = "\033[1;31m";
232 m_colorMap[kFATAL] = "\033[37;41;1m";
233 m_colorMap[kALWAYS] = "\033[30m";
234}
static const string SUFFIX
static const string::size_type MAXIMUM_SOURCE_NAME_LENGTH
static const string PREFIX
virtual ~TMsgLogger()
static std::atomic< TMsgLevel > m_minLevel
Definition TMsgLogger.h:99
TMsgLogger(const TObject *source, TMsgLevel minLevel=kINFO)
const std::string m_prefix
Definition TMsgLogger.h:108
std::string GetFormattedSource() const
TMsgLevel MapLevel(const TString &instr) const
TMsgLogger & operator=(const TMsgLogger &parent)
void WriteMsg(TMsgLevel level, const std::string &line) const
static TMsgLogger & endmsg(TMsgLogger &logger)
std::map< TMsgLevel, std::string > m_levelMap
Definition TMsgLogger.h:113
const std::string m_suffix
Definition TMsgLogger.h:109
std::map< TMsgLevel, std::string > m_colorMap
Definition TMsgLogger.h:114
const TObject * m_objSource
Definition TMsgLogger.h:106
std::string m_strSource
Definition TMsgLogger.h:107
TMsgLevel GetMinLevel() const
Definition TMsgLogger.h:67
std::string GetPrintedSource() const
TMsgLevel m_activeLevel
Definition TMsgLogger.h:110
const std::string::size_type m_maxSourceSize
Definition TMsgLogger.h:111
STL iterator class.
static Root::TMsgLogger logger("iLumiCalc")
TMsgLevel
Definition TMsgLogger.h:37
@ kALWAYS
Definition TMsgLogger.h:44
@ kERROR
Definition TMsgLogger.h:42
@ kWARNING
Definition TMsgLogger.h:41
@ kDEBUG
Definition TMsgLogger.h:39
@ kFATAL
Definition TMsgLogger.h:43
@ kVERBOSE
Definition TMsgLogger.h:38
@ kINFO
Definition TMsgLogger.h:40
STL namespace.