Re[3]: Логгинг
От: Left2 Украина  
Дата: 04.04.06 08:19
Оценка:
__>>http://logging.apache.org/log4cxx/

КЛ>Спасибо за ссылку, но что-то типа этого у меня и было. Хотелось избавиться от вызова именно методов с фиксированным кол-ом параметров, и, следовательно, с конкатенацией строк.


В log4cxx вывод идёт через std::strstream — никаких методов с фиксированным кол-вом параметров.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Логгинг
От: Константин Л. Франция  
Дата: 06.04.06 16:04
Оценка:
Здравствуйте, Константин Ленин, Вы писали:

Вот окончательная версия


namespace Logging
{
    typedef ATL::CString String;

    enum LogLevel
    {
        LogDebug = 0,
        LogInfo,
        LogWarning,
        LogError,
        LogNo
    };

    LPCTSTR LogLevelToString( LogLevel level );

    class ILogger
    {
    protected:

        virtual void WriteEntry_( LogLevel level, LPCTSTR message ) = 0;

        ~ILogger(){}

    public:

        void WriteEntry(LogLevel level, LPCTSTR message );        
    };        

    class LogEntry
    {
    private:        

        ILogger*                pLogger_;
        std::auto_ptr<String>    pBuffer_;
        LogLevel                Level_;                        

        LogEntry& operator =( const LogEntry& );        

    public:

        LogEntry::LogEntry( LogLevel level, ILogger* pLogger )
             : Level_( level ),
               pLogger_( pLogger ),
               pBuffer_( new String() )
            {}
        
        LogEntry::LogEntry( LogEntry& entry )
        : Level_( entry.Level_ ),
            pLogger_( entry.pLogger_ ),
            pBuffer_( entry.pBuffer_ )
            {    
                  entry.pLogger_ = NULL;        
            }

                LogEntry::~LogEntry()
            { 
           try
           {
            if( pBuffer_.get() && !pBuffer_->IsEmpty() && pLogger_ ) pLogger_->WriteEntry( Level_, (*pBuffer_) );
           }
           catch(...){}
            }        

        LogEntry LogEntry::print( LPCTSTR value )
            {             
            if( value && _tcslen(value) ) (*pBuffer_) += value;
            return *this;
                }
    };            

    template <typename Logger>
    LogEntry log( LogLevel level )
    {
        return LogEntry(level, &Logger::Instance() );
    }

    class HR
    {
    public:

        HRESULT HR_;

        explicit HR( HRESULT hr )
            : HR_(hr)
        {}        
    };    

    LogEntry operator <<( LogEntry& entry, LPCTSTR value );    
    LogEntry operator <<( LogEntry& entry, int value );    
    LogEntry operator <<( LogEntry& entry, unsigned int value );    
    LogEntry operator <<( LogEntry& entry, long value );    
    LogEntry operator <<( LogEntry& entry, unsigned long value );    
    LogEntry operator <<( LogEntry& entry, const HR& hr );    
    LogEntry operator <<( LogEntry& entry, LogEntry (*manip)( LogEntry& ) );    

    //manipulators

    LogEntry dot( LogEntry& entry );    
    LogEntry colon( LogEntry& entry );    
    LogEntry endl( LogEntry& entry );
    LogEntry comma( LogEntry& entry );    

    //endof manipulators    

    template <typename MTPolicy>
    class FileLogger : public Logging::ILogger, protected MTPolicy
    {
    private:

        class AutoLock
        {
            const FileLogger* pLogger_;

        public:

            AutoLock( const FileLogger* pLogger )
                : pLogger_( pLogger )
            {
                pLogger->Lock();
            }

            ~AutoLock()
            {
                pLogger_->Unlock();
                pLogger_ = NULL;
            }
        };

    private:

        FileLogger& operator =( const FileLogger& );
        FileLogger( const FileLogger& );

        ~FileLogger();

    public:

        FileLogger();
        
        static FileLogger& Instance()
        {
            static FileLogger fileLogger;
            return fileLogger;
        }


    private:
        

        //ILogger implementation
        void WriteEntry_( LogLevel level, LPCTSTR message );
    };

    class MultiThreadedPolicy;
    typedef FileLogger<MultiThreadedPolicy> DefaultLogger;

    template <typename T>
    LogEntry operator <<( LogLevel level, const T& value )
    {
        return LogEntry(level, &DefaultLogger::Instance() ) << value;
    }
    
    class MethodTracer
    {
    public:

        MethodTracer::MethodTracer(LPCTSTR location, HRESULT* pHr)
        : pHr_(pHr),
          Location_(location)
            {
            LogInfo<<_T("Enter              -> ") << Location_<< endl;
             }

            MethodTracer::~MethodTracer()
             {
            try
            {
            LogInfo<< _T("Return( ") << HR( pHr_ != NULL? *pHr_ : S_OK ) << _T(" ) <- ") << Location_ << endl;
            }
                catch( ... ){}
             }
    private:    

        String            Location_;
        HRESULT*        pHr_;    
    };

    //MT policies

    class SingleThreadedPolicy
    {
    protected:

        SingleThreadedPolicy(){}    

        void Lock(){}
        void Unlock(){}
    };

    class MultiThreadedPolicy
    {
        mutable ATL::CComAutoCriticalSection Mutex_;

    protected:        

        MultiThreadedPolicy(){}

        void Lock() const
        {
            Mutex_.Lock();
        }
        void Unlock() const
        {
            Mutex_.Unlock();
        }
    };
}
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.