radioengine/utils/api/cradioenginelogger.h
branchRCL_3
changeset 20 93c594350b9a
parent 19 cce62ebc198e
equal deleted inserted replaced
19:cce62ebc198e 20:93c594350b9a
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 #ifndef C_RADIOENGINELOGGER_H
       
    19 #define C_RADIOENGINELOGGER_H
       
    20 
       
    21 // System includes
       
    22 #include <e32base.h>
       
    23 
       
    24 // User includes
       
    25 #include "mradioenginelogger.h"
       
    26 
       
    27 /**
       
    28  * Main logging macro.
       
    29  * When the macro is defined, logging is on
       
    30  */
       
    31 #ifdef _DEBUG
       
    32     #define LOGGING_ENABLED
       
    33 #endif
       
    34 
       
    35 #define LOGGING_LEVEL 1
       
    36 
       
    37 /**
       
    38  * Logging level macro definitions
       
    39  * Level 1 - No level macro needed. The trace is shown when logging is on.
       
    40  * Level 2 - Wrap log line with LEVEL2 macro. Traces of level 1 and 2 are shown.
       
    41  * Level 3 - Wrap log line with LEVEL3 macro. Traces of level 1, 2 and 3 are shown.
       
    42  */
       
    43 #if LOGGING_LEVEL == 2
       
    44 #   define LEVEL2( expr ) expr
       
    45 #   define LEVEL3( expr )
       
    46 #elif LOGGING_LEVEL == 3
       
    47 #   define LEVEL2( expr ) expr
       
    48 #   define LEVEL3( expr ) expr
       
    49 #else
       
    50 #   define LEVEL2( expr )
       
    51 #   define LEVEL3( expr )
       
    52 #endif
       
    53 
       
    54 #ifdef LOGGING_ENABLED
       
    55 
       
    56 /**
       
    57  * Debug var macros for all logging levels
       
    58  */
       
    59 #if LOGGING_LEVEL == 2
       
    60 #   define DEBUGVAR( var ) var
       
    61 #   define DEBUGVAR2( var ) var
       
    62 #   define DEBUGVAR3( var )
       
    63 #elif LOGGING_LEVEL == 3
       
    64 #   define DEBUGVAR( var ) var
       
    65 #   define DEBUGVAR2( var ) var
       
    66 #   define DEBUGVAR3( var ) var
       
    67 #else
       
    68 #   define DEBUGVAR( var ) var
       
    69 #   define DEBUGVAR2( var )
       
    70 #   define DEBUGVAR3( var )
       
    71 #endif
       
    72 
       
    73 /**
       
    74  * Log file path.
       
    75  * If the path points to memory card and the card is not present or is read only,
       
    76  * the log is written to C: drive.
       
    77  */
       
    78 _LIT( KLogFile, "c:\\logs\\radio\\radioenginelog.txt" );
       
    79 
       
    80 /**
       
    81  * Logging buffer length. Should be big enough to hold one line of text
       
    82  */
       
    83 const TInt KLogBufferLength = 512;
       
    84 
       
    85 
       
    86 // ===========================================================================
       
    87 // ===========================================================================
       
    88 //
       
    89 // BEGIN LOGGING MACROS. Use these to write log prints
       
    90 //
       
    91 // ===========================================================================
       
    92 // ===========================================================================
       
    93 
       
    94 // All macros except LOG_METHOD and LOG_METHOD_RET are enclosed in do { }while( 0 );
       
    95 // statements to make them form a complete code block that can be used anywhere.
       
    96 
       
    97 /**
       
    98  * Function entry, exit and leave logging.
       
    99  *
       
   100  *  @code
       
   101  *   LOG_METHOD( "CSomeClass::SomeFunctionL" );
       
   102  *  @endcode
       
   103  */
       
   104 #define LOG_METHOD( func ) TRadioMethodLogger ___methodLogger( _S( func ), _S( "" ) )
       
   105 
       
   106 /**
       
   107  * Function entry, exit and leave logging.
       
   108  * Gets the function name automatically
       
   109  *
       
   110  *  @code
       
   111  *   LOG_METHOD_AUTO;
       
   112  *  @endcode
       
   113  */
       
   114 // Substract 1 from MaxLength() because PtrZ() adds the zero terminator
       
   115 #define LOG_METHOD_AUTO \
       
   116     TPtrC8 __ptr8( (const TUint8*)__PRETTY_FUNCTION__ ); \
       
   117     TBuf<150> __buf; \
       
   118     __buf.Copy( __ptr8.Left( __buf.MaxLength() - 1 ) ); \
       
   119     TRadioMethodLogger ___methodLogger( __buf.PtrZ(), _S( "" ) )
       
   120 
       
   121 /**
       
   122  * Function entry, exit and leave logging. Logs also returned value
       
   123  * NOTE! At the moment return value is only logged in emulator builds.
       
   124  *
       
   125  *  @code
       
   126  *   // Function returns an integer value
       
   127  *   LOG_METHOD_RET( "CSomeClass::SomeFunctionL", "Error: %d" );
       
   128  *
       
   129  *   // Function returns an HBufC pointer
       
   130  *   LOG_METHOD_RET( "CSomeClass::SomeFunctionL", "HBufC: %S" );
       
   131  *  @endcode
       
   132  */
       
   133 #define LOG_METHOD_RET( func,fmt ) TRadioMethodLogger ___methodLogger( _S( func ), _S( fmt ) )
       
   134 
       
   135 /**
       
   136  * Function entry, exit and leave logging. Logs also returned value
       
   137  * Gets the function name automatically
       
   138  * NOTE! At the moment return value is only logged in emulator builds.
       
   139  *
       
   140  *  @code
       
   141  *   // Function returns an integer value
       
   142  *   LOG_METHOD_RET( "CSomeClass::SomeFunctionL", "Error: %d" );
       
   143  *
       
   144  *   // Function returns an HBufC pointer
       
   145  *   LOG_METHOD_RET( "CSomeClass::SomeFunctionL", "HBufC: %S" );
       
   146  *  @endcode
       
   147  */
       
   148 // Substract 1 from MaxLength() because PtrZ() adds the zero terminator
       
   149 #define LOG_METHOD_AUTO_RET( fmt ) \
       
   150     TPtrC8 __ptr8( (const TUint8*)__PRETTY_FUNCTION__ ); \
       
   151     TBuf<150> __buf; \
       
   152     __buf.Copy( __ptr8.Left( __buf.MaxLength() - 1 ) ); \
       
   153     TRadioMethodLogger ___methodLogger( __buf.PtrZ(), _S( fmt ) )
       
   154 
       
   155 /**
       
   156  * Simple assert macro that works like normal asserts. The expression ( expr ) is
       
   157  * expected to be true in which case nothing is done. If the expression is false the
       
   158  * statement ( stmt ) is executed.
       
   159  *
       
   160  * Note! As with normal asserts, do not put a function call as the expression because
       
   161  * it will not be executed when logging is off!
       
   162  *
       
   163  *  @code
       
   164  *   // Log error code if it is not KErrNone
       
   165  *   TRAPD( err, SomeFunctionL() );
       
   166  *   MTV_ASSERT( !err, LOG_FORMAT( "Operation failed. error: %d", err ) );
       
   167  *  @endcode
       
   168  */
       
   169 #define LOG_ASSERT( expr, stmt ) do { if ( !( expr )) { stmt; } }while( 0 )
       
   170 
       
   171 /**
       
   172  * Writes a formatted string to log. Accepts variable number of parameters
       
   173  *
       
   174  *  @code
       
   175  *   LOG_FORMAT( "Integer: %d", 1 );
       
   176  *   LOG_FORMAT( "Integer: %d Desc %S", 1, &desc );
       
   177  *   LOG_FORMAT( "Integer: %d Desc %S hex 0x%X", 1, &desc, 0xC0FFEE );
       
   178  *  @endcode
       
   179  */
       
   180 #define LOG_FORMAT( fmt,args...) do{MRadioEngineLogger::Logger()->AddIndent( KMarkerEngine()).AddFormat( _L( fmt ),args ).Commit();}while( 0 )
       
   181 
       
   182 /**
       
   183  * Writes current time to log. Example: Time: 13.9.2007 13:23:25.383750
       
   184  */
       
   185 #define LOG_CURRENT_TIME() do{MRadioEngineLogger::Logger()->AddIndent( KMarkerEngine()).AddTimestamp().Commit();}while( 0 )
       
   186 
       
   187 /**
       
   188  * Writes a time to log. Accepts a TTime as parameter
       
   189  *
       
   190  *  @code
       
   191  *   TTime now;
       
   192  *   now.HomeTime();
       
   193  *   LOG_TIME( now );
       
   194  *  @endcode
       
   195  */
       
   196 #define LOG_TIME( x ) do{MRadioEngineLogger::Logger()->AddIndent( KMarkerEngine()).AddTimestamp( x ).Commit();}while( 0 )
       
   197 
       
   198 /**
       
   199  * Writes a time to log. Accepts a string and a TTime as parameter
       
   200  *
       
   201  *  @code
       
   202  *   TTime now;
       
   203  *   now.HomeTime();
       
   204  *   LOG_TIME2( "Current time", now );
       
   205  *  @endcode
       
   206  */
       
   207 #define LOG_TIME2( desc, time ) do{MRadioEngineLogger::Logger()->AddIndent( KMarkerEngine()).Add( desc ).Add( ": " ).Add( time ).Commit();}while( 0 )
       
   208 
       
   209 /**
       
   210  * Clear the log contents
       
   211  */
       
   212 #define LOG_CLEAR() do{MRadioEngineLogger::Logger()->ClearLog();}while( 0 )
       
   213 
       
   214 /**
       
   215  * Construct a log line one item at a time. No newline at end
       
   216  */
       
   217 //#define LOG( x ) do{CRadioEngineLogger::Logger()->Add( x );}while( 0 )
       
   218 
       
   219 /**
       
   220  * Write a newline to log
       
   221  */
       
   222 #define LOG_NEWLINE() do{MRadioEngineLogger::Logger()->Commit();}while( 0 )
       
   223 
       
   224 /**
       
   225  * Macro that behaves like User::LeaveIfError except it logs the leave
       
   226  * The line "TInt __error_code = expr;" makes sure the expression is evaluated only once
       
   227  */
       
   228 #define LEAVEIFERROR( expr )                                                \
       
   229     do {                                                                    \
       
   230         TInt __err = expr;                                                  \
       
   231         if ( __err )                                                        \
       
   232             {                                                               \
       
   233             _LIT( KExpression, #expr );                                     \
       
   234             LOG_FORMAT( "%S leaving with code %d!", &KExpression, __err );  \
       
   235             User::Leave( __err );                                           \
       
   236             }                                                               \
       
   237         } while( 0 )
       
   238 
       
   239 /**
       
   240  * Macro that behaves like User::Leave except it logs the leave
       
   241  * The line "TInt __error_code = expr;" makes sure the expression is evaluated only once
       
   242  */
       
   243 #define LEAVE( expr )                                   \
       
   244     do {                                                \
       
   245         TInt __err = expr;                              \
       
   246         LOG_FORMAT( "Leaving with code %d!", __err );   \
       
   247         User::Leave( __err );                           \
       
   248         } while( 0 )
       
   249 
       
   250 /**
       
   251  * Macro that behaves like TRAP except it logs the possible error
       
   252  */
       
   253 #define TRAP_AND_LOG_ERR( err, expr )                               \
       
   254     TRAP( err, expr );                                              \
       
   255     if ( err )                                                      \
       
   256         {                                                           \
       
   257         _LIT( KExpression, #expr );                                 \
       
   258         LOG_FORMAT( "%S failed with err %d", &KExpression, err );   \
       
   259         }                                                           \
       
   260 
       
   261 /**
       
   262  * Macro that behaves like TRAPD except it logs the possible error
       
   263  */
       
   264 #define TRAPD_AND_LOG_ERR( err, expr )  \
       
   265     TInt err = 0;                       \
       
   266     TRAP_AND_LOG_ERR( err, expr )
       
   267 
       
   268 
       
   269 /**
       
   270  * Macro that behaves like TRAP_IGNORE except it logs the possible error
       
   271  */
       
   272 #define TRAP_IGNORE_AND_LOG_ERR( expr )     \
       
   273     do {                                    \
       
   274         TRAPD_AND_LOG_ERR( __err, expr );     \
       
   275         } while ( 0 )
       
   276 
       
   277 /**
       
   278  * Write a single log line.
       
   279  */
       
   280 #define LOGGER_WRITE( x ) do{MRadioEngineLogger::Logger()->AddIndent( KMarkerEngine ).Add( _L8( x ) ).Commit();}while( 0 )
       
   281 #define LOG( x ) do{MRadioEngineLogger::Logger()->AddIndent( KMarkerEngine ).Add( x ).Commit();}while( 0 )
       
   282 //#define LOG2( x1, x2 ) do{CRadioEngineLogger::Logger()->AddIndent().Add( x1 ).Add( x2 ).Commit();}while( 0 )
       
   283 //#define LOG3( x1, x2, x3 ) do{CRadioEngineLogger::Logger()->AddIndent().Add( x1 ).Add( x2 ).Add( x3 ).Commit();}while( 0 )
       
   284 //#define LOG4( x1, x2, x3, x4 ) do{CRadioEngineLogger::Logger()->AddIndent().Add( x1 ).Add( x2 ).Add( x3 ).Add( x4 ).Commit();}while( 0 )
       
   285 //#define LOG5( x1, x2, x3, x4, x5 ) do{CRadioEngineLogger::Logger()->AddIndent().Add( x1 ).Add( x2 ).Add( x3 ).Add( x4 ).Add( x5 ).Commit();}while( 0 )
       
   286 
       
   287 // ===========================================================================
       
   288 // ===========================================================================
       
   289 //
       
   290 // END LOGGING MACROS. Do not use anything below this line directly!
       
   291 //
       
   292 // ===========================================================================
       
   293 // ===========================================================================
       
   294 
       
   295 
       
   296 #include <f32file.h>
       
   297 #include <e32debug.h>
       
   298 
       
   299 class TRadioMethodLogger;
       
   300 
       
   301 const TInt KTimestampLength = 40;
       
   302 typedef TBuf8<KTimestampLength> TTimestamp;
       
   303 
       
   304 /**
       
   305  * Logger for writing log to a file and RDebug
       
   306  *
       
   307  *  @lib mtvcommon.lib
       
   308  *  @since Live TV UI v1.0
       
   309  */
       
   310 NONSHARABLE_CLASS( CRadioEngineLogger ) : public CBase
       
   311                                         , public MRadioEngineLogger
       
   312                                         , public TDes16Overflow
       
   313     {
       
   314     friend class CRadioEngineTls;
       
   315 public:
       
   316 
       
   317 // from base class MRadioEngineLogger
       
   318 
       
   319     MRadioEngineLogger& ClearLog();
       
   320     MRadioEngineLogger& Add( const TDesC8& aMsg );
       
   321     MRadioEngineLogger& Add( const TDesC& aMsg );
       
   322     MRadioEngineLogger& Add( TInt aInt );
       
   323     MRadioEngineLogger& Add( const TReal& aReal );
       
   324     MRadioEngineLogger& Add( const char* aText );
       
   325     MRadioEngineLogger& Add( const TAny* aPtr );
       
   326     MRadioEngineLogger& Add( const TTime& aTime );
       
   327     MRadioEngineLogger& AddTimestamp();
       
   328     MRadioEngineLogger& AddFormat( TRefByValue<const TDesC> aFmt, ... );
       
   329     MRadioEngineLogger& AddIndent( const TDesC& aMarker );
       
   330     MRadioEngineLogger& AddIndentClear( const TDesC& aMarker );
       
   331     MRadioEngineLogger& IncIndent();
       
   332     MRadioEngineLogger& DecIndent();
       
   333     MRadioEngineLogger& Commit( TBool aNewLine = ETrue );
       
   334 
       
   335 // from base class TDes16Overflow
       
   336 
       
   337     /**
       
   338      * Handles the overflow from AppendFormatList()
       
   339      *
       
   340      * @since Live TV UI v1.0
       
   341      * @param aDes The 16-bit modifiable descriptor whose overflow results in the
       
   342      *             call to this overflow handler.
       
   343      */
       
   344     void Overflow( TDes16 &aDes );
       
   345 
       
   346 private:
       
   347 
       
   348     static CRadioEngineLogger* NewL( RFs& aFs );
       
   349 
       
   350     ~CRadioEngineLogger();
       
   351 
       
   352     CRadioEngineLogger( RFs& aFs );
       
   353 
       
   354     void ConstructL();
       
   355 
       
   356     /**
       
   357      * Returns the amount of characters that still fit in the buffer
       
   358      *
       
   359      * @since Live TV UI v1.0
       
   360      * @return Amount of space available
       
   361      */
       
   362     TInt Available() const;
       
   363 
       
   364     /**
       
   365      * Templated function to add either 8-bit or 16-bit descriptor to buffer
       
   366      *
       
   367      * @since Live TV UI v1.0
       
   368      * @param aDesc Descriptor to add
       
   369      */
       
   370     template<class PTR, class DESC>
       
   371     void AddDesC( const DESC& aDesc );
       
   372 
       
   373     /**
       
   374      * Parses the timestamp from the given TTime
       
   375      *
       
   376      * @since Live TV UI v1.0
       
   377      * @param aTime Time to parse
       
   378      * @param aTimestamp On return, the parsed timestamp
       
   379      */
       
   380     void ParseTimestamp( const TTime& aTime, TTimestamp& aTimestamp );
       
   381 
       
   382 private: // data
       
   383 
       
   384     /**
       
   385      * Reference to file server session.
       
   386      */
       
   387     RFs&    iFs;
       
   388 
       
   389     /**
       
   390      * File handle
       
   391      */
       
   392     RFile   iFile;
       
   393 
       
   394     /**
       
   395      * Name of the log file.
       
   396      * Own.
       
   397      */
       
   398     HBufC*  iFileName;
       
   399 
       
   400     /**
       
   401      * Logging buffer. holds one log line at a time
       
   402      */
       
   403     TBuf8<KLogBufferLength> iBuf8;
       
   404 
       
   405     /**
       
   406      * Indentation
       
   407      */
       
   408     TInt    iIndent;
       
   409 
       
   410     /**
       
   411      * Flag to indicate whether or not timestamp has already been written to the beginning of line
       
   412      */
       
   413     TBool   iTimeStampWritten;
       
   414 
       
   415     };
       
   416 
       
   417 /**
       
   418  * Helper class for method entry, exit and leave logging.
       
   419  * Used as automatic variable declared by LOG_METHOD() macro.
       
   420  */
       
   421 NONSHARABLE_CLASS( TRadioMethodLogger )
       
   422     {
       
   423 public:
       
   424 
       
   425     /**
       
   426      * Constructor. Writes method entry log.
       
   427      */
       
   428     IMPORT_C TRadioMethodLogger( const TText* aFunc, const TText* aRetFormat );
       
   429 
       
   430     /**
       
   431      * Destructor. Writes method exit log.
       
   432      */
       
   433     IMPORT_C ~TRadioMethodLogger();
       
   434 
       
   435 private: // data
       
   436 
       
   437     /**
       
   438      * Pointer descriptor to function signature that is to be logged.
       
   439      */
       
   440     TPtrC iFunc;
       
   441 
       
   442     /**
       
   443      * Formatting string used to print the function return value
       
   444      */
       
   445     TPtrC iRetFormat;
       
   446 
       
   447     };
       
   448 
       
   449 #else // LOGGING_ENABLED
       
   450 
       
   451 // Empty macro definitions for non logging build.
       
   452 
       
   453 #define LOG_METHOD_AUTO
       
   454 #define LOG_METHOD_AUTO_RET( fmt )
       
   455 
       
   456 #define LOG_METHOD( func )
       
   457 #define LOG_METHOD_RET( func,fmt )
       
   458 #define LOG_FORMAT( fmt,args...)
       
   459 #define LOG_ASSERT( expr, stmt )
       
   460 #define DEBUGVAR( var )
       
   461 #define DEBUGVAR2( var )
       
   462 #define DEBUGVAR3( var )
       
   463 
       
   464 #define LOG_CURRENT_TIME()
       
   465 #define LOG_TIME( x )
       
   466 #define LOG_TIME2( desc, time )
       
   467 
       
   468 #define LOG_CLEAR()
       
   469 #define LOG( x )
       
   470 #define LOG_NEWLINE()
       
   471 #define LOG1( x )
       
   472 #define LOG2( x1, x2 )
       
   473 #define LOG3( x1, x2, x3 )
       
   474 #define LOG4( x1, x2, x3, x4 )
       
   475 #define LOG5( x1, x2, x3, x4, x5 )
       
   476 
       
   477 // Default implementations for leave macros.
       
   478 // Note! These can NOT be empty macros because the errors would not be checked when logging is off
       
   479 #define LEAVEIFERROR( expr )    User::LeaveIfError( expr )
       
   480 #define LEAVE( expr )           User::Leave( expr )
       
   481 
       
   482 // Default implementation for trap macros
       
   483 // Note! As with leave macros, these can not be empty
       
   484 #define TRAP_AND_LOG_ERR( err,stmt )      TRAP( err, stmt )
       
   485 #define TRAPD_AND_LOG_ERR( err,stmt )     TRAPD( err, stmt )
       
   486 #define TRAP_IGNORE_AND_LOG_ERR( stmt )   TRAP_IGNORE( stmt )
       
   487 
       
   488 #define LOGGER_WRITE( x )
       
   489 
       
   490 // ===========================================================================
       
   491 // Dummy classes to keep the exports unchanged when logging is turned off
       
   492 // These can not be used.
       
   493 // ===========================================================================
       
   494 class RFs;
       
   495 NONSHARABLE_CLASS( CRadioEngineLogger ) : public CBase
       
   496     {
       
   497     friend class CRadioEngineImp;
       
   498 private:
       
   499     static void InitializeL( RFs& aFs );
       
   500     static void Release();
       
   501     };
       
   502 
       
   503 NONSHARABLE_CLASS( TRadioMethodLogger )
       
   504     {
       
   505 public:
       
   506     IMPORT_C TRadioMethodLogger( const TText* /*aFunc*/, const TText* /*aRetFormat*/ );
       
   507     IMPORT_C ~TRadioMethodLogger();
       
   508     };
       
   509 
       
   510 #endif // LOGGING_ENABLED
       
   511 
       
   512 #endif // C_RADIOENGINELOGGER_H