开发中打印一些程序 log 是一个很很很常用的需求了,怎么样打印这些 log 其实也很重要,除了必须的一些信息外,通常打印出这条 log 信息所在的 文件名、方法、行号 这类通用信息,也可以更好的帮助我们定位问题。并且,C 语言的 printf 为例,它并不是自己换行,每行 log 还需要我们手动添加一个 \n ,这个也是比较麻烦的,还容易漏掉。
所以,我们可以定制一个这样的 log 输出工具,输出一些通用信息(例如文件名、方法名、行号等),同时还可以添加一个统一的 log 开关,达成一次性关掉所有 log 的功能。
这里以 C 语言为例,写了一个 LogUtils.h 文件,其它 C++、Android NDK 等类似语言,都可以在此基础上稍加修改即可。
LogUtils.h:
#ifndef _LOG_UTILS_H_
#define _LOG_UTILS_H_
#include <stdio.h>
#include <string.h>
#define DEBUG // log开关
#define __FILENAME__ (strrchr(__FILE__, '/') + 1) // 文件名
#ifdef DEBUG
#define LOGD(format, ...) printf("[%s][%s][%d]: " format "\n", __FILENAME__, __FUNCTION__,\
__LINE__, ##__VA_ARGS__)
#else
#define LOGD(format, ...)
#endif
#endif // _LOG_UTILS_H_
编写一个小程序测试一下:
#include <stdio.h>
#include "LogUtils.h"
int main() {
LOGD("hello world");
LOGD("%d", 10);
LOGD("%s : %d", "num", 20);
LOGD();
return 0;
}
执行结果:
[main.cpp][main][5]: hello world
[main.cpp][main][6]: 10
[main.cpp][main][7]: num : 20
[main.cpp][main][8]:
可以看到,输出的 log 已经是按照我们预设的那样,打印出了 文件名、方法、行号 这类通用信息,且实现的每行 log 自动换行。
注意:
如果需要关掉所有的 log,只需要注释掉 #define DEBUG 即可。也可以通过直接在 gcc 命令中添加 -DDEBUG 定义这个宏。
上面的代码中用到了一些系统提供的宏定义,这里简单的介绍一下它们的含义:
值得注意的是,宏定义都是在预编译时期就会替换到相应代码中去的。