00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "CeylanLogAggregatorConsole.h"
00028
00029
00030 #include "CeylanLogChannel.h"
00031 #include "CeylanLogMessage.h"
00032 #include "CeylanLogLight.h"
00033 #include "CeylanLog.h"
00034
00035 #include "CeylanOperators.h"
00036 #include "CeylanTimestamp.h"
00037 #include "CeylanStringUtils.h"
00038 #include "CeylanConsole.h"
00039
00040
00041 #include <iostream>
00042
00043
00044 using std::string ;
00045 using std::list ;
00046
00047 using namespace Ceylan::Log ;
00048 using namespace Ceylan::System ;
00049
00050
00051
00052 #ifdef CEYLAN_USES_CONFIG_H
00053 #include "CeylanConfig.h"
00054 #endif // CEYLAN_USES_CONFIG_H
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 LogAggregatorConsole::LogAggregatorConsole(
00072 StandardStream consoleStream,
00073 bool immediateWrite,
00074 bool useGlobalLevelOfDetail,
00075 bool beSmart ) :
00076 LogAggregator( beSmart, useGlobalLevelOfDetail ),
00077 _streamNumber( consoleStream ),
00078 _outputStream( 0 ),
00079 _console( 0 ),
00080 _immediateWrite( immediateWrite )
00081 {
00082
00083 #if CEYLAN_ARCH_NINTENDO_DS
00084
00085
00086 _console = new System::Console( false ) ;
00087
00088
00089 if ( _immediateWrite )
00090 _console->setToForeground( true ) ;
00091
00092 #else // CEYLAN_ARCH_NINTENDO_DS
00093
00094 switch( consoleStream )
00095 {
00096
00097 case Output:
00098 _outputStream = & std::cout ;
00099 break ;
00100
00101 case Error:
00102 _outputStream = & std::cerr ;
00103 break ;
00104
00105 case Log:
00106 _outputStream = & std::clog ;
00107 break ;
00108
00109 default:
00110 throw LogAggregatorException(
00111 "LogAggregatorConsole constructor: "
00112 "unknown console stream selected." ) ;
00113 break ;
00114
00115 }
00116
00117 #endif // CEYLAN_ARCH_NINTENDO_DS
00118
00119 }
00120
00121
00122
00123 LogAggregatorConsole::~LogAggregatorConsole() throw()
00124 {
00125
00126 CEYLAN_LOG( "LogAggregatorConsole destructor called." ) ;
00127
00128
00129 if ( _beSmart )
00130 {
00131
00132 CEYLAN_LOG( "LogAggregatorConsole is smart, therefore "
00133 "automatically triggers log aggregation on exit." ) ;
00134
00135 try
00136 {
00137 aggregate() ;
00138 }
00139 catch( const LogAggregatorException & e )
00140 {
00141
00142 std::cerr << "Error while aggregating logs in "
00143 "LogAggregatorConsole destructor: "
00144 << e.toString() << "." << std::endl ;
00145
00146
00147 }
00148
00149 }
00150
00151
00152 if ( _console != 0 )
00153 {
00154
00155 try
00156 {
00157
00158
00159 _console->goInteractive() ;
00160
00161
00162 _console->blankBuffer() ;
00163 _console->addInBuffer( "Log system stopped on user request." ) ;
00164
00165
00166 }
00167 catch( const System::Console::ConsoleException & e )
00168 {
00169
00170 display( "LogAggregatorConsole shutdown failed: " + e.toString() ) ;
00171
00172 }
00173
00174
00175 delete _console ;
00176
00177 }
00178
00179 }
00180
00181
00182
00183 void LogAggregatorConsole::aggregate()
00184 {
00185
00186
00187 if ( _immediateWrite )
00188 {
00189 CEYLAN_LOG( "LogAggregatorConsole::aggregate: "
00190 "write mode is immediate, nothing to do." ) ;
00191 return ;
00192 }
00193
00194 CEYLAN_LOG( "LogAggregatorConsole aggregation started" ) ;
00195
00196 #if CEYLAN_ARCH_NINTENDO_DS
00197
00198 #ifdef CEYLAN_RUNS_ON_ARM7
00199
00200
00201 throw UtilsException( "LogAggregatorConsole::aggregate: "
00202 "not available on the Nintendo DS ARM7." ) ;
00203
00204 #else // CEYLAN_RUNS_ON_ARM7
00205
00206
00207
00208
00209
00210
00211
00212 return ;
00213
00214 #endif // CEYLAN_RUNS_ON_ARM7
00215
00216 #else // CEYLAN_ARCH_NINTENDO_DS
00217
00218 Timestamp stamp ;
00219
00220 (*_outputStream) << stamp.toString() + " Aggregating Log messages.\n\n" ;
00221
00222 for ( list<LogChannel *>::const_iterator it = _channelList.begin() ;
00223 it != _channelList.end() ; it++ )
00224 {
00225 (*_outputStream) << * (*it) ;
00226 }
00227
00228 (*_outputStream) << stamp.toString() + " Log messages aggregated." ;
00229
00230 #endif // CEYLAN_ARCH_NINTENDO_DS
00231
00232 }
00233
00234
00235
00236 void LogAggregatorConsole::store( LogMessage & message )
00237 {
00238
00239 CEYLAN_LOG( "Storing a new message " + message.toString() ) ;
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 #if CEYLAN_ARCH_NINTENDO_DS
00252
00253 #ifdef CEYLAN_RUNS_ON_ARM7
00254
00255
00256 throw LogException( "LogAggregatorConsole::store: "
00257 "not available on the Nintendo DS ARM7." ) ;
00258
00259 #else // CEYLAN_RUNS_ON_ARM7
00260
00261
00262
00263
00264
00265
00266
00267
00268 write( message ) ;
00269
00270
00271 #endif // CEYLAN_RUNS_ON_ARM7
00272
00273 #else // CEYLAN_ARCH_NINTENDO_DS
00274
00275 if ( _immediateWrite )
00276 write( message ) ;
00277 else
00278 LogAggregator::store( message ) ;
00279
00280 #endif // CEYLAN_ARCH_NINTENDO_DS
00281
00282 }
00283
00284
00285
00286 void LogAggregatorConsole::write( const LogChannel & channel ) const
00287 {
00288
00289 CEYLAN_LOG( "Writing on console channel " + channel.toString() ) ;
00290
00291 #if CEYLAN_ARCH_NINTENDO_DS
00292
00293 _console->addInBuffer( channel.toString( getOverallVerbosityLevel() ) ) ;
00294
00295 #else // CEYLAN_ARCH_NINTENDO_DS
00296
00297 (*_outputStream) << '\t'
00298 + channel.toString( getOverallVerbosityLevel() ) ;
00299 (*_outputStream) << "\n" ;
00300
00301 #endif // CEYLAN_ARCH_NINTENDO_DS
00302
00303 }
00304
00305
00306
00307 void LogAggregatorConsole::write( const LogMessage & message ) const
00308 {
00309
00310 CEYLAN_LOG( "Writing on console message " + message.toString() ) ;
00311
00312 #if CEYLAN_ARCH_NINTENDO_DS
00313
00314 _console->addInBuffer(
00315 message.toString( getMessageVerbosityLevel( message ) ) ) ;
00316
00317 #else // CEYLAN_ARCH_NINTENDO_DS
00318
00319 (*_outputStream) <<
00320 message.toString( getMessageVerbosityLevel( message ) ) + '\n' ;
00321
00322 #endif // CEYLAN_ARCH_NINTENDO_DS
00323
00324 }
00325
00326
00327
00328 const string LogAggregatorConsole::toString( Ceylan::VerbosityLevels level )
00329 const
00330 {
00331
00332 string res = string( "This is LogAggregatorConsole in " )
00333 + ( _immediateWrite ? "": "non-" )
00334 + string( "immediate mode. It " )
00335 + ( _useGlobalLevelOfDetail ? "uses" : "does not use" )
00336 + string( " a global level of detail for message output. It uses " ) ;
00337
00338 #if CEYLAN_ARCH_NINTENDO_DS
00339
00340 res += "a Ceylan text console" ;
00341
00342 #else // CEYLAN_ARCH_NINTENDO_DS
00343
00344 switch( _streamNumber )
00345 {
00346
00347 case Output:
00348 res += "the standard output stream" ;
00349 break ;
00350
00351 case Error:
00352 res += "the standard error stream" ;
00353 break ;
00354
00355 case Log:
00356 res += "the standard log stream" ;
00357 break ;
00358
00359 default:
00360 res += "an unknown stream (abnormal)" ;
00361 break ;
00362
00363 }
00364
00365 #endif // CEYLAN_ARCH_NINTENDO_DS
00366
00367 res += ". " + LogAggregator::toString( level ) ;
00368
00369 return res ;
00370
00371 }
00372