HAL层日志的调用接口定义
#define HAL_LOGE(format, args...) LOG(LOG_PRI_E, LOG_HAL, LOG_ALL, format, ##args)
#define HAL_LOGW(format, args...) LOG(LOG_PRI_W, LOG_HAL, LOG_ALL, format, ##args)
#define HAL_LOGI(format, args...) LOG(LOG_PRI_I, LOG_HAL, LOG_ALL, format, ##args)
#define HAL_LOGD(format, args...) LOG(LOG_PRI_D, LOG_HAL, LOG_ALL, format, ##args)
#define HAL_LOGV(format, args...) LOG(LOG_PRI_V, LOG_HAL, LOG_ALL, format, ##args)
参数
LOG(LOG_PRI_V, LOG_HAL, LOG_ALL, format, ##args)
优先级定义
const int LOG_PRI_E = '1';
const int LOG_PRI_W = '2';
const int LOG_PRI_I = '3';
const int LOG_PRI_D = '4';
const int LOG_PRI_V = '5';
模块
typedef enum{
LOG_HAL = 0,
LOG_OEM,
LOG_ISP_MW,
LOG_SENSOR,
LOG_ISPALG,
LOG_ARITH,
LOG_MODULE_MAX,
}LOG_MODULE_E;
typedef enum{
LOG_ALL = 0,
LOG_AE,
LOG_AF,
LOG_AWBC,
LOG_FUNC_MAX
}LOG_FUNC_E;
#ifndef LOG
#define LOG(prio, module, func,format,...) \
((void)PRI_LOG(prio, module, func,LOG_TAG, \
"%d, %s: " format,__LINE__, __FUNCTION__,##__VA_ARGS__))
#endif
LOG_TAG
在调用打印log的文件定义。不同文件会有不同的标签定义,用于查看和筛选日志用。
#ifndef PRI_LOG
#define PRI_LOG(prio, module, func,tag, format...) \
__print_log(prio,module,func,tag,format)
#endif
最终会调用到__print_log()
函数
int __print_log(int pri, int module, int func,
const char* tag, const char* format, ...){
int prio=0;
if((g_log_level[module] > LOG_PRI_V) ||
(g_log_level[module] < LOG_PRI_E)) {
g_log_level[module] = LOG_PRI_D;
}
if((int)g_log_module_setting[module] == LOG_STATUS_EN) {
if((int)g_log_func_setting[func] == LOG_STATUS_EN) {
//update g_log_level according to module priority
if((int)g_log_level[module] >= pri){
va_list ap;
char buf[1024];
va_start(ap, format);
vsnprintf(buf, 1024, format, ap);
va_end(ap);
switch(pri) {
case LOG_PRI_E: prio=ANDROID_LOG_ERROR; break;
case LOG_PRI_W: prio=ANDROID_LOG_WARN; break;
case LOG_PRI_I: prio=ANDROID_LOG_INFO; break;
case LOG_PRI_D: prio=ANDROID_LOG_DEBUG; break;
case LOG_PRI_V: prio=ANDROID_LOG_VERBOSE; break;
default:prio=ANDROID_LOG_DEBUG;
}
return __android_log_write(prio, tag, buf);
}
}
}
return 0;
}
g_log_level是一个数组(全局变量)。
这个函数会将参数与数组的一个成员变量比较,判断是否需要打印。与数组的哪个成员变量比较就看调用LOG()
传递的是哪个LOG_MODULE_E
如何修改日志打印等级
静态修改
修改数组成员变量
数组下标是LOG_MODULE_E
char g_log_level[LOG_MODULE_MAX] = {'4', '4', '4', '4', '4', '4'};
动态修改
在创建SprdCamera3OEMIf
对象时会调用log_monitor_thread_init()
void *SprdCamera3OEMIf::log_monitor_thread_proc(void *p_data) {
char prop[PROPERTY_VALUE_MAX];
char version[PROPERTY_VALUE_MAX];
char loglevel_stat[LOG_MODULE_MAX+1];
int num = 0;
struct timespec ts;
SprdCamera3OEMIf *obj = (SprdCamera3OEMIf *)p_data;
s_mLogState = 1;
HAL_LOGI("E, %d",s_mLogMonitor.load());
while(s_mLogMonitor.load() > 1) {
/*
*prop[0]:hal,HAL_LOGX/F_HAL_LOGX
*prop[1]:oem,CMR_LOGX/F_CMR_LOGX
*prop[2]:MW&PM,ISP_LOGX/F_ISP_LOGX
*prop[3]:sensor,SENSOR_LOGX/F_SENSOR_LOGX
*prop[4]:3A ctrl&alg, undefined
*prop[5]:arithmetic,ARITH_LOGX/F_ARITH_LOGX
*/
property_get("persist.vendor.cam.mlog.on_off", prop, "000000");
for (num = 0 ;num < LOG_MODULE_MAX; num++) {
if ((prop[num] != g_log_module_setting[num]) &&
((prop[num] == LOG_STATUS_EN) || (prop[num] == LOG_STATUS_DIS))) {
g_log_module_setting[num] = prop[num];
}
}
/*
*prop[0]:ALL
*prop[1]:AE
*prop[2]:AF
*prop[3]:AWBC
*/
property_get("persist.vendor.cam.flog.on_off", prop, "0000");
for (num = 0; num < LOG_FUNC_MAX; num++) {
if ((prop[num] != g_log_func_setting[num]) &&
((prop[num] == LOG_STATUS_EN) || (prop[num] == LOG_STATUS_DIS))) {
g_log_func_setting[num] = prop[num];
}
}
/*
*prop[0]:hal,HAL_LOGX/F_HAL_LOGX,
*prop[1]:oem,CMR_LOGX/F_CMR_LOGX
*prop[2]:MW&PM,ISP_LOGX/F_ISP_LOGX
*prop[3]:sensor,SENSOR_LOGX/F_SENSOR_LOGX
*prop[4]:3A ctrl&alg,undefined
*prop[5]:arithmetic,ARITH_LOGX/F_ARITH_LOGX
*/
property_get("ro.debuggable", version, "1");
strcmp(version, "0") ? strncpy(loglevel_stat, "444444", LOG_MODULE_MAX+1)
: strncpy(loglevel_stat, "333333", LOG_MODULE_MAX+1);
property_get("persist.vendor.cam.mlog.loglevel", prop, loglevel_stat);
for (num = 0; num < LOG_MODULE_MAX; num++) {
if ((prop[num] != g_log_level[num]) &&
(prop[num] >= LOG_PRI_E) && (prop[num] <= LOG_PRI_V)) {
g_log_level[num] = prop[num];
}
}
obj->log_monitor_test();
if (clock_gettime(CLOCK_REALTIME, &ts))
continue;
ts.tv_nsec += ms2ns(1000);
if (ts.tv_nsec > 1000000000) {
ts.tv_sec += 1;
ts.tv_nsec -= 1000000000;
}
sem_timedwait(&s_mLogMonitorSem, &ts);
}
s_mLogState = 0;
HAL_LOGV("X");
return NULL;
}
通过属性配置
property_get("persist.vendor.cam.mlog.loglevel", prop, loglevel_stat);
for (num = 0; num < LOG_MODULE_MAX; num++) {
if ((prop[num] != g_log_level[num]) &&
(prop[num] >= LOG_PRI_E) && (prop[num] <= LOG_PRI_V)) {
g_log_level[num] = prop[num];
}
}
例如所有日志等级配置为V
setprop persist.vendor.cam.mlog.loglevel 555555