/*- * Copyright 2005 Guram Dukashvili * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ //--------------------------------------------------------------------------- #ifndef _Log_H_ #define _Log_H_ //--------------------------------------------------------------------------- namespace ksys { //--------------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////////// //--------------------------------------------------------------------------- class AsyncFile; class FiberInterlockedMutex; //--------------------------------------------------------------------------- class LogFile : protected Thread { friend void initialize(int,char **); friend void cleanup(); public: ~LogFile(); LogFile(); LogFile & open(); LogFile & close(); LogFile & fileName(const utf8::String & name); const utf8::String & fileName() const; LogFile & debug(uintptr_t level,const utf8::String::Stream & stream); bool debugLevel(uintptr_t level) const; LogFile & debugLevel(uintptr_t level,intptr_t value); LogFile & setDebugLevels(const utf8::String & levels); LogFile & setAllDebugLevels(intptr_t value); LogFile & rotationThreshold(uint64_t a); const uint64_t & rotationThreshold() const; LogFile & rotatedFileCount(uintptr_t a); const uintptr_t & rotatedFileCount() const; LogFile & codePage(uintptr_t a); const uintptr_t & codePage() const; LogFile & bufferDataTTA(uint64_t a); const uint64_t & bufferDataTTA() const; LogFile & flush(bool wait = false); protected: static const char * const priNicks_[]; utf8::String file_; FiberInterlockedMutex mutex_; InterlockedMutex threadMutex_; AutoPtr buffer_; uintptr_t bufferPos_; uintptr_t bufferSize_; uint64_t bufferDataTTA_; // data time to accumulation uint64_t lastFlushTime_; Semaphore bufferSemaphore_; uint8_t enabledLevels_[32]; uint64_t rotationThreshold_; uintptr_t rotatedFileCount_; uintptr_t codePage_; LogFile & internalLog(uintptr_t level,const utf8::String::Stream & stream); void rotate(AsyncFile & file); void threadExecute(); void threadBeforeWait(); AsyncFile threadFile_; private: static void initialize(); static void cleanup(); }; //--------------------------------------------------------------------------- inline LogFile & LogFile::bufferDataTTA(uint64_t a) { bufferDataTTA_ = a; return *this; } //--------------------------------------------------------------------------- inline const uint64_t & LogFile::bufferDataTTA() const { return bufferDataTTA_; } //--------------------------------------------------------------------------- inline LogFile & LogFile::debug(uintptr_t level,const utf8::String::Stream & stream) { return internalLog(level,stream); } //--------------------------------------------------------------------------- inline const utf8::String & LogFile::fileName() const { return file_; } //--------------------------------------------------------------------------- inline bool LogFile::debugLevel(uintptr_t level) const { return bit(enabledLevels_,level & (sizeof(enabledLevels_) * 8u - 1)) != 0; } //--------------------------------------------------------------------------- inline LogFile & LogFile::debugLevel(uintptr_t level,intptr_t value) { setBitValue(enabledLevels_,level & (sizeof(enabledLevels_) * 8u - 1),value > 0); return *this; } //--------------------------------------------------------------------------- inline LogFile & LogFile::rotationThreshold(uint64_t a) { rotationThreshold_ = a; return *this; } //--------------------------------------------------------------------------- inline const uint64_t & LogFile::rotationThreshold() const { return rotationThreshold_; } //--------------------------------------------------------------------------- inline LogFile & LogFile::rotatedFileCount(uintptr_t a) { rotatedFileCount_ = a; return *this; } //--------------------------------------------------------------------------- inline const uintptr_t & LogFile::rotatedFileCount() const { return rotatedFileCount_; } //--------------------------------------------------------------------------- inline LogFile & LogFile::codePage(uintptr_t a) { codePage_ = a; return *this; } //--------------------------------------------------------------------------- inline const uintptr_t & LogFile::codePage() const { return codePage_; } //--------------------------------------------------------------------------- extern char stdErr_[sizeof(LogFile) / sizeof(char)]; extern LogFile & stdErr; //--------------------------------------------------------------------------- } // namespace ksys //--------------------------------------------------------------------------- #endif /* _Log_H_ */ //---------------------------------------------------------------------------