📄 traceimpl.cpp
字号:
//// This file is part of the "More for C++" library//// Copyright (c) 1999-2003 by Thorsten Goertz (thorsten@morefor.org)//// The "More for C++" library is free software; you can redistribute it and/or// modify it under the terms of the license that comes with this package.//// Read "license.txt" for more details.//// THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED// WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES// OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.////////////////////////////////////////////////////////////////////////////////#include <cstdio>#include <ctime>#include <iostream.hpp>#include <more/create.hpp>#include <more/synchronized.hpp>#include <more/os/file.hpp>#include <more/os/thread.hpp>#include "traceimpl.hpp"using namespace more;using namespace more::io;using namespace more::os;using namespace more::util;using namespace std;////////////////////////////////////////////////////////////////////////////////TraceImpl::TraceImpl( ): m_pMutex( Mutex::create( ) ), m_pLevelMap( CREATE Trace::LevelMap( ) ), m_pPorts( CREATE Ports( ) ){ ( *m_pLevelMap )[Trace::DEBUG] = "Debug"; ( *m_pLevelMap )[Trace::INFO] = "Info"; ( *m_pLevelMap )[Trace::WARN] = "Warn"; ( *m_pLevelMap )[Trace::ERROR] = "Error"; ( *m_pLevelMap )[Trace::NONE] = "None"; Singleton<TraceImpl>::setInstance( this );}////////////////////////////////////////////////////////////////////////////////void TraceImpl::destroy( ){ Singleton<TraceImpl>::setInstance( 0 );}////////////////////////////////////////////////////////////////////////////////void TraceImpl::addLevel( const Trace::Level& Level){ synchronized( m_pMutex ) { ( *m_pLevelMap )[Level.value] = Level.name; } end_synchronized}////////////////////////////////////////////////////////////////////////////////void TraceImpl::removeLevel( size_t nLevel){ synchronized( m_pMutex ) { Trace::LevelMap::iterator pLevelIterator = m_pLevelMap -> find( nLevel ); if( pLevelIterator != m_pLevelMap -> end( ) ) { m_pLevelMap -> erase( pLevelIterator ); } } end_synchronized}////////////////////////////////////////////////////////////////////////////////p<Trace::LevelMap> TraceImpl::getLevels( ){ p<Trace::LevelMap> pResult; synchronized( m_pMutex ) { pResult = CREATE Trace::LevelMap( *m_pLevelMap ); } end_synchronized return pResult;}////////////////////////////////////////////////////////////////////////////////void TraceImpl::addPort( const p<Trace::Port>& pPort){ synchronized( m_pMutex ) { m_pPorts -> insert( pPort ); } end_synchronized}////////////////////////////////////////////////////////////////////////////////void TraceImpl::removePort( const p<Trace::Port>& pPort){ synchronized( m_pMutex ) { m_pPorts -> erase( pPort ); } end_synchronized}////////////////////////////////////////////////////////////////////////////////bool TraceImpl::accept( size_t nLevel){ bool bResult = false; synchronized( m_pMutex ) { Ports::iterator pPortIterator = m_pPorts -> begin( ); while( bResult == false && pPortIterator != m_pPorts -> end( ) ) { bResult = ( *pPortIterator ) -> accept( nLevel ); pPortIterator++; } } end_synchronized return bResult;}////////////////////////////////////////////////////////////////////////////////void TraceImpl::dump( size_t nLevel, const String& sMessage){ synchronized( m_pMutex ) { Ports::iterator pPortIterator = m_pPorts -> begin( ); while( pPortIterator != m_pPorts -> end( ) ) { try { if( ( *pPortIterator ) -> accept( nLevel ) ) { ( *pPortIterator ) -> dump( nLevel, sMessage ); } } catch( ... ) { } pPortIterator++; } } end_synchronized}////////////////////////////////////////////////////////////////////////////////SingletonCreator<TraceImpl> TraceImpl::singletonCreator;////////////////////////////////////////////////////////////////////////////////static const char* createHeader( char* pcBuffer, const char* pcLevel){ time_t nTime; tm* pTime; size_t i, j = 0; char cLevel[16];::time( &nTime ); pTime = localtime( &nTime ); for( i = 0; i < 5 && pcLevel[j] > '\0'; i++ ) { cLevel[i] = pcLevel[j++]; } cLevel[j++] = ':'; while( j < 7 ) { cLevel[j++] = ' '; } cLevel[j] = '\0'; sprintf( pcBuffer, "%04d-%02d-%02d %02d:%02d:%02d [%04X] %s", pTime -> tm_year + 1900, pTime -> tm_mon + 1, pTime -> tm_mday, pTime -> tm_hour, pTime -> tm_min, pTime -> tm_sec, Thread::getId( ), cLevel ); return pcBuffer;}////////////////////////////////////////////////////////////////////////////////static void dumpMessage( OutputStream& rOut, const String& sLevel, const String& sMessage, size_t nMaxLineLength){ char cBuffer[256]; const char* pcHeader = createHeader( cBuffer, sLevel ); size_t nHeaderLength = strlen( pcHeader ); const char* pcMessage = sMessage; size_t nMessageLength = sMessage.getLength( ); if( nHeaderLength + nMessageLength <= nMaxLineLength ) { rOut.write( pcHeader, nHeaderLength ); rOut.write( pcMessage, nMessageLength ); rOut.write( "\r\n", 2 ); } else { const char* pcLine = pcMessage; size_t nLineLength = 0; size_t nMaxNetLineLength = nMaxLineLength - nHeaderLength; while( pcLine < pcMessage + nMessageLength ) { size_t nWordLength = 0; while( pcLine + nLineLength < pcMessage + nMessageLength && nLineLength < nMaxNetLineLength ) { nLineLength++; nWordLength++; if( pcLine[nLineLength] <= ' ' ) { nWordLength = 0; } } if( pcLine[nLineLength] > ' ' && nWordLength < nLineLength ) { nLineLength -= nWordLength; } rOut.write( pcHeader, nHeaderLength ); rOut.write( pcLine, nLineLength ); rOut.write( "\r\n", 2 ); if( pcLine == pcMessage ) { memset( cBuffer, ' ', nHeaderLength ); } pcLine += nLineLength; nLineLength = 0; if( pcLine[0] <= ' ' ) { pcLine++; } } }}////////////////////////////////////////////////////////////////////////////////LogConsole::LogConsole( size_t nMinLevel): m_pMutex( Mutex::create( ) ), m_nMinLevel( nMinLevel ), m_pLevelMap( Trace::getLevels( ) ), m_pOStreamAdapter( CREATE OStreamAdapter( cerr ) ){}////////////////////////////////////////////////////////////////////////////////bool LogConsole::accept( size_t nLevel) const{ bool bResult = false; if( nLevel >= m_nMinLevel ) { synchronized( m_pMutex ) { bResult = m_pLevelMap -> find( nLevel ) != m_pLevelMap -> end( ); } end_synchronized } return bResult;}////////////////////////////////////////////////////////////////////////////////void LogConsole::dump( size_t nLevel, const String& sMessage){ if( nLevel >= m_nMinLevel ) { synchronized( m_pMutex ) { Trace::LevelMap::const_iterator pIterator = m_pLevelMap -> find( nLevel ); if( pIterator != m_pLevelMap -> end( ) ) { dumpMessage( *m_pOStreamAdapter, pIterator -> second, sMessage, 79 ); } } end_synchronized }}////////////////////////////////////////////////////////////////////////////////LogFile::LogFile( const String& sLogFile, size_t nMinLevel): m_pMutex( Mutex::create( ) ), m_sLogFile( sLogFile ), m_nMinLevel( nMinLevel ), m_pLevelMap( Trace::getLevels( ) ){}////////////////////////////////////////////////////////////////////////////////bool LogFile::accept( size_t nLevel) const{ bool bResult = false; if( nLevel >= m_nMinLevel ) { synchronized( m_pMutex ) { bResult = m_pLevelMap -> find( nLevel ) != m_pLevelMap -> end( ); } end_synchronized } return bResult;}////////////////////////////////////////////////////////////////////////////////void LogFile::dump( size_t nLevel, const String& sMessage){ if( nLevel >= m_nMinLevel ) { synchronized( m_pMutex ) { Trace::LevelMap::const_iterator pIterator = m_pLevelMap -> find( nLevel ); if( pIterator != m_pLevelMap -> end( ) ) { try { if( m_pOutputStream == 0 ) { p<File> pFile = File::create( m_sLogFile ); bool bFileExisted = pFile -> exists( ); pFile -> open( File::WRITE_APPEND ); m_pOutputStream = pFile -> getOutputStream( ); if( bFileExisted ) { ( *m_pOutputStream ) << "----------------------------------------------------------------------------------------------------\r\n"; } } dumpMessage( *m_pOutputStream, pIterator -> second, sMessage, 100 ); } catch( const more::io::IOException& e ) { size_t nSavedMinLevel = m_nMinLevel; m_nMinLevel = Trace::NONE; trace( Trace::ERROR ) << "Unable to create log file \"" << m_sLogFile << "\": " << e << end_trace; m_nMinLevel = nSavedMinLevel; m_pOutputStream = 0; } } } end_synchronized }}////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -