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