com.android.ddmlib.log.EventLogParser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ddmlib Show documentation
Show all versions of ddmlib Show documentation
Library providing APIs to talk to Android devices
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.ddmlib.log;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.Log;
import com.android.ddmlib.MultiLineReceiver;
import com.android.ddmlib.log.EventContainer.EventValueType;
import com.android.ddmlib.log.EventValueDescription.ValueType;
import com.android.ddmlib.log.LogReceiver.LogEntry;
import com.android.ddmlib.utils.ArrayHelper;
import com.google.common.base.Charsets;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Parser for the "event" log.
*/
public final class EventLogParser {
/** Location of the tag map file on the device */
private static final String EVENT_TAG_MAP_FILE = "/system/etc/event-log-tags"; //$NON-NLS-1$
/**
* Event log entry types. These must match up with the declarations in
* java/android/android/util/EventLog.java.
*/
private static final int EVENT_TYPE_INT = 0;
private static final int EVENT_TYPE_LONG = 1;
private static final int EVENT_TYPE_STRING = 2;
private static final int EVENT_TYPE_LIST = 3;
private static final Pattern PATTERN_SIMPLE_TAG = Pattern.compile(
"^(\\d+)\\s+([A-Za-z0-9_]+)\\s*$"); //$NON-NLS-1$
private static final Pattern PATTERN_TAG_WITH_DESC = Pattern.compile(
"^(\\d+)\\s+([A-Za-z0-9_]+)\\s*(.*)\\s*$"); //$NON-NLS-1$
private static final Pattern PATTERN_DESCRIPTION = Pattern.compile(
"\\(([A-Za-z0-9_\\s]+)\\|(\\d+)(\\|\\d+){0,1}\\)"); //$NON-NLS-1$
private static final Pattern TEXT_LOG_LINE = Pattern.compile(
"(\\d\\d)-(\\d\\d)\\s(\\d\\d):(\\d\\d):(\\d\\d).(\\d{3})\\s+I/([a-zA-Z0-9_]+)\\s*\\(\\s*(\\d+)\\):\\s+(.*)"); //$NON-NLS-1$
private final TreeMap mTagMap = new TreeMap();
private final TreeMap mValueDescriptionMap =
new TreeMap();
public EventLogParser() {
}
/**
* Inits the parser for a specific Device.
*
* This methods reads the event-log-tags located on the device to find out
* what tags are being written to the event log and what their format is.
* @param device The device.
* @return true
if success, false
if failure or cancellation.
*/
public boolean init(IDevice device) {
// read the event tag map file on the device.
try {
device.executeShellCommand("cat " + EVENT_TAG_MAP_FILE, //$NON-NLS-1$
new MultiLineReceiver() {
@Override
public void processNewLines(String[] lines) {
for (String line : lines) {
processTagLine(line);
}
}
@Override
public boolean isCancelled() {
return false;
}
});
} catch (Exception e) {
// catch all possible exceptions and return false.
return false;
}
return true;
}
/**
* Inits the parser with the content of a tag file.
* @param tagFileContent the lines of a tag file.
* @return true
if success, false
if failure.
*/
public boolean init(String[] tagFileContent) {
for (String line : tagFileContent) {
processTagLine(line);
}
return true;
}
/**
* Inits the parser with a specified event-log-tags file.
* @param filePath
* @return true
if success, false
if failure.
*/
public boolean init(String filePath) {
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(filePath));
String line = null;
do {
line = reader.readLine();
if (line != null) {
processTagLine(line);
}
} while (line != null);
return true;
} catch (IOException e) {
return false;
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
// ignore
}
}
}
/**
* Processes a line from the event-log-tags file.
* @param line the line to process
*/
private void processTagLine(String line) {
// ignore empty lines and comment lines
if (!line.isEmpty() && line.charAt(0) != '#') {
Matcher m = PATTERN_TAG_WITH_DESC.matcher(line);
if (m.matches()) {
try {
int value = Integer.parseInt(m.group(1));
String name = m.group(2);
if (name != null && mTagMap.get(value) == null) {
mTagMap.put(value, name);
}
// special case for the GC tag. We ignore what is in the file,
// and take what the custom GcEventContainer class tells us.
// This is due to the event encoding several values on 2 longs.
// @see GcEventContainer
if (value == GcEventContainer.GC_EVENT_TAG) {
mValueDescriptionMap.put(value,
GcEventContainer.getValueDescriptions());
} else {
String description = m.group(3);
if (description != null && !description.isEmpty()) {
EventValueDescription[] desc =
processDescription(description);
if (desc != null) {
mValueDescriptionMap.put(value, desc);
}
}
}
} catch (NumberFormatException e) {
// failed to convert the number into a string. just ignore it.
}
} else {
m = PATTERN_SIMPLE_TAG.matcher(line);
if (m.matches()) {
int value = Integer.parseInt(m.group(1));
String name = m.group(2);
if (name != null && mTagMap.get(value) == null) {
mTagMap.put(value, name);
}
}
}
}
}
private EventValueDescription[] processDescription(String description) {
String[] descriptions = description.split("\\s*,\\s*"); //$NON-NLS-1$
ArrayList list = new ArrayList();
for (String desc : descriptions) {
Matcher m = PATTERN_DESCRIPTION.matcher(desc);
if (m.matches()) {
try {
String name = m.group(1);
String typeString = m.group(2);
int typeValue = Integer.parseInt(typeString);
EventValueType eventValueType = EventValueType.getEventValueType(typeValue);
if (eventValueType == null) {
// just ignore this description if the value is not recognized.
// TODO: log the error.
}
typeString = m.group(3);
if (typeString != null && !typeString.isEmpty()) {
//skip the |
typeString = typeString.substring(1);
typeValue = Integer.parseInt(typeString);
ValueType valueType = ValueType.getValueType(typeValue);
list.add(new EventValueDescription(name, eventValueType, valueType));
} else {
list.add(new EventValueDescription(name, eventValueType));
}
} catch (NumberFormatException nfe) {
// just ignore this description if one number is malformed.
// TODO: log the error.
} catch (InvalidValueTypeException e) {
// just ignore this description if data type and data unit don't match
// TODO: log the error.
}
} else {
Log.e("EventLogParser", //$NON-NLS-1$
String.format("Can't parse %1$s", description)); //$NON-NLS-1$
}
}
if (list.isEmpty()) {
return null;
}
return list.toArray(new EventValueDescription[list.size()]);
}
public EventContainer parse(LogEntry entry) {
if (entry.len < 4) {
return null;
}
int inOffset = 0;
int tagValue = ArrayHelper.swap32bitFromArray(entry.data, inOffset);
inOffset += 4;
String tag = mTagMap.get(tagValue);
if (tag == null) {
Log.e("EventLogParser", String.format("unknown tag number: %1$d", tagValue));
}
ArrayList
© 2015 - 2025 Weber Informatics LLC | Privacy Policy