oexINT CLog::Log( oexCSTR x_pFile, oexINT x_nLine, oexCSTR8 x_pFunction, oexINT x_uLevel, oexCSTR x_pErr, oexINT x_nErr, oexUINT x_uSkip ) {_STT(); // Ensure valid reporting level if ( x_uLevel < m_uLevel ) return x_nErr; // Log count if ( 1 == oexIncrement( &m_lInLog ) ) { _oexTRY { // Create log file if needed if ( !m_file.IsOpen() ) if ( !OpenLogFile() ) { oexDecrement( &m_lInLog ); return x_nErr; } // end if if ( !oexCHECK_PTR( x_pFile ) ) x_pFile = oexT( "???" ); if ( !oexCHECK_PTR( x_pFunction ) ) x_pFunction = "???"; CStr sLevel; oexCSTR pLevel = oexT( "" ); if ( eHalt == x_uLevel ) pLevel = oexT( "Halt" ); else if ( eError == x_uLevel ) pLevel = oexT( "Error" ); else if ( eWarning == x_uLevel ) pLevel = oexT( "Warning" ); else if ( eNotice == x_uLevel ) pLevel = oexT( "Notice" ); else pLevel = sLevel.Mks( (int)x_uLevel ).Ptr(); CStr sLog; // Add file / line number oexUINT uThreadId = oexGetCurThreadId(); #if defined( oexFULL_FILENAME_IN_LOG ) sLog << x_pFile << oexT( ":(" ) << x_nLine << oexT( ")" ) #else sLog << oexGetFileName( x_pFile ) << oexT( ":(" ) << x_nLine << oexT( ")" ) #endif << oexFmt( oexT( " : Thread %u (0x%x)" ), uThreadId, uThreadId ) << oexNL; // Write out the time #if defined( OEX_NANOSECONDS ) sLog << oexLocalTimeStr( oexT( " -> Local: %Y/%c/%d - %g:%m:%s.%l.%u.%n" oexNL8 ) ); #else sLog << oexLocalTimeStr( oexT( " -> Local Time : %Y/%c/%d - %g:%m:%s.%l.%u" oexNL8 ) ); #endif #if defined( OEXLIB_STACK_TRACING ) CStackTrace::CStack *p = oexSt().GetStack(); if ( p ) { sLog << oexT( " -> Thread Name : " ) << p->GetName() << oexNL; // +++ This really doesn't make a lot of sense in the log file, more for stack tracing // sLog << oexT( " -> Tag : " ) << p->GetTag() << oexNL; // sLog << oexFmt( oexT( " -> CheckPoint : %d (0x%x)" oexNL8 ), p->GetCheckpoint(), p->GetCheckpoint() ); } // end if #endif // Add function name if available if ( x_pFunction && *x_pFunction ) sLog << oexT( " -> Function : " ) << oexMbToStrPtr( x_pFunction ) << oexT( "()" oexNL8 ); // Add error level sLog << oexT( " -> Level : " ) << pLevel; // Add system error info if ( x_nErr ) sLog << CStr().Print( oexT( " : 0x%X (%d) : " ), x_nErr, x_nErr ) << os::CTrace::GetErrorMsg( x_nErr ).RTrim( oexT( "\r\n" ) ); sLog << oexNL; // Write out the user error string if available if ( oexCHECK_PTR( x_pErr ) ) sLog << oexT( " -> " oexNL8 " -> " ) << CStr( x_pErr ).Replace( oexNL, oexT( "" oexNL8 " -> " ) ) << oexNL; #if defined( oexBACKTRACE_IN_LOG ) // Write out the backtrace sLog << oexT( " -> " ) << os::CTrace::GetBacktrace( x_uSkip ).Replace( oexNL, oexT( "" oexNL8 " -> " ) ) << oexNL; #endif // Just to space things out sLog << oexNL; // Write out the string to the file m_file.Write( oexStrToMb( sLog ) ); #if defined( oexPRINT_LOGS ) // Print if user wants to see this level if ( oexPRINT_LOGS <= x_uLevel ) oexEcho( sLog.Ptr() ); #endif } _oexCATCH_ALL() { } // end catch } // end if