该版本的打印调试LOG, 主要是修改了以前的各个版本对于调试信息没有分门别类的缺陷。当打印出来的调试日志信息很多的情况下, 就很难区分出我们需要的日志信息了, 所以在该版本的调试日志中包含了几个基本的调试信息的等级。这样就可以将我们需要的、关系的调试日志信息显示到我们希望的地方了, 这样在程序出现异常的时候也更利于我们及时得知出错的地方。
首先将调试日志的打印等级分为以下几个级别, 使用相应的枚举来定义, 如下所示:
enum {
SL_LOG_DEBUG = 0,
SL_LOG_MSG = 1,
SL_LOG_WARN = 2,
SL_LOG_ERR = 3
};
打印的日志等级分为基本的调试信息、基本的显示信息、警告信息以及出错信息等。
下面先给出该调试日志的头文件:
/*
* Copyright (c) 2011,
* ASMlove. All rights reserved.
*
* http://blog.youkuaiyun.com/zfxfcx/
*
* Use, modification and distribution are subject to the
* "GNU GPL" at listed at <http://www.gnu.org/licenses/>.
*/
#ifndef __SL_LOG_HEADER_H__
#define __SL_LOG_HEADER_H__
#ifndef _SL_LOG_
#define _SL_LOG_
#ifdef __cplusplus
extern {
#endif /* __cplusplus */
enum {
SL_LOG_DEBUG = 0,
SL_LOG_MSG = 1,
SL_LOG_WARN = 2,
SL_LOG_ERR = 3
};
extern void sl_log_err(int v, const char* fmt, ...);
extern void sl_log_warn(const char* fmt, ...);
extern void sl_log_errx(int v, const char* fmt, ...);
extern void sl_log_warnx(const char* fmt, ...);
extern void sl_log_msgx(const char* fmt, ...);
extern void sl_log_debugx(const char* fmt, ...);
#if _WIN32 || _WIN64
#if _DEBUG
#define sl_debug sl_log_debugx
#else
#define sl_debug
#endif
#else
#ifndef NDEBUG
#define sl_debug sl_log_debugx
#else
#define sl_debug
#endif
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _SL_LOG_ */
#endif /* __SL_LOG_HEADER_H__ */
那么具体的接口实现如下所示:
/*
* Copyright (c) 2011,
* ASMlove. All rights reserved.
*
* http://blog.youkuaiyun.com/zfxfcx/
*
* Use, modification and distribution are subject to the
* "GNU GPL" at listed at <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <time.h>
#include <sys/timeb.h>
#if _WIN32 || _WIN64
#include <io.h>
#include <direct.h>
#else
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#endif
#include "sl_log.h"
#if _WIN32 || _WIN64
#define inline __inline
#pragma warning(disable:4996)
#endif
struct __log_time {
unsigned char hour_;
unsigned char min_;
unsigned char sec_;
unsigned short millitm_;
};
static inline void
__get_log_time(struct __log_time* lt)
{
struct timeb tb = {0};
struct tm* local = NULL;
if (NULL != lt) {
ftime(&tb);
local = localtime(&tb.time);
lt->hour_ = local->tm_hour;
lt->min_ = local->tm_min;
lt->sec_ = local->tm_sec;
lt->millitm_ = tb.millitm;
}
}
static int
__log_access(const char* path, int mode)
{
return access(path, mode);
}
static int
__log_mkdir(const char* path)
{
#if _WIN32 || _WIN64
return mkdir(path);
#else
return mkdir(path, S_IRWXU);
#endif
}
static int
__log_snprintf(char* dest, size_t count, const char* fmt, ...)
{
int ret = 0;
va_list ap;
va_start(ap, fmt);
ret = vsnprintf(dest, count, fmt, ap);
va_end(ap);
return ret;
}
static void
__sl_log(int severity, const char* msg)
{
const char* severity_str;
FILE* pFile = NULL;
char fname[100] = {0};
struct __log_time lt = {0};
switch (severity) {
case SL_LOG_DEBUG:
severity_str = "debug";
break;
case SL_LOG_MSG:
severity_str = "msg";
break;
case SL_LOG_WARN:
severity_str = "warn";
break;
case SL_LOG_ERR:
severity_str = "err";
break;
default:
severity_str = "???";
}
__log_snprintf(fname, sizeof(fname), "./sl_log/%s.log", severity_str);
if (0 != __log_access("./sl_log", 0))
__log_mkdir("./sl_log");
pFile = fopen(fname, "a+");
if (NULL != pFile) {
__get_log_time(<);
fprintf(pFile, "[%.2d:%.2d:%.2d:%.3d] - %s/n",
lt.hour_, lt.min_, lt.sec_, lt.millitm_, msg);
fclose(pFile);
}
}
static void
__log_helper(int severity, int log_errno, const char* fmt, va_list ap)
{
char buf[1024] = {0};
size_t len = 0;
if (NULL != fmt)
vsnprintf(buf, sizeof(buf), fmt, ap);
if (log_errno >= 0) {
len = strlen(buf);
if (len < sizeof(buf) - 3) {
__log_snprintf(buf + len,
sizeof(buf) - len, ": %s", strerror(log_errno));
}
}
__sl_log(severity, buf);
}
void
sl_log_err(int v, const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
__log_helper(SL_LOG_ERR, errno, fmt, ap);
va_end(ap);
exit(v);
}
void
sl_log_warn(const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
__log_helper(SL_LOG_WARN, errno, fmt, ap);
va_end(ap);
}
void
sl_log_errx(int v, const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
__log_helper(SL_LOG_ERR, -1, fmt, ap);
va_end(ap);
exit(v);
}
void
sl_log_warnx(const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
__log_helper(SL_LOG_WARN, -1, fmt, ap);
va_end(ap);
}
void
sl_log_msgx(const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
__log_helper(SL_LOG_MSG, -1, fmt, ap);
va_end(ap);
}
void
sl_log_debugx(const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
__log_helper(SL_LOG_DEBUG, -1, fmt, ap);
va_end(ap);
}