• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*---------------------------------------------------------------------------*
2  *  plog.h  *
3  *                                                                           *
4  *  Copyright 2007, 2008 Nuance Communciations, Inc.                               *
5  *                                                                           *
6  *  Licensed under the Apache License, Version 2.0 (the 'License');          *
7  *  you may not use this file except in compliance with the License.         *
8  *                                                                           *
9  *  You may obtain a copy of the License at                                  *
10  *      http://www.apache.org/licenses/LICENSE-2.0                           *
11  *                                                                           *
12  *  Unless required by applicable law or agreed to in writing, software      *
13  *  distributed under the License is distributed on an 'AS IS' BASIS,        *
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
15  *  See the License for the specific language governing permissions and      *
16  *  limitations under the License.                                           *
17  *                                                                           *
18  *---------------------------------------------------------------------------*/
19 
20 #ifndef PLOG_H
21 #define PLOG_H
22 
23 
24 
25 #include "ESR_ReturnCode.h"
26 #include "PortPrefix.h"
27 #ifdef USE_STACKTRACE
28 #include "PStackTrace.h"
29 #endif
30 #include "passert.h"
31 #include "PFileSystem.h"
32 #include "ptypes.h"
33 
34 /**
35  * @addtogroup PLogModule PLogger API functions
36  * Logging API.
37  *
38  * Must call pmemInit() before using this module.
39  *
40  * The logging API is composed of a Logger.
41  * A Logger is an object who implements an API to actually write log messages.
42  * The logging API uses the logger when logging is to be performed but does
43  * not depend on an actual implementation of this API.
44  *
45  * When a request for logging is performed, the current level of the logging
46  * API is compared with the current stack-trace level.  If the logger's log
47  * level is greater than or equal to the stack-trace level, then the
48  * message is being logged through the use of the Logger.  Otherwise, the
49  * message is not logged.  Setting the log level of the API to UINT_MAX is
50  * equivalent to unconditionally log all messages from all modules. Conversely,
51  * setting the log level of the API to 0 is equivalent to disabling logging globally.
52  *
53  * @{
54  */
55 
56 
57 /**
58  * Portable logging framework.
59  */
60 typedef struct PLogger_t
61 {
62   /**
63    * Prints and formats a message to the log.
64    *
65    * @param self the Logger.
66    *
67    * @param format the format string specifying the next arguments (a la
68    * printf).
69    *
70    * @return ESR_SUCCESS if success, otherwise a status code indicating the
71    * nature of the error.
72    */
73   ESR_ReturnCode(*printf)(struct PLogger_t *self,
74                           const LCHAR *format, ...);
75 
76   /**
77    * Flushes internal buffer.  This function can be left unimplemented if no
78    * buffering is performed by the logger.
79 
80    * @param self the Logger
81    *
82    * @return ESR_SUCCESS if success, otherwise a status code indicating the nature of the error.
83    */
84   ESR_ReturnCode(*flush)(struct PLogger_t *self);
85 
86   /**
87    * Destroys the logger.  This function is responsible to deallocate any
88    * resources used by the logger.  In particular, if buffering is internally
89    * used, it needs to flush the buffer.
90    */
91   void(*destroy)(struct PLogger_t *self);
92 }
93 PLogger;
94 
95 /**
96  * Type used to control output format.
97  */
98 typedef asr_uint16_t LOG_OUTPUT_FORMAT;
99 
100 /**
101  * Specifies that no extra information is to be output.
102  */
103 #define LOG_OUTPUT_FORMAT_NONE 0x0000
104 
105 /**
106  * Specifies that the date and time is to be output.
107  */
108 #define LOG_OUTPUT_FORMAT_DATE_TIME 0x0001
109 
110 /**
111  * Specifies that thread id of thread generating the message is to be output.
112  */
113 #define LOG_OUTPUT_FORMAT_THREAD_ID 0x0002
114 
115 /**
116  * Specifies that the module name of the module generating the message is to
117  * be output.
118  */
119 #define LOG_OUTPUT_FORMAT_MODULE_NAME 0x0004
120 
121 /**
122  * Initializes the LOG library.  This function must be called before any
123  * logging can take place. PtrdInit() must be called before this function on
124  * platforms that support threads.
125  *
126  * @param logger The logger to be used to output the messages.  If NULL, then
127  * logging goes to PSTDERR.
128  *
129  * @param logLevel The level of logging requested.
130  *
131  * @return ESR_SUCCESS if success, otherwise a status code indicating the
132  * nature of the error. In particular, it returns ESR_INVALID_STATE if already
133  * initialized.
134  */
135 PORTABLE_API ESR_ReturnCode PLogInit(PLogger *logger, unsigned int logLevel);
136 
137 /**
138  * Indicates if PLog module is initialized.
139  *
140  * @param isInit True if module is initialized
141  * @return ESR_INVALID_ARGUMENT if isLocked is null
142  */
143 PORTABLE_API ESR_ReturnCode PLogIsInitialized(ESR_BOOL* isInit);
144 
145 /**
146  * Indicates if PLog module is locked inside a critical section. This is for internal use only.
147  *
148  * @param isLocked True if module is locked
149  * @return ESR_INVALID_ARGUMENT if isLocked is null
150  */
151 PORTABLE_API ESR_ReturnCode PLogIsLocked(ESR_BOOL* isLocked);
152 
153 /**
154  * Shutdowns the LOG library.  Once this function is called, no logging
155  * activity can be performed.
156  *
157  * @return ESR_SUCCESS if success, otherwise a status code indicating the
158  * nature of the error.  In particular, it returns ESR_INVALID_STATE if not
159  * initialized or already shutted down.
160  */
161 PORTABLE_API ESR_ReturnCode PLogShutdown(void);
162 
163 /**
164  * Sets the format of the logging messages.  If this function is never called,
165  * the default format is
166  *
167  * <code>LOG_OUTPUT_FORMAT_MODULE_NAME | LOG_OUTPUT_FORMAT_DATE_TIME</code>.
168  *
169  * @param format the format specification for new messages.
170  *
171  * @return ESR_SUCCESS if success, otherwise a status code indicating the
172  * nature of the error.
173  */
174 PORTABLE_API ESR_ReturnCode PLogSetFormat(LOG_OUTPUT_FORMAT format);
175 
176 /**
177  * Gets the current log level of the LOG API.
178  *
179  * @param logLevel A pointer to where the log level is to be stored.  If NULL,
180  * the function returns ESR_INVALID_ARGUMENT.
181  *
182  * @return ESR_SUCCESS if success, otherwise a status code indicating the
183  * nature of the error.  In particular, it returns ESR_INVALID_STATE if the
184  * API is not initialized.
185  */
186 PORTABLE_API ESR_ReturnCode PLogGetLevel(unsigned int *logLevel);
187 
188 
189 /**
190  * Sets the current log level of the LOG API.
191  *
192  * @param logLevel The new log level.
193  *
194  * @return ESR_SUCCESS if success, otherwise a status code indicating the
195  * nature of the error.  In particular, it returns ESR_INVALID_STATE if the
196  * API is not initialized.
197  */
198 PORTABLE_API ESR_ReturnCode PLogSetLevel(unsigned int logLevel);
199 
200 /**
201  * Conditionally Logs a message.  The message is logged only if module is enabled.
202  *
203  * @param msg The message format specification (ala printf).
204  *
205  * @return ESR_SUCCESS if success, otherwise a status code indicating the
206  * nature of the error.  In particular, it returns ESR_INVALID_STATE if
207  * the API is not initialized.
208  */
209 PORTABLE_API ESR_ReturnCode PLogMessage(const LCHAR* msg, ...);
210 
211 /**
212  * Unconditionally logs an error message.
213  *
214  * @param msg The message format specification (ala printf).
215  *
216  * @return ESR_SUCCESS if success, otherwise a status code indicating the
217  * nature of the error.  In particular, it returns ESR_INVALID_STATE if
218  * the API is not initialized.
219  */
220 PORTABLE_API ESR_ReturnCode PLogError(const LCHAR* msg, ...);
221 
222 
223 /**
224  *
225  * Creates a logger that logs to a file.
226  *
227  * @param file The file to log to.
228  * @param logger logger handle receiving the created logger.
229  *
230  * @return ESR_SUCCESS if success, otherwise a status code indicating the
231  * nature of the error.
232  */
233 PORTABLE_API ESR_ReturnCode PLogCreateFileLogger(PFile* file,
234     PLogger** logger);
235 
236 /**
237  * Creates a logger that logs to a circular file.
238  *
239  * @param filename The name of the file to be created.
240  * @param maxsize The maximum number of bytes that the file may have.
241  * @param logger logger handle receiving the created logger.
242  *
243  * @return ESR_SUCCESS if success, otherwise a status code indicating the
244  * nature of the error.
245  */
246 PORTABLE_API ESR_ReturnCode PLogCreateCircularFileLogger(const LCHAR* filename,
247     unsigned int maxsize,
248     PLogger** logger);
249 
250 
251 
252 /**
253  * Runs a function, checks its return-code. In case of an error, logs it and jumps to
254  * the CLEANUP label.
255  */
256 /* show more information for vxworks due to lack of stack trace */
257 #define CHKLOG(rc, function) do { rc = (function); if (rc != ESR_SUCCESS) { PLogError("%s in %s:%d", ESR_rc2str(rc),  __FILE__, __LINE__); goto CLEANUP; } } while (0)
258 /**
259  * Invokes the function with args and if it is not ESR_SUCCESS, logs and
260  * returns it.
261  *
262  * @param rc Used to store the function return value
263  * @param function Function name
264  * @param args Function arguments
265  */
266 #define PLOG_CHKRC_ARGS(rc, function, args) do { if((rc = (function args)) != ESR_SUCCESS) { PLogError(ESR_rc2str(rc)); return rc; } } while (0)
267 
268 /**
269  * Checks the function return-code and if it is not ESR_SUCCESS, logs and
270  * returns it.
271  */
272 #define PLOG_CHKRC(rc, function) do { rc = (function); if (rc != ESR_SUCCESS) { PLogError(rc); return rc; } } while (0)
273 
274 #if defined(_DEBUG) && !defined(ENABLE_PLOG_TRACE) && ENABLE_STACKTRACE
275 #define ENABLE_PLOG_TRACE
276 #endif
277 
278 /**
279  * Macro used to have logging enabled on debug build only.
280  */
281 #ifdef ENABLE_PLOG_TRACE
282 
283 #define PLOG_DBG_ERROR(msg) ((void) (PLogError msg))
284 /**
285  * Usage: PLOG_DBG_TRACE((printf-arguments))
286  *
287  * The reason we require double brackets is to allow the use of printf-style variable
288  * argument listings in a macro.
289  */
290 #define PLOG_DBG_TRACE(args) ((void) (PLogMessage args))
291 #define PLOG_DBG_BLOCK(block) block
292 #define PLOG_DBG_API_ENTER() \
293   do \
294   { \
295     LCHAR text[P_MAX_FUNCTION_NAME]; \
296     size_t len = P_MAX_FUNCTION_NAME; \
297     ESR_ReturnCode rc; \
298     \
299     rc = PStackTraceGetFunctionName(text, &len); \
300     if (rc==ESR_SUCCESS) \
301       PLogMessage(L("%s entered."), text); \
302     else if (rc!=ESR_NOT_SUPPORTED) \
303       pfprintf(PSTDERR, L("[%s:%d] PStackTraceGetValue failed with %s\n"), __FILE__, __LINE__, ESR_rc2str(rc)); \
304   } while (0)
305 
306 #define PLOG_DBG_API_EXIT(rc) \
307   \
308   do \
309   { \
310     LCHAR text[P_MAX_FUNCTION_NAME]; \
311     size_t len = P_MAX_FUNCTION_NAME; \
312     ESR_ReturnCode rc2; \
313     \
314     rc2 = PStackTraceGetFunctionName(text, &len); \
315     if (rc2==ESR_SUCCESS) \
316       PLogMessage(L("%s returned %s"), text, ESR_rc2str(rc)); \
317     else if (rc!=ESR_NOT_SUPPORTED) \
318       pfprintf(PSTDERR, "[%s:%d] PStackTraceGetValue failed with %s\n", __FILE__, __LINE__, ESR_rc2str(rc2)); \
319   } while (0)
320 
321 #else
322 
323 #ifndef DOXYGEN_SHOULD_SKIP_THIS
324 #define PLOG_DBG_ERROR(msg) ((void) 0)
325 #define PLOG_DBG_MODULE(name, logLevel)
326 #define PLOG_DBG_TRACE(args) ((void) 0)
327 #define PLOG_DBG_BLOCK(block)
328 #define PLOG_DBG_API_ENTER() ((void) 0)
329 #define PLOG_DBG_API_EXIT(rc) ((void) 0)
330 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
331 #endif /* ENABLE_PLOG_TRACE */
332 
333 /**
334  * @}
335  */
336 
337 
338 #endif
339