| /*---------------------------------------------------------------------------* |
| * plog.h * |
| * * |
| * Copyright 2007, 2008 Nuance Communciations, Inc. * |
| * * |
| * Licensed under the Apache License, Version 2.0 (the 'License'); * |
| * you may not use this file except in compliance with the License. * |
| * * |
| * You may obtain a copy of the License at * |
| * http://www.apache.org/licenses/LICENSE-2.0 * |
| * * |
| * Unless required by applicable law or agreed to in writing, software * |
| * distributed under the License is distributed on an 'AS IS' BASIS, * |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * |
| * See the License for the specific language governing permissions and * |
| * limitations under the License. * |
| * * |
| *---------------------------------------------------------------------------*/ |
| |
| #ifndef PLOG_H |
| #define PLOG_H |
| |
| |
| |
| #include "ESR_ReturnCode.h" |
| #include "PortPrefix.h" |
| #ifdef USE_STACKTRACE |
| #include "PStackTrace.h" |
| #endif |
| #include "passert.h" |
| #include "PFileSystem.h" |
| #include "ptypes.h" |
| |
| /** |
| * @addtogroup PLogModule PLogger API functions |
| * Logging API. |
| * |
| * Must call pmemInit() before using this module. |
| * |
| * The logging API is composed of a Logger. |
| * A Logger is an object who implements an API to actually write log messages. |
| * The logging API uses the logger when logging is to be performed but does |
| * not depend on an actual implementation of this API. |
| * |
| * When a request for logging is performed, the current level of the logging |
| * API is compared with the current stack-trace level. If the logger's log |
| * level is greater than or equal to the stack-trace level, then the |
| * message is being logged through the use of the Logger. Otherwise, the |
| * message is not logged. Setting the log level of the API to UINT_MAX is |
| * equivalent to unconditionally log all messages from all modules. Conversely, |
| * setting the log level of the API to 0 is equivalent to disabling logging globally. |
| * |
| * @{ |
| */ |
| |
| |
| /** |
| * Portable logging framework. |
| */ |
| typedef struct PLogger_t |
| { |
| /** |
| * Prints and formats a message to the log. |
| * |
| * @param self the Logger. |
| * |
| * @param format the format string specifying the next arguments (a la |
| * printf). |
| * |
| * @return ESR_SUCCESS if success, otherwise a status code indicating the |
| * nature of the error. |
| */ |
| ESR_ReturnCode(*printf)(struct PLogger_t *self, |
| const LCHAR *format, ...); |
| |
| /** |
| * Flushes internal buffer. This function can be left unimplemented if no |
| * buffering is performed by the logger. |
| |
| * @param self the Logger |
| * |
| * @return ESR_SUCCESS if success, otherwise a status code indicating the nature of the error. |
| */ |
| ESR_ReturnCode(*flush)(struct PLogger_t *self); |
| |
| /** |
| * Destroys the logger. This function is responsible to deallocate any |
| * resources used by the logger. In particular, if buffering is internally |
| * used, it needs to flush the buffer. |
| */ |
| void(*destroy)(struct PLogger_t *self); |
| } |
| PLogger; |
| |
| /** |
| * Type used to control output format. |
| */ |
| typedef asr_uint16_t LOG_OUTPUT_FORMAT; |
| |
| /** |
| * Specifies that no extra information is to be output. |
| */ |
| #define LOG_OUTPUT_FORMAT_NONE 0x0000 |
| |
| /** |
| * Specifies that the date and time is to be output. |
| */ |
| #define LOG_OUTPUT_FORMAT_DATE_TIME 0x0001 |
| |
| /** |
| * Specifies that thread id of thread generating the message is to be output. |
| */ |
| #define LOG_OUTPUT_FORMAT_THREAD_ID 0x0002 |
| |
| /** |
| * Specifies that the module name of the module generating the message is to |
| * be output. |
| */ |
| #define LOG_OUTPUT_FORMAT_MODULE_NAME 0x0004 |
| |
| /** |
| * Initializes the LOG library. This function must be called before any |
| * logging can take place. PtrdInit() must be called before this function on |
| * platforms that support threads. |
| * |
| * @param logger The logger to be used to output the messages. If NULL, then |
| * logging goes to PSTDERR. |
| * |
| * @param logLevel The level of logging requested. |
| * |
| * @return ESR_SUCCESS if success, otherwise a status code indicating the |
| * nature of the error. In particular, it returns ESR_INVALID_STATE if already |
| * initialized. |
| */ |
| PORTABLE_API ESR_ReturnCode PLogInit(PLogger *logger, unsigned int logLevel); |
| |
| /** |
| * Indicates if PLog module is initialized. |
| * |
| * @param isInit True if module is initialized |
| * @return ESR_INVALID_ARGUMENT if isLocked is null |
| */ |
| PORTABLE_API ESR_ReturnCode PLogIsInitialized(ESR_BOOL* isInit); |
| |
| /** |
| * Indicates if PLog module is locked inside a critical section. This is for internal use only. |
| * |
| * @param isLocked True if module is locked |
| * @return ESR_INVALID_ARGUMENT if isLocked is null |
| */ |
| PORTABLE_API ESR_ReturnCode PLogIsLocked(ESR_BOOL* isLocked); |
| |
| /** |
| * Shutdowns the LOG library. Once this function is called, no logging |
| * activity can be performed. |
| * |
| * @return ESR_SUCCESS if success, otherwise a status code indicating the |
| * nature of the error. In particular, it returns ESR_INVALID_STATE if not |
| * initialized or already shutted down. |
| */ |
| PORTABLE_API ESR_ReturnCode PLogShutdown(void); |
| |
| /** |
| * Sets the format of the logging messages. If this function is never called, |
| * the default format is |
| * |
| * <code>LOG_OUTPUT_FORMAT_MODULE_NAME | LOG_OUTPUT_FORMAT_DATE_TIME</code>. |
| * |
| * @param format the format specification for new messages. |
| * |
| * @return ESR_SUCCESS if success, otherwise a status code indicating the |
| * nature of the error. |
| */ |
| PORTABLE_API ESR_ReturnCode PLogSetFormat(LOG_OUTPUT_FORMAT format); |
| |
| /** |
| * Gets the current log level of the LOG API. |
| * |
| * @param logLevel A pointer to where the log level is to be stored. If NULL, |
| * the function returns ESR_INVALID_ARGUMENT. |
| * |
| * @return ESR_SUCCESS if success, otherwise a status code indicating the |
| * nature of the error. In particular, it returns ESR_INVALID_STATE if the |
| * API is not initialized. |
| */ |
| PORTABLE_API ESR_ReturnCode PLogGetLevel(unsigned int *logLevel); |
| |
| |
| /** |
| * Sets the current log level of the LOG API. |
| * |
| * @param logLevel The new log level. |
| * |
| * @return ESR_SUCCESS if success, otherwise a status code indicating the |
| * nature of the error. In particular, it returns ESR_INVALID_STATE if the |
| * API is not initialized. |
| */ |
| PORTABLE_API ESR_ReturnCode PLogSetLevel(unsigned int logLevel); |
| |
| /** |
| * Conditionally Logs a message. The message is logged only if module is enabled. |
| * |
| * @param msg The message format specification (ala printf). |
| * |
| * @return ESR_SUCCESS if success, otherwise a status code indicating the |
| * nature of the error. In particular, it returns ESR_INVALID_STATE if |
| * the API is not initialized. |
| */ |
| PORTABLE_API ESR_ReturnCode PLogMessage(const LCHAR* msg, ...); |
| |
| /** |
| * Unconditionally logs an error message. |
| * |
| * @param msg The message format specification (ala printf). |
| * |
| * @return ESR_SUCCESS if success, otherwise a status code indicating the |
| * nature of the error. In particular, it returns ESR_INVALID_STATE if |
| * the API is not initialized. |
| */ |
| PORTABLE_API ESR_ReturnCode PLogError(const LCHAR* msg, ...); |
| |
| |
| /** |
| * |
| * Creates a logger that logs to a file. |
| * |
| * @param file The file to log to. |
| * @param logger logger handle receiving the created logger. |
| * |
| * @return ESR_SUCCESS if success, otherwise a status code indicating the |
| * nature of the error. |
| */ |
| PORTABLE_API ESR_ReturnCode PLogCreateFileLogger(PFile* file, |
| PLogger** logger); |
| |
| /** |
| * Creates a logger that logs to a circular file. |
| * |
| * @param filename The name of the file to be created. |
| * @param maxsize The maximum number of bytes that the file may have. |
| * @param logger logger handle receiving the created logger. |
| * |
| * @return ESR_SUCCESS if success, otherwise a status code indicating the |
| * nature of the error. |
| */ |
| PORTABLE_API ESR_ReturnCode PLogCreateCircularFileLogger(const LCHAR* filename, |
| unsigned int maxsize, |
| PLogger** logger); |
| |
| |
| |
| /** |
| * Runs a function, checks its return-code. In case of an error, logs it and jumps to |
| * the CLEANUP label. |
| */ |
| /* show more information for vxworks due to lack of stack trace */ |
| #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) |
| /** |
| * Invokes the function with args and if it is not ESR_SUCCESS, logs and |
| * returns it. |
| * |
| * @param rc Used to store the function return value |
| * @param function Function name |
| * @param args Function arguments |
| */ |
| #define PLOG_CHKRC_ARGS(rc, function, args) do { if((rc = (function args)) != ESR_SUCCESS) { PLogError(ESR_rc2str(rc)); return rc; } } while (0) |
| |
| /** |
| * Checks the function return-code and if it is not ESR_SUCCESS, logs and |
| * returns it. |
| */ |
| #define PLOG_CHKRC(rc, function) do { rc = (function); if (rc != ESR_SUCCESS) { PLogError(rc); return rc; } } while (0) |
| |
| #if defined(_DEBUG) && !defined(ENABLE_PLOG_TRACE) && ENABLE_STACKTRACE |
| #define ENABLE_PLOG_TRACE |
| #endif |
| |
| /** |
| * Macro used to have logging enabled on debug build only. |
| */ |
| #ifdef ENABLE_PLOG_TRACE |
| |
| #define PLOG_DBG_ERROR(msg) ((void) (PLogError msg)) |
| /** |
| * Usage: PLOG_DBG_TRACE((printf-arguments)) |
| * |
| * The reason we require double brackets is to allow the use of printf-style variable |
| * argument listings in a macro. |
| */ |
| #define PLOG_DBG_TRACE(args) ((void) (PLogMessage args)) |
| #define PLOG_DBG_BLOCK(block) block |
| #define PLOG_DBG_API_ENTER() \ |
| do \ |
| { \ |
| LCHAR text[P_MAX_FUNCTION_NAME]; \ |
| size_t len = P_MAX_FUNCTION_NAME; \ |
| ESR_ReturnCode rc; \ |
| \ |
| rc = PStackTraceGetFunctionName(text, &len); \ |
| if (rc==ESR_SUCCESS) \ |
| PLogMessage(L("%s entered."), text); \ |
| else if (rc!=ESR_NOT_SUPPORTED) \ |
| pfprintf(PSTDERR, L("[%s:%d] PStackTraceGetValue failed with %s\n"), __FILE__, __LINE__, ESR_rc2str(rc)); \ |
| } while (0) |
| |
| #define PLOG_DBG_API_EXIT(rc) \ |
| \ |
| do \ |
| { \ |
| LCHAR text[P_MAX_FUNCTION_NAME]; \ |
| size_t len = P_MAX_FUNCTION_NAME; \ |
| ESR_ReturnCode rc2; \ |
| \ |
| rc2 = PStackTraceGetFunctionName(text, &len); \ |
| if (rc2==ESR_SUCCESS) \ |
| PLogMessage(L("%s returned %s"), text, ESR_rc2str(rc)); \ |
| else if (rc!=ESR_NOT_SUPPORTED) \ |
| pfprintf(PSTDERR, "[%s:%d] PStackTraceGetValue failed with %s\n", __FILE__, __LINE__, ESR_rc2str(rc2)); \ |
| } while (0) |
| |
| #else |
| |
| #ifndef DOXYGEN_SHOULD_SKIP_THIS |
| #define PLOG_DBG_ERROR(msg) ((void) 0) |
| #define PLOG_DBG_MODULE(name, logLevel) |
| #define PLOG_DBG_TRACE(args) ((void) 0) |
| #define PLOG_DBG_BLOCK(block) |
| #define PLOG_DBG_API_ENTER() ((void) 0) |
| #define PLOG_DBG_API_EXIT(rc) ((void) 0) |
| #endif /* DOXYGEN_SHOULD_SKIP_THIS */ |
| #endif /* ENABLE_PLOG_TRACE */ |
| |
| /** |
| * @} |
| */ |
| |
| |
| #endif |