| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

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

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
MessageSvc.cpp
Go to the documentation of this file.
1 #ifdef _WIN32
2 // Avoid conflicts between windows and the message service.
3 #define NOMSG
4 #define NOGDI
5 #endif
6
7 #include "GaudiKernel/Kernel.h"
8 #include "GaudiKernel/StatusCode.h"
9 #include "GaudiKernel/Message.h"
10 #include "GaudiKernel/xtoa.h"
11 #include "MessageSvc.h"
12
13 #include <sstream>
14 #include <iostream>
15 #include <fstream>
16
17 using namespace std;
18
19 // Instantiation of a static factory class used by clients to create
20 // instances of this service
21 DECLARE_COMPONENT(MessageSvc)
22
23 static std::string levelNames[MSG::NUM_LEVELS];
24
25 // Constructor
26 MessageSvc::MessageSvc( const std::string& name, ISvcLocator* svcloc )
27 : base_class( name, svcloc ) {
28 m_defaultStream = &std::cout;
29 m_outputLevel = MSG::NIL;
30 declareProperty( "Format", m_defaultFormat = Message::getDefaultFormat() );
31 declareProperty( "timeFormat", m_defaultTimeFormat = Message::getDefaultTimeFormat() );
32 declareProperty( "showStats", m_stats = false );
33 declareProperty( "statLevel", m_statLevel = 0 );
34
35 // Special properties to control output level of individual sources
36 declareProperty( "setVerbose", m_thresholdProp[MSG::VERBOSE] );
37 declareProperty( "setDebug", m_thresholdProp[MSG::DEBUG] );
38 declareProperty( "setInfo", m_thresholdProp[MSG::INFO] );
39 declareProperty( "setWarning", m_thresholdProp[MSG::WARNING] );
40 declareProperty( "setError", m_thresholdProp[MSG::ERROR] );
41 declareProperty( "setFatal", m_thresholdProp[MSG::FATAL] );
42 declareProperty( "setAlways", m_thresholdProp[MSG::ALWAYS] );
43
44 declareProperty( "useColors", m_color=false);
45 m_color.declareUpdateHandler(&MessageSvc::initColors, this);
46
47 declareProperty( "fatalColorCode", m_logColors[MSG::FATAL] );
48 declareProperty( "errorColorCode", m_logColors[MSG::ERROR] );
49 declareProperty( "warningColorCode", m_logColors[MSG::WARNING] );
50 declareProperty( "infoColorCode", m_logColors[MSG::INFO] );
51 declareProperty( "debugColorCode", m_logColors[MSG::DEBUG] );
52 declareProperty( "verboseColorCode", m_logColors[MSG::VERBOSE] );
53 declareProperty( "alwaysColorCode", m_logColors[MSG::ALWAYS] );
54
55 const int defaultLimit = 500;
56 declareProperty( "fatalLimit", m_msgLimit[MSG::FATAL] = defaultLimit );
57 declareProperty( "errorLimit", m_msgLimit[MSG::ERROR] = defaultLimit );
58 declareProperty( "warningLimit", m_msgLimit[MSG::WARNING] = defaultLimit );
59 declareProperty( "infoLimit", m_msgLimit[MSG::INFO] = defaultLimit );
60 declareProperty( "debugLimit", m_msgLimit[MSG::DEBUG] = defaultLimit );
61 declareProperty( "verboseLimit", m_msgLimit[MSG::VERBOSE] = defaultLimit );
62 declareProperty( "alwaysLimit", m_msgLimit[MSG::ALWAYS] = 0 );
63
64 declareProperty( "defaultLimit", m_msgLimit[MSG::NIL] = defaultLimit );
65
66 declareProperty( "enableSuppression", m_suppress = false );
67 declareProperty( "countInactive", m_inactCount = false )->declareUpdateHandler( &MessageSvc::setupInactCount, this );
68 #ifndef NDEBUG
69 // initialize the MsgStream static flag.
70 MsgStream::enableCountInactive(m_inactCount);
71 #endif
72
73 declareProperty( "loggedStreams",
74 m_loggedStreamsName,
75 "MessageStream sources we want to dump into a logfile" );
76
77 for (int ic=0; ic<MSG::NUM_LEVELS; ++ic) {
78 m_logColors[ic].declareUpdateHandler(&MessageSvc::setupColors, this);
79 m_msgLimit[ic].declareUpdateHandler(&MessageSvc::setupLimits, this);
80 m_thresholdProp[ic].declareUpdateHandler(&MessageSvc::setupThreshold, this);
81 }
82
83 levelNames[0] = "NIL";
84 levelNames[1] = "VERBOSE";
85 levelNames[2] = "DEBUG";
86 levelNames[3] = "INFO";
87 levelNames[4] = "WARNING";
88 levelNames[5] = "ERROR";
89 levelNames[6] = "FATAL";
90 levelNames[7] = "ALWAYS";
91
92 for (int i=0; i<MSG::NUM_LEVELS; ++i) {
93 m_msgCount[i] = 0;
94 }
95
96 }
97
98 //#############################################################################
99
100 MessageSvc::~MessageSvc()
101 {
102 // closing log-files, if any
103 LoggedStreamsMap_t::iterator iStream = m_loggedStreams.begin();
104 LoggedStreamsMap_t::iterator endStream = m_loggedStreams.end();
105 for ( ; iStream != endStream; ++iStream ) {
106 delete iStream->second;
107 iStream->second = 0;
108 }
109 }
110 //#############################################################################
111
112
114 StatusCode MessageSvc::initialize() {
115 StatusCode sc;
116 sc = Service::initialize();
117 if( sc.isFailure() ) return sc;
118 // Release pointer to myself done in Service base class
119 //if( m_msgsvc.isValid() ) {
120 // m_msgsvc = 0;
121 //}
122 // Set my own properties
123 sc = setProperties();
124 if (sc.isFailure()) return sc;
125
126 #ifdef _WIN32
127 m_color = false;
128 #endif
129
130 m_colMap["black"] = MSG::BLACK;
131 m_colMap["red"] = MSG::RED;
132 m_colMap["green"] = MSG::GREEN;
133 m_colMap["yellow"] = MSG::YELLOW;
134 m_colMap["blue"] = MSG::BLUE;
135 m_colMap["purple"] = MSG::PURPLE;
136 m_colMap["cyan"] = MSG::CYAN;
137 m_colMap["white"] = MSG::WHITE;
138
139 // make sure the map of logged stream names is initialized
140 setupLogStreams();
141
142 return StatusCode::SUCCESS;
143 }
144
145 //#############################################################################
146
148 StatusCode MessageSvc::reinitialize() {
149 m_state = Gaudi::StateMachine::OFFLINE;
150 return initialize();
151 }
152
153 //#############################################################################
154
155 void MessageSvc::initColors(Property& /*prop*/) {
156
157 if (m_color == true) {
158
159 if (m_logColors[MSG::FATAL].value().size() == 0) {
160 vector<string> fatDef;
161 fatDef.push_back( "[94;101;1m" );
162 m_logColors[MSG::FATAL].set( fatDef );
163 } else {
164 MessageSvc::setupColors( m_logColors[MSG::FATAL] );
165 }
166
167 if (m_logColors[MSG::ERROR].value().size() == 0) {
168 vector<string> errDef;
169 errDef.push_back( "[97;101;1m" );
170 m_logColors[MSG::ERROR].set( errDef );
171 } else {
172 MessageSvc::setupColors( m_logColors[MSG::ERROR] );
173 }
174
175 if (m_logColors[MSG::WARNING].value().size() == 0) {
176 vector<string> warDef;
177 warDef.push_back( "[93;1m" );
178 m_logColors[MSG::WARNING].set( warDef );
179 } else {
180 MessageSvc::setupColors( m_logColors[MSG::WARNING] );
181 }
182
183 } else {
184
185 // reset all color codes;
186 for (int ic=0; ic<MSG::NUM_LEVELS; ++ic) {
187 vector<string> def;
188 m_logColors[ic].set( def );
189 }
190
191 }
192
193 }
194
195 //#############################################################################
196
197 void MessageSvc::setupColors(Property& prop) {
198
199 if (! m_color) return;
200
201 int ic;
202 if (prop.name() == "fatalColorCode") {
203 ic = MSG::FATAL;
204 } else if (prop.name() == "errorColorCode") {
205 ic = MSG::ERROR;
206 } else if (prop.name() == "warningColorCode") {
207 ic = MSG::WARNING;
208 } else if (prop.name() == "infoColorCode") {
209 ic = MSG::INFO;
210 } else if (prop.name() == "debugColorCode") {
211 ic = MSG::DEBUG;
212 } else if (prop.name() == "verboseColorCode") {
213 ic = MSG::VERBOSE;
214 } else if (prop.name() == "alwaysColorCode") {
215 ic = MSG::ALWAYS;
216 } else {
217 cout << "ERROR: Unknown message color parameter: " << prop.name()
218 << endl;
219 return;
220 }
221
222 string code;
223 vector<string>::const_iterator itr;
224 itr = m_logColors[ic].value().begin();
225
226 if ( m_logColors[ic].value().size() == 1 ) {
227
228 if (*itr == "") {
229 code = "";
230 } else if (itr->substr(0,1) == "[") {
231 code = "\033" + *itr;
232 } else {
233 code = "\033[" + colTrans(*itr, 90) + ";1m";
234 }
235
236 } else if (m_logColors[ic].value().size() == 2) {
237 vector<string>::const_iterator itr2 = itr + 1;
238
239 code = "\033[" + colTrans(*itr, 90) + ";"
240 + colTrans(*itr2, 100) + ";1m";
241
242 }
243
244 m_logColorCodes[ic] = code;
245
246 }
247 //#############################################################################
248
249 void MessageSvc::setupLimits(Property& prop) {
250 // Just report problems in the settings of the limits and unknown limit parameters
251 if (prop.name() == "alwaysLimit") {
252 IntegerProperty *p = dynamic_cast<IntegerProperty*>(&prop);
253 if (p && p->value() != 0) {
254 cout << "MessageSvc ERROR: cannot suppress ALWAYS messages" << endl;
255 p->setValue(0);
256 }
257 } else if (prop.name() == "defaultLimit") {
258 for (int i = MSG::VERBOSE; i< MSG::NUM_LEVELS; ++i) {
259 if (i != MSG::ALWAYS) {
260 m_msgLimit[i] = m_msgLimit[MSG::NIL].value();
261 }
262 }
263 } else if (prop.name() != "fatalLimit" &&
264 prop.name() != "errorLimit" &&
265 prop.name() != "warningLimit" &&
266 prop.name() == "infoLimit" &&
267 prop.name() == "debugLimit" &&
268 prop.name() == "verboseLimit") {
269 cout << "MessageSvc ERROR: Unknown message limit parameter: "
270 << prop.name() << endl;
271 return;
272 }
273 }
274 //#############################################################################
275
276 void MessageSvc::setupThreshold(Property& prop) {
277
278 int ic = 0;
279 if (prop.name() == "setFatal") {
280 ic = MSG::FATAL;
281 } else if (prop.name() == "setError") {
282 ic = MSG::ERROR;
283 } else if (prop.name() == "setWarning") {
284 ic = MSG::WARNING;
285 } else if (prop.name() == "setInfo") {
286 ic = MSG::INFO;
287 } else if (prop.name() == "setDebug") {
288 ic = MSG::DEBUG;
289 } else if (prop.name() == "setVerbose") {
290 ic = MSG::VERBOSE;
291 } else if (prop.name() == "setAlways") {
292 ic = MSG::ALWAYS;
293 } else {
294 cerr << "MessageSvc ERROR: Unknown message threshold parameter: "
295 << prop.name() << endl;
296 return;
297 }
298
299 StringArrayProperty *sap = dynamic_cast<StringArrayProperty*>( &prop);
300 if (sap == 0) {
301 std::cerr << "could not dcast " << prop.name()
302 << " to a StringArrayProperty (which it should be!)" << endl;
303 return;
304 } else {
305 std::vector<std::string>::const_iterator itr;
306 for ( itr = sap->value().begin();
307 itr != sap->value().end();
308 ++itr) {
309 setOutputLevel( *itr, ic );
310 }
311 }
312
313 }
314
315 //#############################################################################
316
317 #ifdef NDEBUG
318 void MessageSvc::setupInactCount(Property&) {}
319 #else
320 void MessageSvc::setupInactCount(Property&prop) {
321 if (prop.name() == "countInactive") {
322 BooleanProperty *p = dynamic_cast<BooleanProperty*>(&prop);
323 if (p)
324 MsgStream::enableCountInactive(p->value());
325 }
326 }
327 #endif
328
329
330 //#############################################################################
332 StatusCode MessageSvc::finalize() {
333
334 m_suppress = false;
335
336 {
337 std::ostringstream os;
338
339 if (m_stats) {
340 os << "Summarizing all message counts" << endl;
341 } else {
342 os << "Listing sources of suppressed message: " << endl;
343 }
344
345 os << "=====================================================" << endl;
346 os << " Message Source | Level | Count" << endl;
347 os << "-----------------------------+---------+-------------" << endl;
348
349
350 bool found(false);
351
352 std::map<std::string,MsgAry>::const_iterator itr;
353 for (itr=m_sourceMap.begin(); itr!=m_sourceMap.end(); ++itr) {
354 for (unsigned int ic = 0; ic < MSG::NUM_LEVELS; ++ic) {
355 if ( (itr->second.msg[ic] >= m_msgLimit[ic] && m_msgLimit[ic] != 0 ) ||
356 (m_stats && itr->second.msg[ic] > 0 && ic >= m_statLevel.value()) ) {
357 os << " ";
358 os.width(28);
359 os.setf(ios_base::left,ios_base::adjustfield);
360 os << itr->first;
361
362 os << "|";
363
364 os.width(8);
365 os.setf(ios_base::right,ios_base::adjustfield);
366 os << levelNames[ic];
367
368 os << " |";
369
370 os.width(9);
371 os << itr->second.msg[ic];
372
373 os << endl;
374
375 found = true;
376 }
377 }
378 }
379 os << "=====================================================" << endl;
380
381 if (found || m_stats) {
382 cout << os.str();
383 }
384 }
385
386 #ifndef NDEBUG
387 if (m_inactCount.value()) {
388
389 std::ostringstream os;
390 os << "Listing sources of Unprotected and Unseen messages\n";
391
392 bool found(false);
393
394 unsigned int ml(0);
395 std::map<std::string,MsgAry>::const_iterator itr;
396 for (itr=m_inactiveMap.begin(); itr!=m_inactiveMap.end(); ++itr) {
397 for (unsigned int ic = 0; ic < MSG::NUM_LEVELS; ++ic) {
398 if (itr->second.msg[ic] != 0) {
399 if (itr->first.length() > ml) { ml = itr->first.length(); }
400 }
401 }
402 }
403
404 for (unsigned int i=0; i<ml+25; ++i) {
405 os << "=";
406 }
407
408 os << endl << " ";
409 os.width(ml+2);
410 os.setf(ios_base::left,ios_base::adjustfield);
411 os << "Message Source";
412 os.width(1);
413 os << "| Level | Count" << endl;
414
415 for (unsigned int i=0; i<ml+3; ++i) {
416 os << "-";
417 }
418 os << "+---------+-----------" << endl;
419
420
421 for (itr=m_inactiveMap.begin(); itr!=m_inactiveMap.end(); ++itr) {
422 for (unsigned int ic = 0; ic < MSG::NUM_LEVELS; ++ic) {
423 if (itr->second.msg[ic] != 0) {
424 os << " ";
425 os.width(ml+2);
426 os.setf(ios_base::left,ios_base::adjustfield);
427 os << itr->first;
428
429 os << "|";
430
431 os.width(8);
432 os.setf(ios_base::right,ios_base::adjustfield);
433 os << levelNames[ic];
434
435 os << " |";
436
437 os.width(9);
438 os << itr->second.msg[ic];
439
440 os << endl;
441
442 found = true;
443 }
444 }
445 }
446 for (unsigned int i=0; i<ml+25; ++i) {
447 os << "=";
448 }
449 os << endl;
450
451 if (found) {
452 cout << os.str();
453 }
454 }
455 #endif
456
457 return StatusCode::SUCCESS;
458 }
459
460 //#############################################################################
461 std::string MessageSvc::colTrans(std::string col, int offset) {
462 ColorMap::const_iterator itr = m_colMap.find(col);
463 int icol;
464 if (itr != m_colMap.end()) {
465 icol = offset + itr->second;
466 } else {
467 icol = offset + 8;
468 }
469 std::ostringstream os1;
470
471 os1 << icol;
472
473 return os1.str();
474
475 }
476
477 //#############################################################################
478 // ---------------------------------------------------------------------------
479 // Routine: reportMessage
480 // Purpose: dispatches a message to the relevant streams.
481 // ---------------------------------------------------------------------------
482 //
483
484 void MessageSvc::reportMessage( const Message& msg, int outputLevel ) {
485 boost::recursive_mutex::scoped_lock lock(m_reportMutex);
486
487 int key = msg.getType();
488
489 m_msgCount[key] ++;
490
491 const Message *cmsg = &msg;
492
493 // processing logged streams
494 if ( !m_loggedStreams.empty() ) {
495 const LoggedStreamsMap_t::iterator iLog = m_loggedStreams.find( msg.getSource() );
496 if ( m_loggedStreams.end() != iLog ) {
497 (*iLog->second) << *cmsg << std::endl;
498 }
499 }
500
501 if ( m_suppress.value() || m_stats.value() ) {
502
503 // Increase the counter of 'key' type of messages for the source and
504 // get the new value.
505 const int nmsg = ++(m_sourceMap[msg.getSource()].msg[key]);
506
507 if (m_suppress.value()) {
508
509 if ( m_msgLimit[key] != 0 ) {
510 if (nmsg == m_msgLimit[key]) {
511 std::ostringstream txt;
512 txt << levelNames[key] << " message limit ("
513 << m_msgLimit[key].value()
514 << ") reached for "
515 << msg.getSource() + ". Suppressing further output.";
516 cmsg = new Message(msg.getSource(), MSG::WARNING, txt.str());
517 cmsg->setFormat(msg.getFormat());
518 } else if (nmsg > m_msgLimit[key]) {
519 return;
520 }
521 }
522 }
523
524 }
525
526 StreamMap::const_iterator first = m_streamMap.lower_bound( key );
527 if ( first != m_streamMap.end() ) {
528 StreamMap::const_iterator last = m_streamMap.upper_bound( key );
529 while( first != last ) {
530 std::ostream& stream = *( (*first).second.second );
531 stream << *cmsg << std::endl;
532 first++;
533 }
534 }
535 else if ( key >= outputLevel ) {
536 msg.setFormat(m_defaultFormat);
537 msg.setTimeFormat(m_defaultTimeFormat);
538 if (!m_color) {
539 (*m_defaultStream) << *cmsg << std::endl << std::flush;
540 } else {
541 (*m_defaultStream) << m_logColorCodes[key] << *cmsg << "\033[m"
542 << std::endl << std::flush;
543 }
544 }
545
546 if (cmsg != &msg) { delete cmsg; }
547
548 }
549
550 //#############################################################################
551 // ---------------------------------------------------------------------------
552 // Routine: reportMessage
553 // Purpose: dispatches a message to the relevant streams.
554 // ---------------------------------------------------------------------------
555 //
556 void MessageSvc::reportMessage( const Message& msg ) {
557 reportMessage(msg, outputLevel(msg.getSource()));
558 }
559
560 //#############################################################################
561 // ---------------------------------------------------------------------------
562 // Routine: reportMessage
563 // Purpose: dispatches a message to the relevant streams.
564 // ---------------------------------------------------------------------------
565 //
566 void MessageSvc::reportMessage (const char* source,
567 int type,
568 const char* message) {
569 Message msg( source, type, message);
570 reportMessage( msg );
571 }
572
573 //#############################################################################
574 // ---------------------------------------------------------------------------
575 // Routine: reportMessage
576 // Purpose: dispatches a message to the relevant streams.
577 // ---------------------------------------------------------------------------
578 //
579 void MessageSvc::reportMessage (const std::string& source,
580 int type,
581 const std::string& message) {
582 Message msg( source, type, message);
583 reportMessage( msg );
584 }
585
586 //#############################################################################
587 // ---------------------------------------------------------------------------
588 // Routine: sendMessage
589 // Purpose: finds a message for a given status code and dispatches it.
590 // ---------------------------------------------------------------------------
591 //
592
593 void MessageSvc::reportMessage (const StatusCode& key,
594 const std::string& source)
595 {
596 boost::recursive_mutex::scoped_lock lock(m_messageMapMutex);
597
598 MessageMap::const_iterator first = m_messageMap.lower_bound( key );
599 if ( first != m_messageMap.end() ) {
600 MessageMap::const_iterator last = m_messageMap.upper_bound( key );
601 while( first != last ) {
602 Message msg = (*first).second;
603 msg.setSource( source );
604 std::ostringstream os1;
605 os1 << "Status Code " << key.getCode() << std::ends;
606 Message stat_code1( source, msg.getType(), os1.str() );
607 reportMessage( stat_code1 );
608 reportMessage( msg );
609 first++;
610 }
611 }
612 else {
613 Message mesg = m_defaultMessage;
614 mesg.setSource( source );
615 std::ostringstream os2;
616 os2 << "Status Code " << key.getCode() << std::ends;
617 Message stat_code2( source, mesg.getType(), os2.str() );
618 reportMessage( stat_code2 );
619 reportMessage( mesg );
620 }
621 }
622
623 //#############################################################################
624 // ---------------------------------------------------------------------------
625 // Routine: insertStream
626 // Purpose: inserts a stream for a message type.
627 // ---------------------------------------------------------------------------
628 //
629
630 void MessageSvc::insertStream (int key,
631 const std::string& name,
632 std::ostream *stream)
633 {
634 typedef StreamMap::value_type value_type;
635 m_streamMap.insert( value_type( key, NamedStream(name,stream) ) );
636 }
637
638 //#############################################################################
639 // ---------------------------------------------------------------------------
640 // Routine: eraseStream
641 // Purpose: erases all the streams for all the message types.
642 // ---------------------------------------------------------------------------
643 //
644
645 void MessageSvc::eraseStream()
646 {
647 m_streamMap.erase( m_streamMap.begin(), m_streamMap.end() );
648 }
649
650 //#############################################################################
651 // ---------------------------------------------------------------------------
652 // Routine: eraseStream
653 // Purpose: erases all the streams for a message type.
654 // ---------------------------------------------------------------------------
655 //
656
657 void MessageSvc::eraseStream( int message_type )
658 {
659 m_streamMap.erase( message_type );
660 }
661
662 //#############################################################################
663 // ---------------------------------------------------------------------------
664 // Routine: eraseStream
665 // Purpose: erases one stream for a message type.
666 // ---------------------------------------------------------------------------
667 //
668
669 void MessageSvc::eraseStream( int key, std::ostream* stream ) {
670 if ( 0 != stream ) {
671 bool changed = true;
672 while( changed ) {
673 changed = false;
674 StreamMap::iterator first = m_streamMap.lower_bound( key );
675 StreamMap::iterator last = m_streamMap.upper_bound( key );
676 while( first != last ) {
677 if ( (*first).second.second == stream ) {
678 m_streamMap.erase( first );
679 changed = true;
680 break;
681 }
682 }
683 }
684 }
685 }
686
687 //#############################################################################
688 // ---------------------------------------------------------------------------
689 // Routine: eraseStream
690 // Purpose: erases one stream for all message types.
691 // ---------------------------------------------------------------------------
692 //
693
694 void MessageSvc::eraseStream( std::ostream* stream ) {
695 if ( 0 != stream ) {
696 bool changed = true;
697 while( changed ) {
698 changed = false;
699 StreamMap::iterator first = m_streamMap.begin();
700 while( first != m_streamMap.end() ) {
701 if ( (*first).second.second == stream ) {
702 m_streamMap.erase( first );
703 changed = true;
704 break;
705 }
706 }
707 }
708 }
709 }
710
711
712 //#############################################################################
713 // ---------------------------------------------------------------------------
714 // Routine: insertMessage
715 // Purpose: inserts a message for a status code.
716 // ---------------------------------------------------------------------------
717 //
718
719 void MessageSvc::insertMessage( const StatusCode& key, const Message& msg )
720 {
721 boost::recursive_mutex::scoped_lock lock(m_messageMapMutex);
722
723 typedef MessageMap::value_type value_type;
724 m_messageMap.insert( value_type( key, msg ) );
725 }
726
727 //#############################################################################
728 // ---------------------------------------------------------------------------
729 // Routine: eraseMessage
730 // Purpose: erases all the messages for all the status codes.
731 // ---------------------------------------------------------------------------
732 //
733
734 void MessageSvc::eraseMessage()
735 {
736 boost::recursive_mutex::scoped_lock lock(m_messageMapMutex);
737
738 m_messageMap.erase( m_messageMap.begin(), m_messageMap.end() );
739 }
740
741 //#############################################################################
742 // ---------------------------------------------------------------------------
743 // Routine: eraseMessage
744 // Purpose: erases all the messages for a status code.
745 // ---------------------------------------------------------------------------
746 //
747
748 void MessageSvc::eraseMessage( const StatusCode& key )
749 {
750 boost::recursive_mutex::scoped_lock lock(m_messageMapMutex);
751
752 m_messageMap.erase( key );
753 }
754
755 //#############################################################################
756 // ---------------------------------------------------------------------------
757 // Routine: eraseMessage
758 // Purpose: erases one message for a status code.
759 // ---------------------------------------------------------------------------
760 //
761
762 void MessageSvc::eraseMessage( const StatusCode& key, const Message& msg )
763 {
764 boost::recursive_mutex::scoped_lock lock(m_messageMapMutex);
765
766 bool changed = true;
767 while( changed ) {
768 changed = false;
769 MessageMap::iterator first = m_messageMap.lower_bound( key );
770 MessageMap::iterator last = m_messageMap.upper_bound( key );
771 while( first != last ) {
772 const Message& message = (*first).second;
773 if ( message == msg ) {
774 m_messageMap.erase( first );
775 changed = true;
776 break;
777 }
778 }
779 }
780 }
781
782 // ---------------------------------------------------------------------------
783 int MessageSvc::outputLevel() const {
784 // ---------------------------------------------------------------------------
785 return m_outputLevel;
786 }
787
788 // ---------------------------------------------------------------------------
789 int MessageSvc::outputLevel( const std::string& source ) const {
790 // ---------------------------------------------------------------------------
791 boost::recursive_mutex::scoped_lock lock(m_thresholdMapMutex);
792
793 ThresholdMap::const_iterator it;
794
795 it = m_thresholdMap.find( source );
796 if( it != m_thresholdMap.end() ) {
797 return (*it).second;
798 }
799 else {
800 return m_outputLevel;
801 }
802 }
803
804 // ---------------------------------------------------------------------------
805 void MessageSvc::setOutputLevel(int new_level) {
806 // ---------------------------------------------------------------------------
807 m_outputLevel = new_level;
808 }
809
810 // ---------------------------------------------------------------------------
811 void MessageSvc::setOutputLevel(const std::string& source, int level) {
812 // ---------------------------------------------------------------------------
813 boost::recursive_mutex::scoped_lock lock(m_thresholdMapMutex);
814
815 /*
816 std::pair<ThresholdMap::iterator, bool> p;
817 p = m_thresholdMap.insert(ThresholdMap::value_type( source, level) );
818 if( p.second == false ) {
819 // Already esisting an output level for that source. Erase and enter it again
820 m_thresholdMap.erase ( p.first );
821 m_thresholdMap.insert(ThresholdMap::value_type( source, level) );
822 }
823 */
824 m_thresholdMap[source] = level;
825 }
826
827 // ---------------------------------------------------------------------------
828 std::string MessageSvc::getLogColor(int logLevel) const {
829 // ---------------------------------------------------------------------------
830 if (logLevel < MSG::NUM_LEVELS) {
831 return m_logColorCodes[logLevel];
832 } else {
833 return "";
834 }
835 }
836
837 // ---------------------------------------------------------------------------
838 int MessageSvc::messageCount( MSG::Level level) const {
839
840 return m_msgCount[level];
841
842 }
843
844 // ---------------------------------------------------------------------------
845 void
846 MessageSvc::incrInactiveCount(MSG::Level level, const std::string& source) {
847
848 ++(m_inactiveMap[source].msg[level]);
849
850 }
851
852 // ---------------------------------------------------------------------------
853 void MessageSvc::setupLogStreams()
854 {
855 // reset state
856 for ( LoggedStreamsMap_t::iterator iLog = m_loggedStreams.begin();
857 iLog != m_loggedStreams.end();
858 ++iLog ) {
859 delete iLog->second;
860 }
861 m_loggedStreams.clear();
862
863 typedef std::map<std::string,std::string> StreamMap_t;
864 const StreamMap_t& streamMap = m_loggedStreamsName;
865 typedef StreamMap_t::const_iterator StreamMapIter;
866
867 for ( StreamMapIter iProp = streamMap.begin(), iEnd = streamMap.end();
868 iProp != iEnd;
869 ++iProp ) {
870
871 const std::string sourceName = iProp->first;
872 const std::string outFileName = iProp->second;
873
874 std::set<std::string> outFileNames;
875 for ( StreamMapIter jProp = streamMap.begin();
876 jProp != iEnd;
877 ++jProp ) {
878 if ( jProp->first != iProp->first ) {
879 outFileNames.insert( jProp->second );
880 }
881 }
882
883 tee( sourceName, outFileName, outFileNames );
884
885 }//> loop over property entries
886
887 return;
888 }
889
890 // ---------------------------------------------------------------------------
891 void MessageSvc::tee( const std::string& sourceName,
892 const std::string& outFileName,
893 const std::set<std::string>& outFileNames )
894 {
895 const std::ios_base::openmode openMode = std::ios_base::out |
896 std::ios_base::trunc;
897
898 LoggedStreamsMap_t::iterator iEnd = m_loggedStreams.end();
899 LoggedStreamsMap_t::iterator iStream = m_loggedStreams.find( sourceName );
900 if ( iStream != iEnd ) {
901 delete iStream->second;
902 iStream->second = 0;
903 m_loggedStreams.erase( iStream );
904 }
905
906 // before creating a new ofstream, make sure there is no already existing
907 // one with the same file name...
908 iEnd = m_loggedStreams.end();
909 for ( iStream = m_loggedStreams.begin(); iStream != iEnd; ++iStream ) {
910 if ( outFileNames.find( outFileName ) != outFileNames.end() ) {
911 m_loggedStreams[sourceName] = m_loggedStreams[iStream->first];
912 return;
913 }
914 }
915
916 std::ofstream * out = new std::ofstream( outFileName.c_str(), openMode );
917
918 if ( !out->good() ) {
919 out->close();
920 delete out;
921 return;
922 }
923
924 m_loggedStreams[sourceName] = out;
925
926 return;
927 }
928