1 //----------------------------------------------------------------------------- 2 // 3 // Log.h 4 // 5 // Cross-platform message and error logging 6 // 7 // Copyright (c) 2010 Mal Lansell <mal@lansell.org> 8 // All rights reserved. 9 // 10 // SOFTWARE NOTICE AND LICENSE 11 // 12 // This file is part of OpenZWave. 13 // 14 // OpenZWave is free software: you can redistribute it and/or modify 15 // it under the terms of the GNU Lesser General Public License as published 16 // by the Free Software Foundation, either version 3 of the License, 17 // or (at your option) any later version. 18 // 19 // OpenZWave is distributed in the hope that it will be useful, 20 // but WITHOUT ANY WARRANTY; without even the implied warranty of 21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 // GNU Lesser General Public License for more details. 23 // 24 // You should have received a copy of the GNU Lesser General Public License 25 // along with OpenZWave. If not, see <http://www.gnu.org/licenses/>. 26 // 27 //----------------------------------------------------------------------------- 28 #ifndef _Log_H 29 #define _Log_H 30 31 #include <stdarg.h> 32 #include <string> 33 #include <vector> 34 #include "Defs.h" 35 36 namespace OpenZWave 37 { 38 namespace Internal 39 { 40 namespace Platform 41 { 42 class Mutex; 43 } 44 } 45 extern char const *LogLevelString[]; 46 47 /** \brief Various LogLevels available to the Application 48 * \ingroup Platform 49 * 50 * \see Log::SetLoggingState 51 */ 52 enum LogLevel 53 { 54 LogLevel_Invalid, /**< Invalid Log Status */ 55 LogLevel_None, /**< Disable all logging */ 56 LogLevel_Always, /**< These messages should always be shown */ 57 LogLevel_Fatal, /**< A likely fatal issue in the library */ 58 LogLevel_Error, /**< A serious issue with the library or the network */ 59 LogLevel_Warning, /**< A minor issue from which the library should be able to recover */ 60 LogLevel_Alert, /**< Something unexpected by the library about which the controlling application should be aware */ 61 LogLevel_Info, /**< Everything is working fine...these messages provide streamlined feedback on each message */ 62 LogLevel_Detail, /**< Detailed information on the progress of each message */ 63 LogLevel_Debug, /**< Very detailed information on progress that will create a huge log file quickly 64 But this level (as others) can be queued and sent to the log only on an error or warning */ 65 LogLevel_StreamDetail, /**< Will include low-level byte transfers from controller to buffer to application and back */ 66 LogLevel_Internal /**< Used only within the log class (uses existing timestamp, etc.) */ 67 }; 68 69 /** \brief A Abstract class to create a Custom Logging Method 70 * \ingroup Platform 71 * 72 * Use this as the basis to create a custom logging class for your applation. 73 * \see Log::SetLoggingClass 74 */ 75 class i_LogImpl 76 { 77 public: i_LogImpl()78 i_LogImpl() 79 { 80 } 81 ; ~i_LogImpl()82 virtual ~i_LogImpl() 83 { 84 } 85 ; 86 virtual void Write(LogLevel _level, uint8 const _nodeId, char const* _format, va_list _args) = 0; 87 virtual void QueueDump() = 0; 88 virtual void QueueClear() = 0; 89 virtual void SetLoggingState(LogLevel _saveLevel, LogLevel _queueLevel, LogLevel _dumpTrigger) = 0; 90 virtual void SetLogFileName(const string &_filename) = 0; 91 }; 92 93 /** \brief Implements a platform-independent log...written to the console and, optionally, a file. 94 * \ingroup Platform 95 */ 96 class OPENZWAVE_EXPORT Log 97 { 98 public: 99 /** \brief Create a log. 100 * 101 * Creates the cross-platform logging singleton. 102 * Any previous log will be cleared. 103 * \return a pointer to the logging object. 104 * \see Destroy, Write 105 */ 106 static Log* Create(string const& _filename, bool const _bAppend, bool const _bConsoleOutput, LogLevel const _saveLevel, LogLevel const _queueLevel, LogLevel const _dumpTrigger); 107 108 /** \brief Create a log. 109 * 110 * Creates the cross-platform logging singleton. 111 * Any previous log will be cleared. 112 * \param LogClass a Logging Class that inherits the i_LogImpl Class to use to Log 113 * \return a pointer to the logging object. 114 * \see Destroy, Write 115 */ 116 117 static Log* Create(i_LogImpl *LogClass); 118 119 /** \brief Destroys the log. 120 * 121 * Destroys the logging singleton. The log can no longer 122 * be written to without another call to Create. 123 * \see Create, Write 124 */ 125 static void Destroy(); 126 127 /** 128 * \brief Set the Logging Implementation Class to replace the standard File/Console logging 129 * 130 * \param LogClass A Logging Class that inherits the i_LogImpl Class used to Log to 131 * \param Append if this new Logging Class should be appended to the list of Logging Implementations, 132 * or replace the existing Logging Class 133 * \return Bool Value indicating success or failure 134 */ 135 static bool SetLoggingClass(i_LogImpl *LogClass, bool Append = false); 136 137 /** \brief Enable or disable library logging (retained for backward compatibility) 138 * 139 * \param _dologging If true, logging is enabled; if false, disabled 140 */ 141 static void SetLoggingState(bool _dologging); 142 143 /**\brief Enable or disable library logging. 144 * 145 * To disable, set _saveLevel and _queueLevel to LogLevel_None. 146 * 147 * \param _saveLevel LogLevel of messages to write in real-time 148 * \param _queueLevel LogLevel of messages to queue to be dumped in case of an error 149 * \param _dumpTrigger LogLevel of message that triggers a queue dump (probably LogLevel_Error or LogLevel_Warning) 150 */ 151 static void SetLoggingState(LogLevel _saveLevel, LogLevel _queueLevel, LogLevel _dumpTrigger); 152 153 /**\brief Determine whether logging is enabled or not (retained for backward compatibility) 154 * 155 * \param _dologging If true, logging is enabled; if false, disabled 156 */ 157 static bool GetLoggingState(); 158 159 /**\brief Obtain the various logging levels. 160 * 161 * \param _saveLevel LogLevel of messages to write in real-time 162 * \param _queueLevel LogLevel of messages to queue to be dumped in case of an error 163 * \param _dumpTrigger LogLevel of message that triggers a queue dump (probably LogLevel_Error or LogLevel_Warning) 164 */ 165 static void GetLoggingState(LogLevel* _saveLevel, LogLevel* _queueLevel, LogLevel* _dumpTrigger); 166 167 /** \brief Change the log file name. 168 * 169 * This will start a new log file (or potentially start appending 170 * information to an existing one. Developers might want to use this function, together with a timer 171 * in the controlling application, to create timestamped log file names. 172 * \param _filename Name of the new (or existing) file to use for log output. 173 */ 174 static void SetLogFileName(const string &_filename); 175 176 /**\brief Write an entry to the log. 177 * 178 * Writes a formatted string to the log. 179 * \param _level Specifies the type of log message (Error, Warning, Debug, etc.) 180 * \param _format. A string formatted in the same manner as used with printf etc. 181 * \param ... a variable number of arguments, to be included in the formatted string. 182 * \see Create, Destroy 183 */ 184 static void Write(LogLevel _level, char const* _format, ...); 185 186 /**\brief Write an entry to the log. 187 * 188 * Writes a formatted string to the log. 189 * \param _level Specifies the type of log message (Error, Warning, Debug, etc.) 190 * \param _nodeId Node Id this entry is about. 191 * \param _format. A string formatted in the same manner as used with printf etc. 192 * \param ... a variable number of arguments, to be included in the formatted string. 193 * \see Create, Destroy 194 */ 195 static void Write(LogLevel _level, uint8 const _nodeId, char const* _format, ...); 196 197 /** \brief Send the queued log messages to the log output. 198 */ 199 static void QueueDump(); 200 201 /** 202 * Clear the log message queue 203 */ 204 static void QueueClear(); 205 206 private: 207 Log(string const& _filename, bool const _bAppend, bool const _bConsoleOutput, LogLevel _saveLevel, LogLevel _queueLevel, LogLevel _dumpTrigger); 208 ~Log(); 209 210 static std::vector<i_LogImpl*> m_pImpls; /**< Pointer to an object that encapsulates the platform-specific logging implementation. */ 211 static Log* s_instance; 212 Internal::Platform::Mutex* m_logMutex; 213 }; 214 } // namespace OpenZWave 215 216 #endif //_Log_H 217