1. Overview
ALOGV 的配置信息和使用方法如下:
#ifdef LOG_NDEBUG
#undef LOG_NDEBUG
#endif
#define LOG_NDEBUG 0
#define LOG_TAG "TAG_NAME"
#include "utils/Log.h"
static void method(int param) {
ALOGV("%s: param is: %d", __func__, param);
}
ALOGD、ALOGI、ALOGW、ALOGE 默认开启,无需单独配置。
2. Detail
2.1 ALOGV 使用
packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp
#define LOG_NDEBUG 0
#define LOG_TAG "BluetoothServiceJni"
.......
#include "utils/Log.h"
......
static void adapter_state_change_callback(bt_state_t status) {
......
ALOGV("%s: Status is: %d", __func__, status);
......
}
2.2 ALOGV 原理
2.2.1 #include "utils/Log.h"
system/core/libutils/include/utils/Log.h
// DO NOT INCLUDE ANYTHING NEW IN THIS FILE.
// <log/log.h> has replaced this file and all changes should go there instead.
// This path remains strictly to include that header as there are thousands of
// references to <utils/Log.h> in the tree.
#include <log/log.h>
2.2.2 #include <log/log.h>
system/logging/liblog/include/log/log.h
#pragma once
/* Too many in the ecosystem assume these are included */
#if !defined(_WIN32)
#include <pthread.h>
#endif
#include <stdint.h> /* uint16_t, int32_t */
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <android/log.h>
#include <log/log_id.h>
#include <log/log_main.h>
#include <log/log_radio.h>
#include <log/log_safetynet.h>
#include <log/log_system.h>
#include <log/log_time.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* LOG_TAG is the local tag used for the following simplified
* logging macros. You can change this preprocessor definition
* before using the other macros to change the tag.
*/
#ifndef LOG_TAG
#define LOG_TAG NULL
#endif
/*
* Normally we strip the effects of ALOGV (VERBOSE messages),
* LOG_FATAL and LOG_FATAL_IF (FATAL assert messages) from the
* release builds be defining NDEBUG. You can modify this (for
* example with "#define LOG_NDEBUG 0" at the top of your source
* file) to change that behavior.
*/
#ifndef LOG_NDEBUG
#ifdef NDEBUG
#define LOG_NDEBUG 1
#else
#define LOG_NDEBUG 0
#endif
#endif
- LOG_TAG
从源码注释可知,若未定义 LOG_TAG 宏,那么打印的 log 没有 tag 信息;
若在引用头文件之前定义 LOG_TAG 宏,则使用该宏作为 tag,如 2.1 ALOGV 使用 - LOG_DEBUG
从源码注释可知,若想开启 ALOGV,则需要在源文件顶部定义 #define LOG_NDEBUG 0,如 2.1 ALOGV 使用
2.2.3 #include <log/log_main.h>
system/logging/liblog/include/log/log_main.h
#pragma once
#include <stdbool.h>
#include <sys/cdefs.h>
#include <sys/types.h>
#include <android/log.h>
......
#ifndef ALOGV
#define __ALOGV(...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) // 2
#if LOG_NDEBUG
#define ALOGV(...) \
do { \
__FAKE_USE_VA_ARGS(__VA_ARGS__); \
if (false) { \
__ALOGV(__VA_ARGS__); \
} \
} while (false)
#else
#define ALOGV(...) __ALOGV(__VA_ARGS__) // 1
#endif
#endif
// ALOGD 不受此控制,默认开启
#ifndef ALOGD
#define ALOGD(...) ((void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__))
#endif
由以上源码可知:若 LOG_NDEBUG 宏为0,则对应的是 // 1、// 2,相当于开启 ALOGV();否则 ALOGV() 对应的是 do-while(false) 循环体,其内部是 if(false) 语句,相当于无实现。
继续分析 ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
#ifndef ALOG
#define ALOG(priority, tag, ...) LOG_PRI(ANDROID_##priority, tag, __VA_ARGS__)
#endif
- ANDROID_##priority 表示拼接,根据之前传递的参数 LOG_VERBOSE,那么,此时相当于 LOG_PRI(ANDROID_LOG_VERBOSE, tag, __VA_ARGS__),继续分析该函数
#ifndef LOG_PRI
#define LOG_PRI(priority, tag, ...) android_printLog(priority, tag, __VA_ARGS__)
#endif
#define android_printLog(prio, tag, ...) \
__android_log_print(prio, tag, __VA_ARGS__)
2.2.4 #include <android/log.h>
system/logging/liblog/include/android/log.h
int __android_log_print(int prio, const char* tag, const char* fmt, ...)
__attribute__((__format__(printf, 3, 4)));
Log 优先级定义如下:
/**
* Android log priority values, in increasing order of priority.
*/
typedef enum android_LogPriority {
/** For internal use only. */
ANDROID_LOG_UNKNOWN = 0,
/** The default priority, for internal use only. */
ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */
/** Verbose logging. Should typically be disabled for a release apk. */
ANDROID_LOG_VERBOSE,
/** Debug logging. Should typically be disabled for a release apk. */
ANDROID_LOG_DEBUG,
/** Informational logging. Should typically be disabled for a release apk. */
ANDROID_LOG_INFO,
/** Warning logging. For use with recoverable failures. */
ANDROID_LOG_WARN,
/** Error logging. For use with unrecoverable failures. */
ANDROID_LOG_ERROR,
/** Fatal logging. For use when aborting. */
ANDROID_LOG_FATAL,
/** For internal use only. */
ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */
} android_LogPriority;
system/logging/liblog/logger_write.cpp
int __android_log_print(int prio, const char* tag, const char* fmt, ...) {
ErrnoRestorer errno_restorer;
if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
return -EPERM;
}
va_list ap;
__attribute__((uninitialized)) char buf[LOG_BUF_SIZE];
va_start(ap, fmt);
vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
va_end(ap);
__android_log_message log_message = {
sizeof(__android_log_message), LOG_ID_MAIN, prio, tag, nullptr, 0, buf};
__android_log_write_log_message(&log_message);
return 1;
}
网友评论