emailservices/emaildebug/src/cmaillogger.cpp
changeset 0 8466d47a6819
equal deleted inserted replaced
-1:000000000000 0:8466d47a6819
       
     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:  commonemail file logger implementation
       
    15 *
       
    16 */
       
    17 
       
    18 #include "cmaillogger.h"
       
    19 #include <e32std.h>
       
    20 
       
    21 _LIT( KLogFileExt, ".txt" );
       
    22 _LIT( KLogFileBaseName, "c:\\data\\cmail_" );
       
    23 
       
    24 // log file is replaced after certain amount of rows
       
    25 const TInt KLogFileMaxRowCount = 3000;
       
    26 
       
    27 #ifdef _DEBUG
       
    28 #define CMAILLOGGERTACE(x) {RDebug::Print(_L(x) );}
       
    29 #define CMAILLOGGERTACE2(x,y) {RDebug::Print(_L(x),y );}
       
    30 #else
       
    31 #define CMAILLOGGERTACE(x)
       
    32 #define CMAILLOGGERTACE2(x,y)
       
    33 #endif
       
    34 
       
    35 // local functions
       
    36 RFileWriteStream* File();
       
    37 
       
    38 void ReplaceIfSizeExceeded(LogFile& aLogFile );
       
    39 
       
    40 // ---------------------------------------------------------------------------
       
    41 // Exception handler that closes and renames current log file and passes
       
    42 // exception to original handler.
       
    43 // ---------------------------------------------------------------------------
       
    44 void LoggerExcHandler( TExcType aType )
       
    45     {
       
    46     CMAILLOGGERTACE2( "cmail exception handler %d", aType )
       
    47     LogFile* logFile = reinterpret_cast<LogFile*>( Dll::Tls() );
       
    48     TExceptionHandler storedExcHandler = NULL;
       
    49     if ( logFile )
       
    50         {
       
    51         _LIT8( KExceptionText, "CMAIL catched exception %d \n" );
       
    52         TBuf8<50> buf8;
       
    53         buf8.Format( KExceptionText(), aType );
       
    54         TRAP_IGNORE( logFile->iFile.WriteL( buf8 ) );
       
    55         logFile->iFile.Close();
       
    56 
       
    57         // rename file to prevent over writing
       
    58         TBuf<100> newName;
       
    59         TTime time;
       
    60         time.HomeTime();
       
    61         TDateTime dt = time.DateTime();
       
    62         TInt pos = logFile->iFileName.Locate(TChar('.'));
       
    63         if ( pos != KErrNotFound )
       
    64             {
       
    65             _LIT( KDateTimeFormat, "%C" ); // microsecond form
       
    66             TBuf<20> timeBuf;
       
    67             TRAP_IGNORE( time.FormatL( timeBuf, KDateTimeFormat() ) )
       
    68             newName = logFile->iFileName.Left( pos );
       
    69             newName.Append( timeBuf );
       
    70             newName.Append( KLogFileExt() );
       
    71             TInt err = logFile->iFs.Rename( logFile->iFileName, newName);
       
    72             CMAILLOGGERTACE2( "CMAIL log file rename err=%d", err )
       
    73             }
       
    74 
       
    75         storedExcHandler = logFile->iHandler;
       
    76         (*storedExcHandler)(aType);
       
    77         }
       
    78 
       
    79     }
       
    80 
       
    81 // ---------------------------------------------------------------------------
       
    82 // CmailLogger::Write
       
    83 // ---------------------------------------------------------------------------
       
    84 //
       
    85 EXPORT_C void CmailLogger::Write( const TDesC8& aData )
       
    86 {
       
    87     RFileWriteStream* file = File();
       
    88     if ( file /*&& file->SubSessionHandle() */)
       
    89         {
       
    90         TRAP_IGNORE( 
       
    91             {
       
    92             file->WriteL( aData );
       
    93             TBuf8<2> crLf;
       
    94             crLf.Append( 13 );
       
    95             crLf.Append( 10 );
       
    96             file->WriteL( crLf ); 
       
    97             } );            
       
    98         }
       
    99 }
       
   100 
       
   101 // ---------------------------------------------------------------------------
       
   102 // CmailLogger::Close
       
   103 // ---------------------------------------------------------------------------
       
   104 //
       
   105 EXPORT_C void CmailLogger::Close()
       
   106 {
       
   107     CMAILLOGGERTACE("Cmaillogger Close")
       
   108     TAny* tls = Dll::Tls();
       
   109     if ( tls )
       
   110         {
       
   111         LogFile* logFile = reinterpret_cast<LogFile*>( tls );
       
   112         logFile->iFile.Close();
       
   113         logFile->iFs.Close();
       
   114         logFile->iFileName.Zero();
       
   115         User::SetExceptionHandler( logFile->iHandler,0xFFFFFFFF );
       
   116         delete logFile;
       
   117         Dll::SetTls( NULL );
       
   118         }
       
   119 }
       
   120 
       
   121 // ---------------------------------------------------------------------------
       
   122 // Returns log file pointer. When called first time file handle container
       
   123 // LogFile is stored to TLS.
       
   124 // ---------------------------------------------------------------------------
       
   125 //
       
   126 RFileWriteStream* File()
       
   127     {
       
   128     CMAILLOGGERTACE("Cmaillogger File")
       
   129     TAny* tls = Dll::Tls();
       
   130     LogFile* logFile = NULL;
       
   131     if ( !tls )
       
   132         {
       
   133         CMAILLOGGERTACE("Cmaillogger File no tls")
       
   134         RThread t;
       
   135         TName n = t.Name();
       
   136         logFile = new LogFile;
       
   137         if ( !logFile )
       
   138             {
       
   139             return NULL;
       
   140             }
       
   141         Dll::SetTls( logFile );
       
   142         logFile->iThreadName.Copy( t.Name().Left(20));
       
   143         logFile->iLinesWritten = KErrNotFound; // for ReplaceIfSizeExceeded()
       
   144         TInt res = logFile->iFs.Connect();
       
   145         CMAILLOGGERTACE2("Cmaillogger iFs.Connect res=%d", res )
       
   146         ReplaceIfSizeExceeded( *logFile );
       
   147 
       
   148         // store default exception handler pointer
       
   149         logFile->iHandler = User::ExceptionHandler();
       
   150 
       
   151         // set own exception handler (see above)
       
   152         User::SetExceptionHandler( LoggerExcHandler,
       
   153             KExceptionAbort |
       
   154             KExceptionAbort |
       
   155             KExceptionUserInterrupt |
       
   156             KExceptionFault );
       
   157         }
       
   158     else
       
   159         {
       
   160         logFile = reinterpret_cast<LogFile*>( tls );
       
   161         ReplaceIfSizeExceeded( *logFile );
       
   162         logFile->iLinesWritten++;
       
   163         if ( logFile->iLinesWritten % 100 == 0 )
       
   164             { // flush every now and then to prevent loss of data if thread
       
   165               // is paniced (exceptions like ke-3 are not a problem, they are
       
   166               // catched by LoggerExcHandler).
       
   167             TRAP_IGNORE( logFile->iFile.CommitL() )
       
   168             }
       
   169         }
       
   170     return &logFile->iFile;
       
   171     }
       
   172 
       
   173 // ---------------------------------------------------------------------------
       
   174 // ReplaceIfSizeExceeded
       
   175 // Replaces log file if determined log row count is exceeded.
       
   176 // ---------------------------------------------------------------------------
       
   177 //
       
   178 void ReplaceIfSizeExceeded( LogFile& aLogFile )
       
   179     {
       
   180     CMAILLOGGERTACE("Cmaillogger ReplaceIfSizeExceeded<")
       
   181     if ( ( aLogFile.iLinesWritten >= KLogFileMaxRowCount ||
       
   182          aLogFile.iLinesWritten < 0 ) && // initial creation
       
   183          aLogFile.iFs.Handle() )
       
   184         {
       
   185         if ( !aLogFile.iFileName.Length() )
       
   186             {
       
   187             aLogFile.iFileName = KLogFileBaseName();
       
   188             aLogFile.iFileName.Append( aLogFile.iThreadName );
       
   189             aLogFile.iFileName.Append( KLogFileExt() );
       
   190             }
       
   191         aLogFile.iLinesWritten = 0;
       
   192         aLogFile.iFile.Close();
       
   193         CMAILLOGGERTACE2("Cmaillogger  open file '%S'",&aLogFile.iFileName)
       
   194         TInt res = aLogFile.iFile.Replace( aLogFile.iFs, aLogFile.iFileName,
       
   195             EFileShareReadersOrWriters );
       
   196         CMAILLOGGERTACE2("Cmaillogger open result=%d", res )
       
   197         }
       
   198     CMAILLOGGERTACE("Cmaillogger ReplaceIfSizeExceeded>")
       
   199     }
       
   200