File: [OMI] / omi / base / log.h
(download)
Revision: 1.1,
Wed May 30 21:47:49 2012 UTC (12 years, 1 month ago) by mike
Branch: MAIN
Initial revision
|
/*
**==============================================================================
**
** Open Management Infrastructure (OMI)
**
** Copyright (c) Microsoft Corporation
**
** 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
**
** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
** MERCHANTABLITY OR NON-INFRINGEMENT.
**
** See the Apache 2 License for the specific language governing permissions
** and limitations under the License.
**
**==============================================================================
*/
#ifndef _omi_log_h
#define _omi_log_h
#include <common.h>
#include <stdarg.h>
BEGIN_EXTERNC
/*
**==============================================================================
**
** Log
**
** This interface supports writing of log entries to a flat file. The
** following fragment shows how to use the logging facility.
**
** Log_Open("/var/log/mylogfile");
** ...
** Log_Put(LOG_ERROR, __FILE__, __LINE__, "bad sock=%u", sock);
** Log_Put(LOG_INFO, __FILE__, __LINE__, "started");
** Log_Put(LOG_DEBUG, __FILE__, __LINE__, "got this far");
** ...
** Log_Close();
**
** The first argument of Log_Put() is the log level, which is one of
** the following (in descending order of priority).
**
** LOG_FATAL
** LOG_ERROR
** LOG_WARNING
** LOG_INFO
** LOG_DEBUG
**
** Passing one of these to Log_SetLevel() affects which entries are
** written to the log and which are ignored. For example, to log only
** LOG_FATAL and LOG_ERROR levels, call Log_SetLevel as follows.
**
** Log_SetLevel(LOG_ERROR);
**
** Afterwards, attempts to log anything below the LOG_ERROR level are
** ignored. The default log level is LOG_WARNING.
**
** The following macros simplify the writing of log entries by allowing
** the caller to omit the level, __FILE__, and __LINE__ arguments.
**
** LOGF() - LOG_FATAL
** LOGE() - LOG_ERROR
** LOGW() - LOG_WARNING
** LOGI() - LOG_INFO
** LOGD() - LOG_DEBUG
**
** Using these macros reduces the code example above to this.
**
** Log_Open("/var/log/mylogfile");
** ...
** LOGE(("bad sock=%u", sock));
** LOGI(("started"));
** LOGD(("got this far"));
** ...
** Log_Close();
**
** Notice the use of double parentheses (since macros do not support
** varying argument lists).
**
** Log entries have this format:
**
** YYYY/MM/DD HH:MM:SS: LEVEL: FILE(LINE): message...
**
** The code snippet above produces the following log entries.
**
** 2010/01/01 12:43:26: ERROR: erp.c(10): bad sock=14
** 2010/01/01 12:43:27: INFO: erp.c(11): started
** 2010/01/01 12:43:28: DEBUG: erp.c(12): got this far
**
**==============================================================================
*/
/* Log levels (default level is LOG_WARNING */
typedef enum _Log_Level
{
LOG_FATAL,
LOG_ERROR,
LOG_WARNING,
LOG_INFO,
LOG_DEBUG
}
Log_Level;
/* Open 'path' for append (create if it does not exist). */
MI_Result Log_Open(
const MI_Char* path);
/* Open 'fd' for append. */
MI_Result Log_OpenFD(
int fd);
/* Open log and write log entries to standard error */
MI_Result Log_OpenStdErr();
/* Close the log file. */
void Log_Close();
/* Set the log level (ignore all log writes below this level). */
void Log_SetLevel(
Log_Level level);
/* Get the current log level */
Log_Level Log_GetLevel();
/* Set the level from one of the following strings/numbers:
* FATAL/1
* ERROR/2
* WARNING/3
* INFO/4
* DEBUG/5
*
* Examples:
* Log_SetLevelFromString("DEBUG");
* Log_SetLevelFromString("3");
*/
int Log_SetLevelFromString(const char* level);
/* Get a string representing the current log level, which will be one of the
* following symbols: FATAL, ERROR, WARNING, INFO, DEBUG.
*/
const char* Log_GetLevelString(Log_Level level);
PRINTF_FORMAT(4, 5)
int Log_Put(
Log_Level level,
const char* file,
MI_Uint32 line,
const MI_Char* format,
...);
/* Va_List form of Log_Put. Returns '1' if output required,'0' otherwise*/
int Log_VPut(
Log_Level level,
const char* file,
MI_Uint32 line,
const MI_Char* format,
va_list ap);
/* Private internal function. */
int __Log_Put1(
Log_Level level,
const char* file,
MI_Uint32 line);
/* Private internal function. */
PRINTF_FORMAT(1, 2)
void __Log_Put2(
const MI_Char* format,
...);
/* Private internal function. */
PRINTF_FORMAT(1, 2)
void __Log_Put2_char(
const char* format,
...);
/*
* This funtion appears as the false condition expression in the macros
* below. It suppresses the Windows 'conditional expression is constant'
* warning without the use of pragmas (which cannot be used in macros).
*/
INLINE int __LogFalse() { return 0; }
#define LOGF(ARGS) \
do \
{ \
if (__Log_Put1(LOG_FATAL, __FILE__, __LINE__)) \
__Log_Put2 ARGS; \
} \
while (__LogFalse())
#define LOGE(ARGS) \
do \
{ \
if (__Log_Put1(LOG_ERROR, __FILE__, __LINE__)) \
__Log_Put2 ARGS; \
} \
while (__LogFalse())
#define LOGW(ARGS) \
do \
{ \
if (__Log_Put1(LOG_WARNING, __FILE__, __LINE__)) \
__Log_Put2 ARGS; \
} \
while (__LogFalse())
#define LOGI(ARGS) \
do \
{ \
if (__Log_Put1(LOG_INFO, __FILE__, __LINE__)) \
__Log_Put2 ARGS; \
} \
while (__LogFalse())
#define LOGD(ARGS) \
do \
{ \
if (__Log_Put1(LOG_DEBUG, __FILE__, __LINE__)) \
__Log_Put2 ARGS; \
} \
while (__LogFalse())
#define LOGF_CHAR(ARGS) \
do \
{ \
if (__Log_Put1(LOG_FATAL, __FILE__, __LINE__)) \
__Log_Put2_char ARGS; \
} \
while (__LogFalse())
#define LOGE_CHAR(ARGS) \
do \
{ \
if (__Log_Put1(LOG_ERROR, __FILE__, __LINE__)) \
__Log_Put2_char ARGS; \
} \
while (__LogFalse())
#define LOGW_CHAR(ARGS) \
do \
{ \
if (__Log_Put1(LOG_WARNING, __FILE__, __LINE__)) \
__Log_Put2_char ARGS; \
} \
while (__LogFalse())
#define LOGI_CHAR(ARGS) \
do \
{ \
if (__Log_Put1(LOG_INFO, __FILE__, __LINE__)) \
__Log_Put2_char ARGS; \
} \
while (__LogFalse())
#define LOGD_CHAR(ARGS) \
do \
{ \
if (__Log_Put1(LOG_DEBUG, __FILE__, __LINE__)) \
__Log_Put2_char ARGS; \
} \
while (__LogFalse())
END_EXTERNC
#endif /* _omi_log_h */