| The Gaudi Framework v29r1 (5cd95fa2)

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

Message.cpp
Go to the documentation of this file.
1 #include "GaudiKernel/Message.h"
2 #include "GaudiKernel/IMessageSvc.h"
3 #include "GaudiKernel/ThreadLocalContext.h"
4 #include "GaudiKernel/Time.h"
5 #include "GaudiKernel/Timing.h"
6 #include <algorithm>
7 #include <cctype>
8 #include <cstdio>
9 #include <cstdlib>
10 #include <iomanip>
11 #include <iostream>
12 #include <string>
13
14 using namespace MSG;
15
16 namespace
17 {
18 // get the current time from the system and format it according to the format
19 inline std::string formattedTime( const std::string& fmt, bool universal = false )
20 {
21 return Gaudi::Time::current().format( !universal, fmt );
22 }
23 }
24
25 //#############################################################################
26 // ---------------------------------------------------------------------------
27 // Routine: Constructor.
28 // Purpose:
29 // ---------------------------------------------------------------------------
30 //
31 Message::Message()
32 {
33 m_ecSlot = Gaudi::Hive::currentContextId();
34 m_ecEvt = Gaudi::Hive::currentContextEvt();
35 m_ecThrd = pthread_self();
36 }
37
38 //#############################################################################
39 // ---------------------------------------------------------------------------
40 // Routine: Constructor.
41 // Purpose:
42 // ---------------------------------------------------------------------------
43 //
44 Message::Message( const char* src, int type, const char* msg ) : m_message( msg ), m_source( src ), m_type( type )
45 {
46 m_ecSlot = Gaudi::Hive::currentContextId();
47 m_ecEvt = Gaudi::Hive::currentContextEvt();
48 m_ecThrd = pthread_self();
49 }
50
51 //#############################################################################
52 // ---------------------------------------------------------------------------
53 // Routine: Constructor.
54 // Purpose:
55 // ---------------------------------------------------------------------------
56 //
57 Message::Message( std::string src, int type, std::string msg )
58 : m_message( std::move( msg ) ), m_source( std::move( src ) ), m_type( type )
59 {
60 m_ecSlot = Gaudi::Hive::currentContextId();
61 m_ecEvt = Gaudi::Hive::currentContextEvt();
62 m_ecThrd = pthread_self();
63 }
64
65 //#############################################################################
66 // ---------------------------------------------------------------------------
67 // Routine: getMessage
68 // Purpose: Get the message string.
69 // ---------------------------------------------------------------------------
70 //
71 const std::string& Message::getMessage() const { return m_message; }
72
73 //#############################################################################
74 // ---------------------------------------------------------------------------
75 // Routine: setMessage
76 // Purpose: Set the message string.
77 // ---------------------------------------------------------------------------
78 //
79 void Message::setMessage( std::string msg ) { m_message = std::move( msg ); }
80
81 //#############################################################################
82 // ---------------------------------------------------------------------------
83 // Routine: getType
84 // Purpose: Get the message type.
85 // ---------------------------------------------------------------------------
86 //
87 int Message::getType() const { return m_type; }
88
89 //#############################################################################
90 // ---------------------------------------------------------------------------
91 // Routine: setType
92 // Purpose: Set the message type.
93 // ---------------------------------------------------------------------------
94 //
95 void Message::setType( int msg_type ) { m_type = msg_type; }
96
97 //#############################################################################
98 // ---------------------------------------------------------------------------
99 // Routine: getSource
100 // Purpose: Get the message source.
101 // ---------------------------------------------------------------------------
102 //
103 const std::string& Message::getSource() const { return m_source; }
104
105 //#############################################################################
106 // ---------------------------------------------------------------------------
107 // Routine: setSource
108 // Purpose: Set the message source.
109 // ---------------------------------------------------------------------------
110 //
111 void Message::setSource( std::string src ) { m_source = std::move( src ); }
112
113 //#############################################################################
114 // ---------------------------------------------------------------------------
115 // Routine: operator <<
116 // Purpose:Insert the message into a stream.
117 // ---------------------------------------------------------------------------
118 //
119 std::ostream& operator<<( std::ostream& stream, const Message& msg )
120 {
121 msg.makeFormattedMsg( msg.m_format );
122 stream << msg.m_formatted_msg;
123 return stream;
124 }
125
126 //#############################################################################
127 // ---------------------------------------------------------------------------
128 // Routine: operator <
129 // Purpose: comparison operator needed for maps
130 // ---------------------------------------------------------------------------
131 //
132 bool Message::operator<( const Message& b )
133 {
134 return m_type < b.m_type || m_source < b.m_source || m_message < b.m_message;
135 }
136
137 //#############################################################################
138 // ---------------------------------------------------------------------------
139 // Routine: operator ==
140 // Purpose: comparison op.
141 // ---------------------------------------------------------------------------
142 //
143 bool operator==( const Message& a, const Message& b )
144 {
145 return a.m_source == b.m_source && a.m_type == b.m_type && a.m_message == b.m_message;
146 }
147
148 //#############################################################################
149 // ---------------------------------------------------------------------------
150 // Routine:
151 // Purpose: Get the format string.
152 // ---------------------------------------------------------------------------
153 //
154 const std::string& Message::getFormat() const { return m_format; }
155
156 //#############################################################################
157 // ---------------------------------------------------------------------------
158 // Routine:
159 // Purpose: Get the default format string.
160 // ---------------------------------------------------------------------------
161 //
162 const std::string Message::getDefaultFormat() { return DEFAULT_FORMAT; }
163
164 //#############################################################################
165 // ---------------------------------------------------------------------------
166 // Routine:
167 // Purpose: Set the format string -
168 // use isFormatted() to check for valid format.
169 // ---------------------------------------------------------------------------
170 //
171 void Message::setFormat( std::string format ) const
172 {
173 if ( LIKELY( !format.empty() ) ) {
174 m_format = std::move( format );
175 } else {
176 m_format = DEFAULT_FORMAT;
177 }
178 }
179
180 //#############################################################################
181 // ---------------------------------------------------------------------------
182 // Routine:
183 // Purpose: Get the time format string.
184 // ---------------------------------------------------------------------------
185 //
186 const std::string& Message::getTimeFormat() const { return m_time_format; }
187
188 //#############################################################################
189 // ---------------------------------------------------------------------------
190 // Routine:
191 // Purpose: Get the default time format string.
192 // ---------------------------------------------------------------------------
193 //
194 const std::string Message::getDefaultTimeFormat() { return DEFAULT_TIME_FORMAT; }
195
196 //#############################################################################
197 // ---------------------------------------------------------------------------
198 // Routine:
199 // Purpose: Set the time format string -
200 // use isFormatted() to check for valid format.
201 // ---------------------------------------------------------------------------
202 //
203 void Message::setTimeFormat( std::string timeFormat ) const
204 {
205 m_time_format = ( timeFormat.empty() ? DEFAULT_TIME_FORMAT : std::move( timeFormat ) );
206 }
207
208 //#############################################################################
209 // ---------------------------------------------------------------------------
210 // Routine: makeFormattedMsg
211 // Purpose: This formats the message according to the format string.
212 // ---------------------------------------------------------------------------
213 //
214 void Message::makeFormattedMsg( const std::string& format ) const
215 {
216 m_formatted_msg.clear();
217 auto i = format.begin();
218 while ( i != format.end() ) {
219
220 // Output format string until format statement found.
221 while ( i != format.end() && *i != FORMAT_PREFIX ) m_formatted_msg += *i++;
222
223 // Test for end of format string.
224 if ( i == format.end() ) break;
225 i++;
226
227 // Find type of formatting.
228 std::string this_format;
229 while ( i != format.end() && *i != FORMAT_PREFIX && *i != MESSAGE && *i != TYPE && *i != SOURCE && *i != FILL &&
230 *i != WIDTH && *i != TIME && *i != UTIME && *i != SLOT && *i != EVTNUM && *i != THREAD &&
231 *i != JUSTIFY_LEFT && *i != JUSTIFY_RIGHT ) {
232 this_format += *i++;
233 }
234
235 // Reached end of string with improper format.
236 if ( i == format.end() ) {
237 invalidFormat();
238 break;
239 }
240
241 this_format += *i++;
242 decodeFormat( this_format );
243 }
244 }
245
246 //#############################################################################
247 // ---------------------------------------------------------------------------
248 // Routine: decodeFormat
249 // Purpose: This the work horse that checks for a valid format string.
250 // ---------------------------------------------------------------------------
251 //
252 void Message::decodeFormat( const std::string& format ) const
253 {
254 if ( !format.empty() ) {
255 const char FORMAT_TYPE = format[format.length() - 1];
256 const std::string FORMAT_PARAM = format.substr( 0, format.length() - 1 );
257
258 // Now test the format.
259 std::string level;
260 switch ( FORMAT_TYPE ) {
261 case FILL:
262 if ( FORMAT_PARAM.length() == 1 ) {
263 m_fill = FORMAT_PARAM[0];
264 } else
265 invalidFormat();
266 break;
267
268 case TIME: {
269 sizeField( formattedTime( m_time_format ) );
270 } break;
271
272 case UTIME: {
273 sizeField( formattedTime( m_time_format, true ) );
274 } break;
275
276 case THREAD: {
277 std::ostringstream ost;
278 // ost << "0x" << std::hex << pthread_self();
279 ost << "0x" << std::hex << m_ecThrd;
280 const std::string& thrStr( ost.str() );
281 sizeField( thrStr );
282 } break;
283
284 case SLOT: {
285 if ( m_ecEvt >= 0 ) {
286 std::ostringstream ost;
287 ost << m_ecSlot;
288 const std::string& slotStr( ost.str() );
289 sizeField( slotStr );
290 } else {
291 const std::string& slotStr( "" );
292 sizeField( slotStr );
293 }
294 } break;
295
296 case EVTNUM: {
297 if ( m_ecEvt >= 0 ) {
298 std::ostringstream ost;
299 ost << m_ecEvt;
300 const std::string& slotStr( ost.str() );
301 sizeField( slotStr );
302 } else {
303 const std::string& slotStr( "" );
304 sizeField( slotStr );
305 }
306 } break;
307
308 case MESSAGE:
309 sizeField( m_message );
310 break;
311
312 case SOURCE:
313 sizeField( m_source );
314 break;
315
316 case TYPE:
317 switch ( m_type ) {
318 #define SET( x ) \
319 case x: \
320 level = #x; \
321 break
322 SET( NIL );
323 SET( VERBOSE );
324 SET( DEBUG );
325 SET( INFO );
326 SET( WARNING );
327 SET( ERROR );
328 SET( FATAL );
329 case ALWAYS:
330 level = "SUCCESS";
331 break;
332 default:
333 level = "UNKNOWN";
334 break;
335 #undef SET
336 }
337 sizeField( level );
338 break;
339
340 case FORMAT_PREFIX:
341 m_formatted_msg += FORMAT_PREFIX;
342 break;
343 case JUSTIFY_RIGHT:
344 m_left = false;
345 break;
346 case JUSTIFY_LEFT:
347 m_left = true;
348 break;
349 case WIDTH:
350 setWidth( FORMAT_PARAM );
351 break;
352 default:
353 invalidFormat();
354 break;
355 }
356 } else
357 invalidFormat();
358 }
359
360 //#############################################################################
361 // ---------------------------------------------------------------------------
362 // Routine: invalidFormat.
363 // Purpose: called when invalid format found.
364 // ---------------------------------------------------------------------------
365 //
366
367 void Message::invalidFormat() const { makeFormattedMsg( DEFAULT_FORMAT ); }
368
369 //#############################################################################
370 // ---------------------------------------------------------------------------
371 // Routine: setWidth
372 // Purpose: Sets the minimum width of a stream field.
373 // ---------------------------------------------------------------------------
374 //
375 namespace
376 {
377 // Check that a container only contains digits.
378 constexpr struct all_digit_t {
379 template <typename C>
380 bool operator()( const C& c ) const
381 {
382 return std::all_of( std::begin( c ), std::end( c ),
383 []( typename C::const_reference i ) { return isdigit( i ); } );
384 }
385 } all_digits{};
386 }
387
388 void Message::setWidth( const std::string& formatArg ) const
389 {
390 // Convert string to int, if string contains digits only...
391 if ( all_digits( formatArg ) )
392 m_width = std::stoi( formatArg );
393 else
394 invalidFormat();
395 }
396
397 //#############################################################################
398 // ---------------------------------------------------------------------------
399 // Routine: sizeField
400 // Purpose: Truncates or pads the text to m_width as necessary
401 // ---------------------------------------------------------------------------
402 //
403
404 void Message::sizeField( const std::string& text ) const
405 {
406 std::string newText;
407 if ( m_width == 0 || m_width == static_cast<int>( text.length() ) ) {
408 newText = text;
409 } else {
410
411 // Truncate the text if it is too long.
412 if ( m_width < static_cast<int>( text.length() ) ) {
413 newText = text.substr( 0, m_width );
414 for ( int i = 0, j = newText.length() - 1; i < 3 && j >= 0; ++i, --j ) newText[j] = '.';
415 }
416
417 // Pad the text.
418 else {
419 newText = std::string( m_width, m_fill );
420 if ( m_left )
421 newText.replace( newText.begin(), newText.begin() + text.length(), text.begin(), text.end() );
422 else
423 newText.replace( newText.end() - text.length(), newText.end(), text.begin(), text.end() );
424 }
425 }
426
427 m_formatted_msg += newText;
428 }
Message::m_ecSlot
size_t m_ecSlot
Definition: Message.h:171
Message::m_ecEvt
long int m_ecEvt
Definition: Message.h:172
Message::TYPE
static const char TYPE
The character used to indicate that the message type should be printed.
Definition: Message.h:133
Message::m_left
bool m_left
Justification.
Definition: Message.h:116
Message::MESSAGE
static const char MESSAGE
The character used to indicate that the message should be printed.
Definition: Message.h:130
Message::getFormat
const std::string & getFormat() const
Get the format string.
Definition: Message.cpp:154
Message::m_fill
char m_fill
The current fill character.
Definition: Message.h:110
Message::JUSTIFY_LEFT
static const char JUSTIFY_LEFT
The character used to indicate start of left text justification.
Definition: Message.h:124
Gaudi::Hive::currentContextId
GAUDI_API ContextIdType currentContextId()
Return the current context id.
Definition: ThreadLocalContext.cpp:22
std::string::empty
T empty(T...args)
format
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:120
Message::m_formatted_msg
std::string m_formatted_msg
Formatted message.
Definition: Message.h:107
gaudirun.c
c
Definition: gaudirun.py:407
Message::THREAD
static const char THREAD
Definition: Message.h:169
Message::m_time_format
std::string m_time_format
Time format string.
Definition: Message.h:101
Message::decodeFormat
void decodeFormat(const std::string &format) const
Decode format.
Definition: Message.cpp:252
Message::setWidth
void setWidth(const std::string &formatArg) const
Set the width of a stream.
Definition: Message.cpp:388
Message::operator<
bool operator<(const Message &test)
Needed to build maps.
Definition: Message.cpp:132
ThreadLocalContext.h
ReadAndWriteWhiteBoard.DEBUG
DEBUG
Definition: ReadAndWriteWhiteBoard.py:24
Gaudi::Time::current
static Time current()
Returns the current time.
Definition: Time.cpp:112
Message::m_message
std::string m_message
The message.
Definition: Message.h:92
Message::setMessage
void setMessage(std::string msg)
Set the message string.
Definition: Message.cpp:79
std
STL namespace.
Message::setType
void setType(int msg_type)
Set the message type.
Definition: Message.cpp:95
std::string::end
T end(T...args)
Message::getType
int getType() const
Get the message type.
Definition: Message.cpp:87
MSG::VERBOSE
Definition: IMessageSvc.h:16
Message::Message
Message()
Default constructor.
Definition: Message.cpp:31
Message::operator<<
friend std::ostream & operator<<(std::ostream &stream, const Message &msg)
Insert the message into a stream.
Definition: Message.cpp:119
Message::setSource
void setSource(std::string src)
Set the message source.
Definition: Message.cpp:111
Message::invalidFormat
void invalidFormat() const
Called when an invalid format string is encountered.
Definition: Message.cpp:367
std::string
STL class.
MSG::FATAL
Definition: IMessageSvc.h:16
std::string::replace
T replace(T...args)
Message::getDefaultTimeFormat
static const std::string getDefaultTimeFormat()
Get the default time format string.
Definition: Message.cpp:194
std::ostringstream
STL class.
gaudirun.type
type
Definition: gaudirun.py:133
Message::getDefaultFormat
static const std::string getDefaultFormat()
Get the default format string.
Definition: Message.cpp:162
MSG::NIL
Definition: IMessageSvc.h:16
std::ostringstream::str
T str(T...args)
IMessageSvc.h
Message::EVTNUM
static const char EVTNUM
Definition: Message.h:168
Time.h
std::string::clear
T clear(T...args)
Message::operator==
friend bool operator==(const Message &a, const Message &b)
Insert the message into a stream.
Definition: Message.cpp:143
std::move
T move(T...args)
LIKELY
#define LIKELY(x)
Definition: Kernel.h:127
Timing.h
Message::m_width
int m_width
The current field width.
Definition: Message.h:113
Message::TIME
static const char TIME
The character used to indicate that the message timestamp should be printed.
Definition: Message.h:136
Message::m_format
std::string m_format
The format string.
Definition: Message.h:98
Gaudi::Hive::currentContextEvt
GAUDI_API ContextIdType currentContextEvt()
Definition: ThreadLocalContext.cpp:23
std::string::length
T length(T...args)
Message::setFormat
void setFormat(std::string msg) const
Set the format string.
Definition: Message.cpp:171
Message::JUSTIFY_RIGHT
static const char JUSTIFY_RIGHT
The character used to indicate start of right text justification.
Definition: Message.h:127
Message::UTIME
static const char UTIME
The character used to indicate that the message timestamp should be printed in UTC time...
Definition: Message.h:140
Gaudi::Functional::operator()
virtual Out operator()(const vector_of_const_< In > &inputs) const =0
Message
The Message class.
Definition: Message.h:15
Message::SLOT
static const char SLOT
For slot and event number from EventContext.
Definition: Message.h:167
std::string::begin
T begin(T...args)
Message::m_ecThrd
pthread_t m_ecThrd
Definition: Message.h:173
std::all_of
T all_of(T...args)
Message::FILL
static const char FILL
The character used to indicate that the previous character is to be used for padding out fields if th...
Definition: Message.h:148
Message::makeFormattedMsg
void makeFormattedMsg(const std::string &format) const
Format the message.
Definition: Message.cpp:214
MSG
Print levels enumeration.
Definition: IMessageSvc.h:14
SET
#define SET(x)
Message::setTimeFormat
void setTimeFormat(std::string timeFormat) const
Set the time format string.
Definition: Message.cpp:203
GaudiMP.FdsRegistry.msg
msg
Definition: FdsRegistry.py:8
std::hex
T hex(T...args)
MSG::ERROR
Definition: IMessageSvc.h:16
std::string::substr
T substr(T...args)
Message::sizeField
void sizeField(const std::string &text) const
Truncate or pad the output string to the field width as necessary.
Definition: Message.cpp:404
Message::getSource
const std::string & getSource() const
Get the message source.
Definition: Message.cpp:103
gaudirun.level
level
Definition: gaudirun.py:271
Message::getTimeFormat
const std::string & getTimeFormat() const
Get the time format string.
Definition: Message.cpp:186
MSG::WARNING
Definition: IMessageSvc.h:16
Message::DEFAULT_FORMAT
static constexpr const char * DEFAULT_FORMAT
The default message format.
Definition: Message.h:160
MSG::INFO
Definition: IMessageSvc.h:16
Message::FORMAT_PREFIX
static const char FORMAT_PREFIX
Formatting string characters.
Definition: Message.h:121
Message::m_source
std::string m_source
The source.
Definition: Message.h:95
std::ostream
STL class.
Message::WIDTH
static const char WIDTH
The character used to indicate that the previous decimal characters should be taken as the field widt...
Definition: Message.h:153
std::stoi
T stoi(T...args)
Message::SOURCE
static const char SOURCE
The character used to indicate that the message source should be printed.
Definition: Message.h:143
MSG::ALWAYS
Definition: IMessageSvc.h:16
Message::DEFAULT_TIME_FORMAT
static constexpr const char * DEFAULT_TIME_FORMAT
The default time format.
Definition: Message.h:164
Gaudi::Time::format
std::string format(bool local, std::string spec="%c") const
Format the time using strftime.
Definition: Time.cpp:260
Message::getMessage
const std::string & getMessage() const
Get the message string.
Definition: Message.cpp:71
Message::m_type
int m_type
The type.
Definition: Message.h:104
Message.h