/*************************************************************************************/
event tag的意义:
/*************************************************************************************/
# The entries in this file map a sparse set of log tag numbers to tag names.
# This is installed on the device, in /system/etc, and parsed by logcat.
#
# Tag numbers are decimal integers, from 0 to 2^31. (Let's leave the
# negative values alone for now.)
#
# Tag names are one or more ASCII letters and numbers or underscores, i.e.
# "[A-Z][a-z][0-9]_". Do not include spaces or punctuation (the former
# impacts log readability, the latter makes regex searches more annoying).
#
# Tag numbers and names are separated by whitespace. Blank lines and lines
# starting with '#' are ignored.
#
# Optionally, after the tag names can be put a description for the value(s)
# of the tag. Description are in the format
# (<name>|data type[|data unit])
# Multiple values are separated by commas.
#
# The data type is a number from the following values:
# 1: int
# 2: long
# 3: string
# 4: list
# 5: float
#
# The data unit is a number taken from the following list:
# 1: Number of objects
# 2: Number of bytes
# 3: Number of milliseconds
# 4: Number of allocations
# 5: Id
# 6: Percent
# Default value for data of type int/long is 2 (bytes).
#
# TODO: generate ".java" and ".h" files with integer constants from this file.
/*************************************************************************************/
java层打印event log的例子
/*************************************************************************************/
xxx/frameworks/base/core/java/com/xxx/yyyyy/Event/EventLogTags.java
/** 30014 am_proc_start (User|1|5),(PID|1|5),(UID|1|5),(Process Name|3),(Type|3),(Component|3) */
public static final int AM_PROC_START = 30014;
# Application process has been started
30014 am_proc_start (User|1|5),(PID|1|5),(UID|1|5),(Process Name|3),(Type|3),(Component|3)
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
EventLog.writeEvent(EventLogTags.AM_PROC_START,
UserHandle.getUserId(uid), startResult.pid, uid,
app.processName, hostingType,
hostingNameStr != null ? hostingNameStr : "");
/*************************************************************************************/
java层调用EventLog.writeEvent的实现是通过native提供的接口
/*************************************************************************************/
frameworks/base/core/java/android/util/EventLog.java
/**
* Record an event log message.
* @param tag The event type tag code
* @param value A value to log
* @return The number of bytes written
*/
public static native int writeEvent(int tag, int value);
/**
* Record an event log message.
* @param tag The event type tag code
* @param list A list of values to log
* @return The number of bytes written
*/
public static native int writeEvent(int tag, Object... list);
/*************************************************************************************/
frameworks/base/core/jni/android_util_EventLog.cpp
static JNINativeMethod gRegisterMethods[] = {
/* name, signature, funcPtr */
{ "writeEvent", "(II)I", (void*) android_util_EventLog_writeEvent_Integer },
{ "writeEvent", "(IJ)I", (void*) android_util_EventLog_writeEvent_Long },
{ "writeEvent", "(IF)I", (void*) android_util_EventLog_writeEvent_Float },
{ "writeEvent", "(ILjava/lang/String;)I", (void*) android_util_EventLog_writeEvent_String},
{ "writeEvent", "(I[Ljava/lang/Object;)I",(void*) android_util_EventLog_writeEvent_Array},
{ "readEvents", "([ILjava/util/Collection;)V", (void*) android_util_EventLog_readEvents},
};
static jint android_util_EventLog_writeEvent_Array(JNIEnv* env, jobject clazz,
jint tag, jobjectArray value) {
uint8_t buf[MAX_EVENT_PAYLOAD];
const size_t max = sizeof(buf) - 1; // leave room for final newline
size_t pos = 2; // Save room for type tag & array count
jsize copied = 0, num = env->GetArrayLength(value);
for (; copied < num && copied < 255; ++copied) {
jobject item = env->GetObjectArrayElement(value, copied);
if (item == NULL || env->IsInstanceOf(item, gStringClass)) {
buf[pos++] = EVENT_TYPE_STRING;
memcpy(&buf[pos], &len, sizeof(len));
memcpy(&buf[pos + sizeof(len)], str, len);
pos += sizeof(len) + len;
} else if (env->IsInstanceOf(item, gIntegerClass)) {
jint intVal = env->GetIntField(item, gIntegerValueID);
if (pos + 1 + sizeof(intVal) > max) break;
buf[pos++] = EVENT_TYPE_INT;
memcpy(&buf[pos], &intVal, sizeof(intVal));
pos += sizeof(intVal);
} else if (env->IsInstanceOf(item, gLongClass)) {
jlong longVal = env->GetLongField(item, gLongValueID);
if (pos + 1 + sizeof(longVal) > max) break;
buf[pos++] = EVENT_TYPE_LONG;
memcpy(&buf[pos], &longVal, sizeof(longVal));
pos += sizeof(longVal);
} else if (env->IsInstanceOf(item, gFloatClass)) {
jfloat floatVal = env->GetFloatField(item, gFloatValueID);
if (pos + 1 + sizeof(floatVal) > max) break;
buf[pos++] = EVENT_TYPE_FLOAT;
memcpy(&buf[pos], &floatVal, sizeof(floatVal));
pos += sizeof(floatVal);
}
}
buf[0] = EVENT_TYPE_LIST;
buf[1] = copied;
buf[pos++] = '\n';
return android_bWriteLog(tag, buf, pos);
}
/*************************************************************************************/
system/core/include/log/log.h
#define android_bWriteLog(tag, payload, len) \
__android_log_bwrite(tag, payload, len)
system/core/liblog/logd_write.c
int __android_log_bwrite(int32_t tag, const void *payload, size_t len)
{
struct iovec vec[2];
vec[0].iov_base = &tag;
vec[0].iov_len = sizeof(tag);
vec[1].iov_base = (void*)payload;
vec[1].iov_len = len;
return write_to_log(LOG_ID_EVENTS, vec, 2);
}
system/core/include/log/uio.h
struct iovec {
void* iov_base;
size_t iov_len;
};
/*************************************************************************************/
system/core/liblog/logd_write.c
int __android_log_bwrite(int32_t tag, const void *payload, size_t len)
{
struct iovec vec[2];
vec[0].iov_base = &tag;
vec[0].iov_len = sizeof(tag);
vec[1].iov_base = (void*)payload;
vec[1].iov_len = len;
return write_to_log(LOG_ID_EVENTS, vec, 2);
}
write_to_log是个函数指针
static int __write_to_log_init(log_id_t, struct iovec *vec, size_t nr);
static int (*write_to_log)(log_id_t, struct iovec *vec, size_t nr) = __write_to_log_init;
pstore的实现方式和log_id没有关系和log的类型没有关系
typedef enum log_id {
LOG_ID_MIN = 0,
LOG_ID_MAIN = 0,
LOG_ID_RADIO = 1,
LOG_ID_EVENTS = 2,
LOG_ID_SYSTEM = 3,
LOG_ID_CRASH = 4,
LOG_ID_KERNEL = 5,
LOG_ID_MAX
} log_id_t;
/*************************************************************************************/
system/core/logcat/logcat.cpp
这里的struct 应该就是传说中的,struct 作为 class 使用,唯一的差别是 struct 默认是public
struct log_device_t {
const char* device;
bool binary;
struct logger *logger;
struct logger_list *logger_list;
bool printed;
log_device_t* next;
log_device_t(const char* d, bool b) {
device = d;
binary = b;
next = NULL;
printed = false;
logger = NULL;
logger_list = NULL;
}
};
/*************************************************************************************/
system/core/include/log/event_tag_map.h
#define EVENT_TAG_MAP_FILE "/system/etc/event-log-tags"
当 -b 的参数是events时:创建的 log_device_t的成员变量binary为1
bool binary = strcmp(name, "events") == 0;
log_device_t* d = new log_device_t(name, binary);
/*
* Single entry.
*/
typedef struct EventTag {
unsigned int tagIndex;
const char* tagStr;
} EventTag;
/*
* Map.
*/
struct EventTagMap {
/* memory-mapped source file; we get strings from here */
void* mapAddr;
size_t mapLen;
/* array of event tags, sorted numerically by tag index */
EventTag* tagArray;
int numTags;
};
system/core/liblog/event_tag_map.c
static void processBuffer(log_device_t* dev, struct log_msg *buf)
{
int bytesWritten = 0;
int err;
AndroidLogEntry entry;
char binaryMsgBuf[1024];
if (dev->binary) {
static bool hasOpenedEventTagMap = false;
static EventTagMap *eventTagMap = NULL;
if (!eventTagMap && !hasOpenedEventTagMap) {
eventTagMap = android_openEventTagMap(EVENT_TAG_MAP_FILE);
hasOpenedEventTagMap = true;
}
err = android_log_processBinaryLogBuffer(&buf->entry_v1, &entry,
eventTagMap,
binaryMsgBuf,
sizeof(binaryMsgBuf));
//printf(">>> pri=%d len=%d msg='%s'\n",
// entry.priority, entry.messageLen, entry.message);
} else {
err = android_log_processLogBuffer(&buf->entry_v1, &entry);
}
}
/*************************************************************************************/
怎样添加event log
/*************************************************************************************/
1. java层怎样添加 EventLog?
frameworks/base/services/core/java/com/android/server/am/EventLogTags.logtags
/** 30014 am_proc_start (User|1|5),(PID|1|5),(UID|1|5),(Process Name|3),(Type|3),(Component|3) */
public static final int AM_PROC_START = 30014;
# Application process has been started
30014 am_proc_start (User|1|5),(PID|1|5),(UID|1|5),(Process Name|3),(Type|3),(Component|3)
怎样使用?EventLog是个class
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
EventLog.writeEvent(EventLogTags.AM_PROC_START,
UserHandle.getUserId(uid), startResult.pid, uid,
app.processName, hostingType,
hostingNameStr != null ? hostingNameStr : "");
2. C文件中怎样添加 event log:
添加文件:
frameworks/native/services/surfaceflinger/EventLog/EventLogTags.logtags
# 60100 - 60199 reserved for surfaceflinger
60100 sf_frame_dur (window|3),(dur0|1),(dur1|1),(dur2|1),(dur3|1),(dur4|1),(dur5|1),(dur6|1)
在android.mk中添加:
EventLog/EventLogTags.logtags \
logcat -b events的输出结果:
08-08 18:36:20.938 1276 1289 I am_pss : [6423,9801,com.android.thememanager,8239104,6909952]
对应的tag:后面的描述的意思是:Pid:6423[5表示ID], UID:9801, 进程名字:com.android.thememanager, PssKb:8239104字节,UssKb:6909952字节
30047 am_pss (Pid|1|5),(UID|1|5),(Process Name|3),(PssKb|2|2),(UssKb|2|2)
/*************************************************************************************/
通过pstore,得到 各种类型的log
/*************************************************************************************/
pstore保存的log类型
console, logcat?
-L -v threadtime -b system
-L -v threadtime -b all -d *:v [-d *:v是什么意思?]
/*************************************************************************************/
frameworks/base/core/java/com/android/internal/logging/EventLogTags.logtags
# interaction logs
524287 sysui_view_visibility (category|1|5),(visible|1|6)
524288 sysui_action (category|1|5),(pkg|3)
524290 sysui_count (name|3),(increment|1)
524291 sysui_histogram (name|3),(bucket|1)
frameworks/base/services/core/java/com/android/server/GestureLauncherService.java:277:
MetricsLogger.histogram(mContext, "power_double_tap_interval", (int) doubleTapInterval);
event tag的意义:
/*************************************************************************************/
# The entries in this file map a sparse set of log tag numbers to tag names.
# This is installed on the device, in /system/etc, and parsed by logcat.
#
# Tag numbers are decimal integers, from 0 to 2^31. (Let's leave the
# negative values alone for now.)
#
# Tag names are one or more ASCII letters and numbers or underscores, i.e.
# "[A-Z][a-z][0-9]_". Do not include spaces or punctuation (the former
# impacts log readability, the latter makes regex searches more annoying).
#
# Tag numbers and names are separated by whitespace. Blank lines and lines
# starting with '#' are ignored.
#
# Optionally, after the tag names can be put a description for the value(s)
# of the tag. Description are in the format
# (<name>|data type[|data unit])
# Multiple values are separated by commas.
#
# The data type is a number from the following values:
# 1: int
# 2: long
# 3: string
# 4: list
# 5: float
#
# The data unit is a number taken from the following list:
# 1: Number of objects
# 2: Number of bytes
# 3: Number of milliseconds
# 4: Number of allocations
# 5: Id
# 6: Percent
# Default value for data of type int/long is 2 (bytes).
#
# TODO: generate ".java" and ".h" files with integer constants from this file.
/*************************************************************************************/
java层打印event log的例子
/*************************************************************************************/
xxx/frameworks/base/core/java/com/xxx/yyyyy/Event/EventLogTags.java
/** 30014 am_proc_start (User|1|5),(PID|1|5),(UID|1|5),(Process Name|3),(Type|3),(Component|3) */
public static final int AM_PROC_START = 30014;
# Application process has been started
30014 am_proc_start (User|1|5),(PID|1|5),(UID|1|5),(Process Name|3),(Type|3),(Component|3)
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
EventLog.writeEvent(EventLogTags.AM_PROC_START,
UserHandle.getUserId(uid), startResult.pid, uid,
app.processName, hostingType,
hostingNameStr != null ? hostingNameStr : "");
/*************************************************************************************/
java层调用EventLog.writeEvent的实现是通过native提供的接口
/*************************************************************************************/
frameworks/base/core/java/android/util/EventLog.java
/**
* Record an event log message.
* @param tag The event type tag code
* @param value A value to log
* @return The number of bytes written
*/
public static native int writeEvent(int tag, int value);
/**
* Record an event log message.
* @param tag The event type tag code
* @param list A list of values to log
* @return The number of bytes written
*/
public static native int writeEvent(int tag, Object... list);
/*************************************************************************************/
frameworks/base/core/jni/android_util_EventLog.cpp
static JNINativeMethod gRegisterMethods[] = {
/* name, signature, funcPtr */
{ "writeEvent", "(II)I", (void*) android_util_EventLog_writeEvent_Integer },
{ "writeEvent", "(IJ)I", (void*) android_util_EventLog_writeEvent_Long },
{ "writeEvent", "(IF)I", (void*) android_util_EventLog_writeEvent_Float },
{ "writeEvent", "(ILjava/lang/String;)I", (void*) android_util_EventLog_writeEvent_String},
{ "writeEvent", "(I[Ljava/lang/Object;)I",(void*) android_util_EventLog_writeEvent_Array},
{ "readEvents", "([ILjava/util/Collection;)V", (void*) android_util_EventLog_readEvents},
};
static jint android_util_EventLog_writeEvent_Array(JNIEnv* env, jobject clazz,
jint tag, jobjectArray value) {
uint8_t buf[MAX_EVENT_PAYLOAD];
const size_t max = sizeof(buf) - 1; // leave room for final newline
size_t pos = 2; // Save room for type tag & array count
jsize copied = 0, num = env->GetArrayLength(value);
for (; copied < num && copied < 255; ++copied) {
jobject item = env->GetObjectArrayElement(value, copied);
if (item == NULL || env->IsInstanceOf(item, gStringClass)) {
buf[pos++] = EVENT_TYPE_STRING;
memcpy(&buf[pos], &len, sizeof(len));
memcpy(&buf[pos + sizeof(len)], str, len);
pos += sizeof(len) + len;
} else if (env->IsInstanceOf(item, gIntegerClass)) {
jint intVal = env->GetIntField(item, gIntegerValueID);
if (pos + 1 + sizeof(intVal) > max) break;
buf[pos++] = EVENT_TYPE_INT;
memcpy(&buf[pos], &intVal, sizeof(intVal));
pos += sizeof(intVal);
} else if (env->IsInstanceOf(item, gLongClass)) {
jlong longVal = env->GetLongField(item, gLongValueID);
if (pos + 1 + sizeof(longVal) > max) break;
buf[pos++] = EVENT_TYPE_LONG;
memcpy(&buf[pos], &longVal, sizeof(longVal));
pos += sizeof(longVal);
} else if (env->IsInstanceOf(item, gFloatClass)) {
jfloat floatVal = env->GetFloatField(item, gFloatValueID);
if (pos + 1 + sizeof(floatVal) > max) break;
buf[pos++] = EVENT_TYPE_FLOAT;
memcpy(&buf[pos], &floatVal, sizeof(floatVal));
pos += sizeof(floatVal);
}
}
buf[0] = EVENT_TYPE_LIST;
buf[1] = copied;
buf[pos++] = '\n';
return android_bWriteLog(tag, buf, pos);
}
/*************************************************************************************/
system/core/include/log/log.h
#define android_bWriteLog(tag, payload, len) \
__android_log_bwrite(tag, payload, len)
system/core/liblog/logd_write.c
int __android_log_bwrite(int32_t tag, const void *payload, size_t len)
{
struct iovec vec[2];
vec[0].iov_base = &tag;
vec[0].iov_len = sizeof(tag);
vec[1].iov_base = (void*)payload;
vec[1].iov_len = len;
return write_to_log(LOG_ID_EVENTS, vec, 2);
}
system/core/include/log/uio.h
struct iovec {
void* iov_base;
size_t iov_len;
};
/*************************************************************************************/
system/core/liblog/logd_write.c
int __android_log_bwrite(int32_t tag, const void *payload, size_t len)
{
struct iovec vec[2];
vec[0].iov_base = &tag;
vec[0].iov_len = sizeof(tag);
vec[1].iov_base = (void*)payload;
vec[1].iov_len = len;
return write_to_log(LOG_ID_EVENTS, vec, 2);
}
write_to_log是个函数指针
static int __write_to_log_init(log_id_t, struct iovec *vec, size_t nr);
static int (*write_to_log)(log_id_t, struct iovec *vec, size_t nr) = __write_to_log_init;
pstore的实现方式和log_id没有关系和log的类型没有关系
typedef enum log_id {
LOG_ID_MIN = 0,
LOG_ID_MAIN = 0,
LOG_ID_RADIO = 1,
LOG_ID_EVENTS = 2,
LOG_ID_SYSTEM = 3,
LOG_ID_CRASH = 4,
LOG_ID_KERNEL = 5,
LOG_ID_MAX
} log_id_t;
/*************************************************************************************/
system/core/logcat/logcat.cpp
这里的struct 应该就是传说中的,struct 作为 class 使用,唯一的差别是 struct 默认是public
struct log_device_t {
const char* device;
bool binary;
struct logger *logger;
struct logger_list *logger_list;
bool printed;
log_device_t* next;
log_device_t(const char* d, bool b) {
device = d;
binary = b;
next = NULL;
printed = false;
logger = NULL;
logger_list = NULL;
}
};
/*************************************************************************************/
system/core/include/log/event_tag_map.h
#define EVENT_TAG_MAP_FILE "/system/etc/event-log-tags"
当 -b 的参数是events时:创建的 log_device_t的成员变量binary为1
bool binary = strcmp(name, "events") == 0;
log_device_t* d = new log_device_t(name, binary);
/*
* Single entry.
*/
typedef struct EventTag {
unsigned int tagIndex;
const char* tagStr;
} EventTag;
/*
* Map.
*/
struct EventTagMap {
/* memory-mapped source file; we get strings from here */
void* mapAddr;
size_t mapLen;
/* array of event tags, sorted numerically by tag index */
EventTag* tagArray;
int numTags;
};
system/core/liblog/event_tag_map.c
static void processBuffer(log_device_t* dev, struct log_msg *buf)
{
int bytesWritten = 0;
int err;
AndroidLogEntry entry;
char binaryMsgBuf[1024];
if (dev->binary) {
static bool hasOpenedEventTagMap = false;
static EventTagMap *eventTagMap = NULL;
if (!eventTagMap && !hasOpenedEventTagMap) {
eventTagMap = android_openEventTagMap(EVENT_TAG_MAP_FILE);
hasOpenedEventTagMap = true;
}
err = android_log_processBinaryLogBuffer(&buf->entry_v1, &entry,
eventTagMap,
binaryMsgBuf,
sizeof(binaryMsgBuf));
//printf(">>> pri=%d len=%d msg='%s'\n",
// entry.priority, entry.messageLen, entry.message);
} else {
err = android_log_processLogBuffer(&buf->entry_v1, &entry);
}
}
/*************************************************************************************/
怎样添加event log
/*************************************************************************************/
1. java层怎样添加 EventLog?
frameworks/base/services/core/java/com/android/server/am/EventLogTags.logtags
/** 30014 am_proc_start (User|1|5),(PID|1|5),(UID|1|5),(Process Name|3),(Type|3),(Component|3) */
public static final int AM_PROC_START = 30014;
# Application process has been started
30014 am_proc_start (User|1|5),(PID|1|5),(UID|1|5),(Process Name|3),(Type|3),(Component|3)
怎样使用?EventLog是个class
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
EventLog.writeEvent(EventLogTags.AM_PROC_START,
UserHandle.getUserId(uid), startResult.pid, uid,
app.processName, hostingType,
hostingNameStr != null ? hostingNameStr : "");
2. C文件中怎样添加 event log:
添加文件:
frameworks/native/services/surfaceflinger/EventLog/EventLogTags.logtags
# 60100 - 60199 reserved for surfaceflinger
60100 sf_frame_dur (window|3),(dur0|1),(dur1|1),(dur2|1),(dur3|1),(dur4|1),(dur5|1),(dur6|1)
在android.mk中添加:
EventLog/EventLogTags.logtags \
logcat -b events的输出结果:
08-08 18:36:20.938 1276 1289 I am_pss : [6423,9801,com.android.thememanager,8239104,6909952]
对应的tag:后面的描述的意思是:Pid:6423[5表示ID], UID:9801, 进程名字:com.android.thememanager, PssKb:8239104字节,UssKb:6909952字节
30047 am_pss (Pid|1|5),(UID|1|5),(Process Name|3),(PssKb|2|2),(UssKb|2|2)
/*************************************************************************************/
通过pstore,得到 各种类型的log
/*************************************************************************************/
pstore保存的log类型
console, logcat?
-L -v threadtime -b system
-L -v threadtime -b all -d *:v [-d *:v是什么意思?]
/*************************************************************************************/
frameworks/base/core/java/com/android/internal/logging/EventLogTags.logtags
# interaction logs
524287 sysui_view_visibility (category|1|5),(visible|1|6)
524288 sysui_action (category|1|5),(pkg|3)
524290 sysui_count (name|3),(increment|1)
524291 sysui_histogram (name|3),(bucket|1)
frameworks/base/services/core/java/com/android/server/GestureLauncherService.java:277:
MetricsLogger.histogram(mContext, "power_double_tap_interval", (int) doubleTapInterval);