一个简单的用于嵌入式Linux开发的C调试日志打印接口
简介
这个C语言调试日志接口的目的是提供一种用于临时调试的手段, 要求使用方式类似于printf, 在不需要时可容易地去除相关的调试语句.
在必要的情况下可方便地扩展支持syslog接口.
这个接口仅提供了一个.h文件和一个.c文件, 只需向项目中加入这两个文件, 在使用时要包含头文件并在包含语句前作一个调试级别宏定义. 如果要去除相关的调试语句, 只需注释掉调试级别宏定义即可, 所有的调试语句将不会被生成.
注: dp是debug print的缩写.
-------------- 测试文件内容 --------------
/******************************************************************************
**
** FILENAME: main.c
**
** FILE DESCRIPTION:
**
** AUTHORS: Wang Shan
** CREATED:
**
** MODIFICATION HISTORY:
**
** DATE NAME DESCRIPTION
** --------------------------------------------------------------------------
**
**
**
*******************************************************************************/
/* If don't need debug print, comment this macro */
#define ENABLE_DPLOG_LEVEL (DPLOG_DEBUG)
#include "dplog.h"
/* interface definitiones */
int
main(int argc, char * argv[])
{
/* emergency log will causes program abort */
/* dpemerg("Test the emerge log./n"*/
dpalert("Test the alert log./n");
dpcrit("Test the crit log./n");
dperr("Test the error log./n");
dpng("Test the warning log./n");
/* if condition is false, this log will causes assertion failure */
/* dpassert(0, "Test the assert log./n"); */
dpinfo("Test the info log./n");
dpdbg("Test the debug log./n");
return 0;
}
-------------- .h文件内容 --------------
/******************************************************************************
**
** FILENAME: dplog.h
**
** FILE DESCRIPTION:
**
** AUTHORS: Wang Shan
** CREATED:
**
** MODIFICATION HISTORY:
**
** DATE NAME DESCRIPTION
** --------------------------------------------------------------------------
**
**
**
*******************************************************************************/
#ifndef DPLOG_H
#define DPLOG_H
#include
#include
/*
* levels of dplog are exactly the same as priorities of syslog
*/
#define DPLOG_EMERG (0) /* system is unusable */
#define DPLOG_ALERT (1) /* action must be taken immediately */
#define DPLOG_CRIT (2) /* critical conditions */
#define DPLOG_ERR (3) /* error conditions */
#define DPLOG_WARNING (4) /* warning conditions */
#define DPLOG_ASSERT (5) /* normal but significant condition */
#define DPLOG_INFO (6) /* informational */
#define DPLOG_DEBUG (7) /* debug-level messages */
#ifndef ENABLE_DPLOG_LEVEL
#define ENABLE_DPLOG_LEVEL (DPLOG_EMERG - 1)
#endif
#if ENABLE_DPLOG_LEVEL < DPLOG_ASSERT
#define NDEBUG
#else
#ifdef NDEBUG
#undef NDEBUG
#endif
#endif
#include
#define DPLOG_GET_LINE __LINE__
#define DPLOG_PATH_TOKEN '/'
#define DPLOG_GET_FILE /
((strrchr(__FILE__, DPLOG_PATH_TOKEN) != NULL) ? (strrchr(__FILE__, DPLOG_PATH_TOKEN) + 1) : __FILE__)
#define DPLOG_GET_FUNC __func__
#if ENABLE_DPLOG_LEVEL < DPLOG_EMERG
#define dpemerg(...)
#else
#define dpemerg(...) /
do { /
dplog_entry(DPLOG_EMERG, /
DPLOG_GET_FILE, /
DPLOG_GET_LINE, /
DPLOG_GET_FUNC, /
__VA_ARGS__); /
abort(); /
} while(0)
#endif
#if ENABLE_DPLOG_LEVEL < DPLOG_ALERT
#define dpalert(...)
#else
#define dpalert(...) /
do { /
dplog_entry(DPLOG_ALERT, /
DPLOG_GET_FILE, /
DPLOG_GET_LINE, /
DPLOG_GET_FUNC, /
__VA_ARGS__); /
} while(0)
#endif
#if ENABLE_DPLOG_LEVEL < DPLOG_CRIT
#define dpcrit(...)
#else
#define dpcrit(...) /
do { /
dplog_entry(DPLOG_CRIT, /
DPLOG_GET_FILE, /
DPLOG_GET_LINE, /
DPLOG_GET_FUNC, /
__VA_ARGS__); /
} while(0)
#endif
#if ENABLE_DPLOG_LEVEL < DPLOG_ERR
#define dperr(...)
#else
#define dperr(...) /
do { /
dplog_entry(DPLOG_ERR, /
DPLOG_GET_FILE, /
DPLOG_GET_LINE, /
DPLOG_GET_FUNC, /
__VA_ARGS__); /
} while(0)
#endif
#if ENABLE_DPLOG_LEVEL < DPLOG_WARNING
#define dpng(...)
#else
#define dpng(...) /
do { /
dplog_entry(DPLOG_WARNING, /
DPLOG_GET_FILE, /
DPLOG_GET_LINE, /
DPLOG_GET_FUNC, /
__VA_ARGS__); /
} while(0)
#endif
#if ENABLE_DPLOG_LEVEL < DPLOG_ASSERT
#define dpassert(cond, ...)
#else
#define dpassert(cond, ...) /
do { /
if (!(cond)) dplog_entry(DPLOG_ASSERT, /
DPLOG_GET_FILE, /
DPLOG_GET_LINE, /
DPLOG_GET_FUNC, /
__VA_ARGS__); /
assert(cond); /
} while(0)
#endif
#if ENABLE_DPLOG_LEVEL < DPLOG_INFO
#define dpinfo(...)
#else
#define dpinfo(...) /
do { /
dplog_entry(DPLOG_INFO, /
DPLOG_GET_FILE, /
DPLOG_GET_LINE, /
DPLOG_GET_FUNC, /
__VA_ARGS__); /
} while(0)
#endif
#if ENABLE_DPLOG_LEVEL < DPLOG_DEBUG
#define dpdbg(...)
#else
#define dpdbg(...) /
do { /
dplog_entry(DPLOG_DEBUG, /
DPLOG_GET_FILE, /
DPLOG_GET_LINE, /
DPLOG_GET_FUNC, /
__VA_ARGS__); /
} while(0)
#endif
void
dplog_entry(const int level,
const char * file,
const int line,
const char * func,
char * fmt, ...);
#endif /* *_H */
/* end of file */
-------------- .c文件内容 --------------
/******************************************************************************
**
** FILENAME: dplog.c
**
** FILE DESCRIPTION:
**
** AUTHORS: Wang Shan
** CREATED:
**
** MODIFICATION HISTORY:
**
** DATE NAME DESCRIPTION
** --------------------------------------------------------------------------
**
**
**
*******************************************************************************/
#include "dplog.h"
#include
#include
#include
#include
#include
#include
#include
/* static var declarations or definitiones */
static char * f_level_names[] =
{
"emerg",
"alert",
"crit",
"error",
"warning",
"assert",
"info",
"debug"
};
/* help function declarations */
static int
print_meta(const int level,
const char * file,
const int line,
const char * func);
static int
print_log(const char * fmt, va_list ap);
/* interface definitiones */
void
dplog_entry(const int level,
const char * file,
const int line,
const char * func,
char * fmt, ...)
{
va_list ap;
fflush(stdout);
/* print meta info of log */
print_meta(level, file, line, func);
/* print content of log */
va_start(ap, fmt);
if (NULL != fmt)
{
print_log(fmt, ap);
}
va_end(ap);
fflush(stdout);
}
/* help function definitiones */
static int
print_meta(const int level,
const char * file,
const int line,
const char * func)
{
int n = 0;
if (DPLOG_EMERG <= level && DPLOG_DEBUG >= level)
{
n += printf("%-8s ", f_level_names[level]);
}
else
{
n += printf("unknown ");
}
if (NULL != file)
{
n += printf("%s(%05d) ", file, line);
}
if (NULL != func)
{
n += printf("%s ", func);
}
n += printf("> ");
return n;
}
static int
print_log(const char * fmt, va_list ap)
{
if (NULL == fmt)
{
return 0;
}
/* print log to console */
return vprintf(fmt, ap);
}
/* end of file */