总用printf来打日志的话,到后面删除起来太麻烦,所以自己写了几个函数来代替printf。其实也就是把printf包装了一下,然后利用宏根据编译选项是否含有-DDEBUG来判断是否把宏展开为功能代码。代码如下:
//log.h
#ifndef LOG_H_INCLUDED
#define LOG_H_INCLUDED
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#ifdef DEBUG
#define INFO(...) info(__VA_ARGS__)
#define WARN(...) warn(__VA_ARGS__)
#define ERROR(...) error(__VA_ARGS__)
#else
#define INFO(...) {}
#define WARN(...) {}
#define ERROR(...) {}
#endif
extern const char *_log_blue;
extern const char *_log_yellow;
extern const char *_log_red;
extern const char *_log_clear;
extern void info(const char *fmt, ...);
extern void warn(const char *fmt, ...);
extern void error(const char *fmt, ...);
#endif // LOG_H_INCLUDED
//log.c
#include "log.h"
const char *_log_blue = "\033[34m"; //color for info
const char *_log_yellow = "\033[33m"; //color for warn
const char *_log_red = "\033[31m"; //color for error
const char *_log_clear = "\033[0m"; //color for normal
void info(const char *fmt, ...)
{
char fullfmt[strlen(fmt) + 30];
strcpy(fullfmt, _log_blue);
strcat(fullfmt, "[INFO] ");
strcat(fullfmt, fmt);
strcat(fullfmt, _log_clear);
strcat(fullfmt, "\n");
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fullfmt, ap);
va_end(ap);
}
void warn(const char *fmt, ...)
{
char fullfmt[strlen(fmt) + 30];
strcpy(fullfmt, _log_yellow);
strcat(fullfmt, "[WARN] ");
strcat(fullfmt, fmt);
strcat(fullfmt, _log_clear);
strcat(fullfmt, "\n");
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fullfmt, ap);
va_end(ap);
}
void error(const char *fmt, ...)
{
char fullfmt[strlen(fmt) + 30];
strcpy(fullfmt, _log_red);
strcat(fullfmt, "[ERROR] ");
strcat(fullfmt, fmt);
strcat(fullfmt, _log_clear);
strcat(fullfmt, "\n");
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fullfmt, ap);
va_end(ap);
}
如果编译选项有-DDEBUG,则INFO会展开为info(),否则展开为空大括号,这些日志函数的用法和一般的printf没什么区别,唯一的区别也就是加了颜色和前缀。
虽然写了三个不同级别的日志函数,但是目前并没有实现对日志级别的过滤,也没有实现输出到文件,如果需要的话再加了。