Vault  4.1
vlogger.h
Go to the documentation of this file.
00001 /*
00002 Copyright c1997-2014 Trygve Isaacson. All rights reserved.
00003 This file is part of the Code Vault version 4.1
00004 http://www.bombaydigital.com/
00005 License: MIT. See LICENSE.md in the Vault top level directory.
00006 */
00007 
00008 #ifndef vlogger_h
00009 #define vlogger_h
00010 
00013 #include "vtypes.h"
00014 
00015 #include "vmutex.h"
00016 #include "vbufferedfilestream.h"
00017 #include "vtextiostream.h"
00018 
00019 // Microsoft steals this symbol name globally. Take it back.
00020 #ifdef VPLATFORM_WIN
00021     #undef ERROR
00022 #endif
00023 // Xcode 5 steals this symbol name globally. Take it back.
00024 #ifdef VPLATFORM_MAC
00025     #undef DEBUG
00026 #endif
00027 
00028 class VSettings;
00029 class VSettingsNode;
00030 class VBentoNode;
00031 
00214 // This first set of macros sends output to the default logger.
00215 #define VLOGGER_LEVEL(level, message) do { if (!VLogger::isDefaultLogLevelActive(level)) break; VLogger::getDefaultLogger()->log(level, NULL, 0, message, VString::EMPTY()); } while (false)
00216 #define VLOGGER_LEVEL_FILELINE(level, message, file, line) do { if (!VLogger::isDefaultLogLevelActive(level)) break; VLogger::getDefaultLogger()->log(level, file, line, message, VString::EMPTY()); } while (false)
00217 #define VLOGGER_LINE(level, message) VLOGGER_LEVEL_FILELINE(level, message, __FILE__, __LINE__)
00218 #define VLOGGER_FATAL_AND_THROW(message) do { VLogger::getDefaultLogger()->log(VLoggerLevel::FATAL, __FILE__, __LINE__, message); throw VStackTraceException(message); } while (false)
00219 #define VLOGGER_FATAL(message) VLOGGER_LEVEL_FILELINE(VLoggerLevel::FATAL, message, __FILE__, __LINE__)
00220 #define VLOGGER_ERROR(message) VLOGGER_LEVEL_FILELINE(VLoggerLevel::ERROR, message, __FILE__, __LINE__)
00221 #define VLOGGER_WARN(message) VLOGGER_LEVEL(VLoggerLevel::WARN, message)
00222 #define VLOGGER_INFO(message) VLOGGER_LEVEL(VLoggerLevel::INFO, message)
00223 #define VLOGGER_DEBUG(message) VLOGGER_LEVEL(VLoggerLevel::DEBUG, message)
00224 #define VLOGGER_TRACE(message) VLOGGER_LEVEL(VLoggerLevel::TRACE, message)
00225 #define VLOGGER_HEXDUMP(level, message, buffer, length) do { if (!VLogger::isDefaultLogLevelActive(level)) break; VLogger::getDefaultLogger()->logHexDump(level, message, VString::EMPTY(), buffer, length); } while (false)
00226 #define VLOGGER_WOULD_LOG(level) (VLogger::isDefaultLogLevelActive(level))
00227 
00228 // This set of macros sends output to a specified named logger.
00229 #define VLOGGER_NAMED_LEVEL(loggername, level, message) do { if (!VLogger::isLogLevelActive(level)) break; VNamedLoggerPtr nl = VLogger::findNamedLoggerForLevel(loggername, level); if (nl != nullptr) nl->log(level, NULL, 0, message, loggername); } while (false)
00230 #define VLOGGER_NAMED_LEVEL_FILELINE(loggername, level, message, file, line) do { if (!VLogger::isLogLevelActive(level)) break; VNamedLoggerPtr nl = VLogger::findNamedLoggerForLevel(loggername, level); if (nl != nullptr) nl->log(level, file, line, message, loggername); } while (false)
00231 #define VLOGGER_NAMED_LINE(loggername, level, message) VLOGGER_NAMED_LEVEL_FILELINE(loggername, level, message, __FILE__, __LINE__)
00232 #define VLOGGER_NAMED_FATAL(loggername, message) VLOGGER_NAMED_LEVEL_FILELINE(loggername, VLoggerLevel::FATAL, message, __FILE__, __LINE__)
00233 #define VLOGGER_NAMED_ERROR(loggername, message) VLOGGER_NAMED_LEVEL_FILELINE(loggername, VLoggerLevel::ERROR, message, __FILE__, __LINE__)
00234 #define VLOGGER_NAMED_WARN(loggername, message) VLOGGER_NAMED_LEVEL(loggername, VLoggerLevel::WARN, message)
00235 #define VLOGGER_NAMED_INFO(loggername, message) VLOGGER_NAMED_LEVEL(loggername, VLoggerLevel::INFO, message)
00236 #define VLOGGER_NAMED_DEBUG(loggername, message) VLOGGER_NAMED_LEVEL(loggername, VLoggerLevel::DEBUG, message)
00237 #define VLOGGER_NAMED_TRACE(loggername, message) VLOGGER_NAMED_LEVEL(loggername, VLoggerLevel::TRACE, message)
00238 #define VLOGGER_NAMED_HEXDUMP(loggername, level, message, buffer, length) do { if (!VLogger::isLogLevelActive(level)) break; VNamedLoggerPtr nl = VLogger::findNamedLoggerForLevel(loggername, level); if (nl != nullptr) nl->logHexDump(level, message, loggername, buffer, length); } while (false)
00239 #define VLOGGER_NAMED_WOULD_LOG(loggername, level) (VLogger::isLogLevelActive(level) && (VLogger::findNamedLoggerForLevel(loggername, level) != nullptr))
00240 
00241 #define VLOGGER_APPENDER_EMIT(appender, level, message) do { (appender).emit(level, (level <= VLoggerLevel::ERROR) ? __FILE__ : NULL, (level <= VLoggerLevel::ERROR) ? __LINE__ : 0, true, message, VString::EMPTY(), VString::EMPTY(), false, VString::EMPTY()); } while (false)
00242 #define VLOGGER_APPENDER_EMIT_FILELINE(appender, level, message, file, line) do { (appender).emit(level, file, line, true, message, VString::EMPTY(), VString::EMPTY(), false, VString::EMPTY()); } while (false)
00243 
00247 class VLogAppender {
00248     public:
00249 
00250         // These constants can be used for the formatOutput constructor parameter.
00251         static const bool DO_FORMAT_OUTPUT = true;
00252         static const bool DONT_FORMAT_OUTPUT = false;
00253 
00262         VLogAppender(const VString& name, bool formatOutput, const VString& formatSpec, const VString& timeFormat);
00269         VLogAppender(const VSettingsNode& settings, const VSettingsNode& defaults);
00270 
00271         virtual ~VLogAppender();
00272 
00273         const VString& getName() const { return mName; }    
00274         bool isDefaultAppender() const;                     
00275 
00300         virtual void emit(int level, const char* file, int line, bool emitMessage, const VString& message, const VString& specifiedLoggerName, const VString& actualLoggerName, bool emitRawLine, const VString& rawLine);
00305         void emitRaw(const VString& message);
00306 
00312         virtual void addInfo(VBentoNode& infoNode) const;
00313 
00314     protected:
00315 
00327         virtual void _emitMessage(int level, const char* file, int line, const VString& message, const VString& specifiedLoggerName, const VString& actualLoggerName);
00342         virtual VString _formatMessage(int level, const char* file, int line, const VString& message, const VString& specifiedLoggerName, const VString& actualLoggerName);
00350         virtual void _emitRawLine(const VString& /*line*/) {}
00351 
00352         // These helper functions are meant to be used by subclasses constructing from settings.
00353         // Such constructors usually need to get settings, and fall back first to configured defaults, then to a specific default value.
00354         static bool _getBooleanInitSetting(const VString& attributePath, const VSettingsNode& settings, const VSettingsNode& defaults, bool defaultValue);
00355         static int _getIntInitSetting(const VString& attributePath, const VSettingsNode& settings, const VSettingsNode& defaults, int defaultValue);
00356         static VString _getStringInitSetting(const VString& attributePath, const VSettingsNode& settings, const VSettingsNode& defaults, const VString& defaultValue);
00357 
00358         VMutex              mMutex;          
00359                                                 // subclasses may access this carefully; note that it is locked prior to any
00360                                                 // call to emitMessage() or emitRawLine(), so implementors of those functions must
00361                                                 // not re-lock because to do so would cause a deadlock.
00362         VString             mName;          
00363         bool                mFormatOutput;  
00364         VString             mFormatSpec;    
00365         VInstantFormatter   mTimeFormatter; 
00366         
00367         // These fields cache state of the mFormatSpec. This allows _formatMessage() to avoid unnecessary work
00368         // when we know the format doesn't need everything to be supplied. If we allow mFormatSpec to be set
00369         // after construction, these will have to be re-calculated at that time.
00370         bool    mFormatUsesLocalTime;
00371         bool    mFormatUsesUTCTime;
00372         bool    mFormatUsesLevel;
00373         bool    mFormatUsesThread;
00374         bool    mFormatUsesLocation;
00375         bool    mFormatUsesSpecifiedLoggerName;
00376         bool    mFormatUsesActualLoggerName;
00377 
00378     private:
00379 
00380         VString _toString() const; 
00381 
00382         static void _breakpointLocationForEmit(); 
00383 };
00384 
00385 typedef VSharedPtr<VLogAppender> VLogAppenderPtr;
00386 typedef VSharedPtr<const VLogAppender> VLogAppenderConstPtr;
00387 typedef std::vector<VLogAppenderPtr> VLogAppenderPtrList;
00388 
00389 class VNamedLogger;
00390 
00397 class VLoggerRepetitionFilter {
00398     public:
00399 
00400         VLoggerRepetitionFilter();
00401         virtual ~VLoggerRepetitionFilter() {}
00402 
00408         void setEnabled(bool enabled) { mEnabled = enabled; }
00413         bool isEnabled() const { return mEnabled; }
00414 
00419         void reset();
00420 
00435         bool checkMessage(VNamedLogger& logger, int level, const char* file, int line, const VString& message, const VString& specifiedLoggerName, const VString& actualLoggerName);
00436 
00444         void checkTimeout(VNamedLogger& logger);
00445 
00446     private:
00447 
00448         VLoggerRepetitionFilter(const VLoggerRepetitionFilter&); // not copyable
00449         VLoggerRepetitionFilter& operator=(const VLoggerRepetitionFilter&); // not assignable
00450 
00456         void _emitSuppressedMessages(VNamedLogger& logger);
00457 
00458         bool        mEnabled; 
00459 
00460         // Information defining the saved output. The (level, file, line, message) combination
00461         // defines a repeated message. If any of those differ, then it's considered a different
00462         // message that is not a repeat.
00463         bool        mHasSavedMessage;           
00464         int         mNumSuppressedOccurrences;  
00465         VInstant    mTimeOfLastOccurrence;      
00466         int         mLevel;                     
00467         const char* mFile;                      
00468         int         mLine;                      
00469         VString     mMessage;                   
00470         VString     mSpecifiedLoggerName;       
00471         VString     mActualLoggerName;          
00472 };
00473 
00478 class VLoggerPrintStackConfig {
00479     public:
00480 
00481         VLoggerPrintStackConfig();
00482         ~VLoggerPrintStackConfig() {}
00483 
00484         int getLevel() const { return mLevel; } 
00485         void configure(int level, int maxNumOccurrences, const VDuration& timeLimit);
00486         bool shouldPrintStack(int level, VNamedLogger& logger);
00487 
00488     private:
00489 
00490         int         mLevel;         
00491         int         mMaxCount;      
00492         VDuration   mDuration;      
00493         int         mCountdown;     
00494         VInstant    mExpiration;    
00495 };
00496 
00509 class VNamedLogger : public VEnableSharedFromThis<VNamedLogger> {
00510     public:
00511 
00521         VNamedLogger(const VString& name, int level, const VStringVector& appenderNames, VLogAppenderPtr specificAppender = VLogAppenderPtr());
00522         virtual ~VNamedLogger();
00523 
00527         void clearAppenders();
00532         void setAppender(const VString& appenderName);
00537         void addAppender(const VString& appenderName);
00538 
00539         // The following log/emit APIs should generally be accessed through the VLOGGER macros.
00540         // However, it is legal to call them if you have a reference to a logger.
00541 
00551         void log(int level, const char* file, int line, const VString& message, const VString& specifiedLoggerName = VString::EMPTY());
00557         void log(int level, const VString& message);
00566         void logHexDump(int level, const VString& message, const VString& specifiedLoggerName, const Vu8* buffer, Vs64 length);
00571         void emitStackCrawlLine(const VString& message);
00572 
00573         const VString& getName() const { return mName; }            
00574         bool isEnabledFor(int level) { return level <= mLevel; }    
00575         int getLevel() const { return mLevel; }                     
00576         void setLevel(int level);                                   
00577 
00578         void setRepetitionFilterEnabled(bool enabled) { mRepetitionFilter.setEnabled(enabled); }    
00579 
00586         int getPrintStackLevel() const { return mPrintStackConfig.getLevel(); }
00593         void setPrintStackInfo(int printStackLevel, int maxNumOccurrences, const VDuration& timeLimit) { mPrintStackConfig.configure(printStackLevel, maxNumOccurrences, timeLimit); }
00598         bool isDefaultLogger() const;
00599 
00605         virtual void addInfo(VBentoNode& infoNode) const;
00606 
00607     protected:
00608 
00621         virtual void _emitToAppenders(int level, const char* file, int line, bool emitMessage, const VString& message, const VString& specifiedLoggerName, bool emitRawLine, const VString& rawLine);
00622 
00623     private:
00624 
00625         VString _toString() const; 
00626 
00627         static void _breakpointLocationForLog(); 
00628 
00629         VString                 mName;              
00630         int                     mLevel;             
00631         mutable VMutex          mAppendersMutex;    
00632         VStringVector           mAppenderNames;     
00633         VLogAppenderPtr         mSpecificAppender;  
00634         VLoggerRepetitionFilter mRepetitionFilter;  
00635         VLoggerPrintStackConfig mPrintStackConfig;  
00636 
00637         friend class VLoggerRepetitionFilter; // it can call our _emitToAppenders when we call it from our log() function
00638         friend class VLoggerPrintStackConfig; // ditto
00639 };
00640 
00641 typedef VSharedPtr<VNamedLogger> VNamedLoggerPtr;
00642 typedef VSharedPtr<const VNamedLogger> VNamedLoggerConstPtr;
00643 
00648 class VLogAppenderFactory {
00649     public:
00650 
00651         VLogAppenderFactory() {}
00652         virtual ~VLogAppenderFactory() {}
00653 
00659         virtual VLogAppenderPtr instantiateLogAppender(const VSettingsNode& settings, const VSettingsNode& defaults) const = 0;
00660 
00667         virtual void addInfo(VBentoNode& infoNode) const = 0;
00668 
00669 };
00670 
00671 typedef VSharedPtr<const VLogAppenderFactory> VLogAppenderFactoryPtr;
00672 
00679 class VLoggerLevel {
00680     public:
00681 
00682         // Log level constants.
00683         static const int OFF   = 0;    
00684         static const int FATAL = 1;    
00685         static const int ERROR = 20;   
00686         static const int WARN  = 40;   
00687         static const int INFO  = 60;   
00688         static const int DEBUG = 80;   
00689         static const int TRACE = 100;  
00690         static const int ALL   = 100;  
00691 
00701         static VString getName(int level);
00710         static int fromString(const VString& value);
00711 };
00712 
00718 class VLogger {
00719     public:
00720 
00730         static void registerLogAppenderFactory(const VString& appenderKind, VLogAppenderFactoryPtr factory);
00731 
00752         static void configure(const VFSNode& baseLogDirectory, const VSettingsNode& loggingSettings);
00758         static void shutdown();
00759 
00768         static void installNewLogAppender(const VSettingsNode& appenderSettings, const VSettingsNode& appenderDefaults);
00775         static void installNewNamedLogger(const VSettingsNode& loggerSettings);
00784         static void installNewNamedLogger(const VString& name, int level, const VStringVector& appenderNames);
00793         static void installNewNamedLogger(const VString& name, int level, const VString& appenderName);
00800         static void registerLogAppender(VLogAppenderPtr appender, bool asDefaultAppender = false);
00808         static void registerGlobalAppender(VLogAppenderPtr appender, bool asDefaultAppender = false);
00815         static void registerLogger(VNamedLoggerPtr namedLogger, bool asDefaultLogger = false);
00820         static void deregisterLogAppender(VLogAppenderPtr appender);
00825         static void deregisterLogAppender(const VString& name);
00830         static void deregisterLogger(VNamedLoggerPtr namedLogger);
00835         static void deregisterLogger(const VString& name);
00840         static void checkMaxActiveLogLevelForRemovedLogger(int removedActiveLevel);
00846         static void checkMaxActiveLogLevelForChangedLogger(int oldActiveLevel, int newActiveLevel);
00847 
00853         static bool isDefaultLogLevelActive(int level);
00859         static bool isLogLevelActive(int level);
00860 
00861         // The following "getters" and "finders" have the following consistent naming convention:
00862         // - "get" always returns a valid object; it may need to create the object in question
00863         // - "find" will return null if there is no such object; it will not create an object
00864 
00865         // Loggers:
00870         static VNamedLoggerPtr getDefaultLogger();
00875         static void setDefaultLogger(VNamedLoggerPtr namedLogger);
00882         static VNamedLoggerPtr getLogger(const VString& name);
00887         static VNamedLoggerPtr findDefaultLogger();
00893         static VNamedLoggerPtr findDefaultLoggerForLevel(int level);
00899         static VNamedLoggerPtr findNamedLogger(const VString& name);
00906         static VNamedLoggerPtr findNamedLoggerForLevel(const VString& name, int level);
00907 
00908         // Appenders:
00913         static VLogAppenderPtr getDefaultAppender();
00920         static VLogAppenderPtr getAppender(const VString& appenderName);
00926         static VLogAppenderPtrList getAllAppenders();
00931         static VLogAppenderPtr findDefaultAppender();
00937         static VLogAppenderPtr findAppender(const VString& name);
00942         static const VFSNode& getBaseLogDirectory();
00943 
00944         // These functions whose name is prefixed with "command" are intended for use at runtime from
00945         // a command facility that allows reconfiguring logging on the fly.
00946         static VBentoNode* commandGetInfo();    
00947         static VString commandGetInfoString();  
00948         static void commandNewAppender(const VString& appenderName, const VString& kind, const VString& appenderParam); 
00949         static void commandRemoveAppender(const VString& appenderName);                                                 
00950         static void commandRollAppender(const VString& appenderName);                                                   
00951         static void commandNewLogger(const VString& loggerName, const VStringVector& appenderNames);                    
00952         static void commandRemoveLogger(const VString& loggerName);                                                     
00953         static void commandSetLoggerAppenders(const VString& loggerName, const VStringVector& appenderNames);           
00954         static void commandAddLoggerAppenders(const VString& loggerName, const VStringVector& appenderNames);           
00955         static void commandRemoveLoggerAppenders(const VString& loggerName, const VStringVector& appenderNames);        
00956         static void commandSetLogLevel(const VString& loggerName, int level);                                           
00957         static void commandSetPrintStackLevel(const VString& loggerName, int printStackLevel, int count, const VDuration& timeLimit); 
00958 
00959         // Used specifically by VNamedLogger::_emitToAppenders to emit to all "global appenders" with correct locking. Should not be called elsewhere.
00960         static void emitToGlobalAppenders(int level, const char* file, int line, bool emitMessage, const VString& message, const VString& specifiedLoggerName, const VString& actualLoggerName, bool emitRawLine, const VString& rawLine);
00961         
00962         // Utility function useful in forming a logger name; returns a copy of the input string with dots (our path separators) converted to dashes.
00963         static VString getCleansedLoggerName(const VString& s);
00964 
00965     private:
00966 
00967         VLogger(const VLogger&); // not copyable
00968         VLogger& operator=(const VLogger&); // not assignable
00969 
00970         // These helper methods, like private methods in general, assume the caller has locked.
00971         static void _registerAppender(VLogAppenderPtr appender, bool asDefaultAppender = false, bool asGlobalAppender = false);
00972         static void _registerLogger(VNamedLoggerPtr namedLogger, bool asDefaultLogger = false);
00973         static VBentoNode* _commandGetInfo();
00974         static VString _commandGetInfoString();
00975 
00976         // These methods maintain the gMaxActiveLogLevel.
00977         static void _checkMaxActiveLogLevelForNewLogger(int newActiveLevel); // Called when a new logger is created, since that may change the max active log level.
00978         static void _checkMaxActiveLogLevelForRemovedLogger(int removedActiveLevel); // Called when a logger is removed, since that may change the max active log level.
00979         static void _checkMaxActiveLogLevelForChangedLogger(int oldActiveLevel, int newActiveLevel); // Called when a logger's level is changed, since that may change the max active log level.
00980         static void _recalculateMaxActiveLogLevel(); // Called when one of the _check... methods decides the max active log level may indeed have changed, and must be recalculated.
00981 
00982         // These two methods are how we really search for a specified named logger.
00983         static VNamedLoggerPtr _findNamedLoggerFromExactName(const VString& name);      
00984         static VNamedLoggerPtr _findNamedLoggerFromPathName(const VString& pathName);   
00985 
00986         // _mutexInstance() must be used internally whenever referencing these variables:
00987         volatile static int     gMaxActiveLevel;    
00988         static VNamedLoggerPtr  gDefaultLogger;     
00989         static VLogAppenderPtr  gDefaultAppender;   
00990         static VFSNode          gBaseLogDirectory;  
00991 
00992         friend class VLoggerUnit;  // unit tests directly examine our state
00993         friend bool VNamedLogger::isDefaultLogger() const;
00994         friend bool VLogAppender::isDefaultAppender() const;
00995 
00996         // Internal development debugging methods. Only enabled as needed.
00997 //#define VLOGGER_INTERNAL_DEBUGGING
00998 #ifdef VLOGGER_INTERNAL_DEBUGGING
00999         static void _reportLoggerChange(bool before, const VString& label, const VNamedLoggerPtr& was, const VNamedLoggerPtr& is);
01000         static void _reportAppenderChange(bool before, const VString& label, const VLogAppenderPtr& was, const VLogAppenderPtr& is);
01001 #else
01002         static void _reportLoggerChange(bool /*before*/, const VString& /*label*/, const VNamedLoggerPtr& /*was*/, const VNamedLoggerPtr& /*is*/) {}
01003         static void _reportAppenderChange(bool /*before*/, const VString& /*label*/, const VLogAppenderPtr& /*was*/, const VLogAppenderPtr& /*is*/) {}
01004 #endif /* VLOGGER_INTERNAL_DEBUGGING */
01005 };
01006 
01011 class VCoutLogAppender : public VLogAppender {
01012     public:
01013         VCoutLogAppender(const VString& name, bool formatOutput, const VString& formatSpec, const VString& timeFormat);
01014         VCoutLogAppender(const VSettingsNode& settings, const VSettingsNode& defaults);
01015         virtual ~VCoutLogAppender() {}
01016         virtual void addInfo(VBentoNode& infoNode) const;
01017     protected:
01018         virtual void _emitRawLine(const VString& line);
01019 };
01020 
01027 class VFileLogAppender : public VLogAppender {
01028     public:
01029         VFileLogAppender(const VString& name, bool formatOutput, const VString& formatSpec, const VString& timeFormat, const VString& filePath);
01030         VFileLogAppender(const VSettingsNode& settings, const VSettingsNode& defaults);
01031         virtual ~VFileLogAppender() {}
01032         virtual void addInfo(VBentoNode& infoNode) const;
01033     protected:
01034         virtual void _emitRawLine(const VString& line);
01035     private:
01036         void _openFile(); // constructor helper
01037         VBufferedFileStream mFileStream;    
01038         VTextIOStream       mOutputStream;  
01039 };
01040 
01052 class VRollingFileLogAppender : public VLogAppender {
01053     public:
01054         VRollingFileLogAppender(const VString& name, bool formatOutput, const VString& formatSpec, const VString& timeFormat, const VString& dirPath, const VString& fileNamePrefix, int maxNumLines);
01055         VRollingFileLogAppender(const VSettingsNode& settings, const VSettingsNode& defaults);
01056         virtual ~VRollingFileLogAppender() {}
01057         virtual void addInfo(VBentoNode& infoNode) const;
01058     protected:
01059         virtual void _emitRawLine(const VString& line);
01060 };
01061 
01066 class VSilentLogAppender : public VLogAppender {
01067     public:
01068         VSilentLogAppender(const VString& name) : VLogAppender(name, true/*this won't matter*/, VString::EMPTY(), VString::EMPTY()) {}
01069         VSilentLogAppender(const VSettingsNode& settings, const VSettingsNode& defaults) : VLogAppender(settings, defaults) {}
01070         virtual ~VSilentLogAppender() {}
01071         virtual void addInfo(VBentoNode& infoNode) const;
01072         virtual void emit(int /*level*/, const char* /*file*/, int /*line*/, bool /*emitMessage*/, const VString& /*message*/, bool /*emitRawLine*/, const VString& /*rawLine*/) {}
01073 };
01074 
01082 class VStringLogAppender : public VLogAppender {
01083     public:
01084         VStringLogAppender(const VString& name, bool formatOutput, const VString& formatSpec, const VString& timeFormat);
01085         VStringLogAppender(const VSettingsNode& settings, const VSettingsNode& defaults);
01086         virtual ~VStringLogAppender() {}
01087         virtual void addInfo(VBentoNode& infoNode) const;
01088 
01089         VMutex& getMutex() { return mMutex; }
01090         const VString& getLines() const { return mLines; }
01091         const char* orphanLines() { return mLines.orphanDataBuffer(); }
01092 
01093     protected:
01094         virtual void _emitRawLine(const VString& line);
01095     private:
01096         VString mLines;
01097 };
01098 
01105 class VStringVectorLogAppender : public VLogAppender {
01106     public:
01107         VStringVectorLogAppender(const VString& name, bool formatOutput, const VString& formatSpec, const VString& timeFormat, VStringVector* storage);
01108         VStringVectorLogAppender(const VSettingsNode& settings, const VSettingsNode& defaults);
01109         virtual ~VStringVectorLogAppender();
01110         virtual void addInfo(VBentoNode& infoNode) const;
01111 
01112         VMutex& getMutex() { return mMutex; }
01113         const VStringVector& getLines() const { return *mStorage; }
01114 
01115     protected:
01116         virtual void _emitRawLine(const VString& line);
01117     private:
01118         VStringVector* mStorage;
01119         VStringVector mLines;
01120 };
01121 
01126 class VStringLogger : public VNamedLogger {
01127     public:
01128 
01129         VStringLogger(const VString& name, int level, bool formatOutput = VLogAppender::DO_FORMAT_OUTPUT, const VString& formatSpec = VString::EMPTY(), const VString& timeFormat = VString::EMPTY());
01130         virtual ~VStringLogger() {}
01131         virtual void addInfo(VBentoNode& infoNode) const;
01132 
01133         const VString& getLines() const { return mAppender.getLines(); }
01134         const char* orphanLines() { return mAppender.orphanLines(); }
01135 
01136     protected:
01137 
01138         virtual void _emitToAppenders(int level, const char* file, int line, bool emitMessage, const VString& message, const VString& specifiedLoggerName, bool emitRawLine, const VString& rawLine);
01139 
01140     private:
01141 
01142         VStringLogAppender mAppender;
01143 
01144 };
01145 
01146 typedef VSharedPtr<VStringLogger> VStringLoggerPtr;
01147 typedef VSharedPtr<const VStringLogger> VStringLoggerConstPtr;
01148 
01153 class VStringVectorLogger : public VNamedLogger {
01154     public:
01155 
01156         VStringVectorLogger(const VString& name, int level, VStringVector* storage, bool formatOutput = VLogAppender::DO_FORMAT_OUTPUT, const VString& formatSpec = VString::EMPTY(), const VString& timeFormat = VString::EMPTY());
01157         virtual ~VStringVectorLogger() {}
01158         virtual void addInfo(VBentoNode& infoNode) const;
01159 
01160         const VStringVector& getLines() const { return mAppender.getLines(); }
01161 
01162     protected:
01163 
01164         virtual void _emitToAppenders(int level, const char* file, int line, bool emitMessage, const VString& message, const VString& specifiedLoggerName, bool emitRawLine, const VString& rawLine);
01165 
01166     private:
01167 
01168         VStringVectorLogAppender mAppender;
01169 
01170 };
01171 
01172 typedef VSharedPtr<VStringVectorLogger> VStringVectorLoggerPtr;
01173 typedef VSharedPtr<const VStringVectorLogger> VStringVectorLoggerConstPtr;
01174 
01175 #endif /* vlogger_h */

Copyright ©1997-2014 Trygve Isaacson. All rights reserved. This documentation was generated with Doxygen.