Modify LogcatParser to use new utils.
Change-Id: Ib7df6364179123eaaec19ceb2f2e3024550f18de
diff --git a/src/com/android/loganalysis/item/GenericLogcatItem.java b/src/com/android/loganalysis/item/GenericLogcatItem.java
index 4a3642d..4ca5243 100644
--- a/src/com/android/loganalysis/item/GenericLogcatItem.java
+++ b/src/com/android/loganalysis/item/GenericLogcatItem.java
@@ -102,28 +102,28 @@
}
/**
- * Get the last preamble for of the event.
+ * Get the last preamble for the event.
*/
public String getLastPreamble() {
return (String) getAttribute(LAST_PREAMBLE);
}
/**
- * Set the last preamble for of the event.
+ * Set the last preamble for the event.
*/
public void setLastPreamble(String preamble) {
setAttribute(LAST_PREAMBLE, preamble);
}
/**
- * Get the process preamble for of the event.
+ * Get the process preamble for the event.
*/
public String getProcessPreamble() {
return (String) getAttribute(PROC_PREAMBLE);
}
/**
- * Set the process preamble for of the event.
+ * Set the process preamble for the event.
*/
public void setProcessPreamble(String preamble) {
setAttribute(PROC_PREAMBLE, preamble);
diff --git a/src/com/android/loganalysis/item/LogcatItem.java b/src/com/android/loganalysis/item/LogcatItem.java
index 7bf42a2..883773a 100644
--- a/src/com/android/loganalysis/item/LogcatItem.java
+++ b/src/com/android/loganalysis/item/LogcatItem.java
@@ -128,4 +128,18 @@
}
return ncs;
}
+
+ /**
+ * Get the list of all {@link MiscLogcatItem} events for a cateogry.
+ */
+ public List<MiscLogcatItem> getMiscEvents(String category) {
+ List<MiscLogcatItem> items = new LinkedList<MiscLogcatItem>();
+ for (IItem item : getEvents()) {
+ if (item instanceof MiscLogcatItem &&
+ ((MiscLogcatItem) item).getCategory().equals(category)) {
+ items.add((MiscLogcatItem) item);
+ }
+ }
+ return items;
+ }
}
diff --git a/src/com/android/loganalysis/item/MiscLogcatItem.java b/src/com/android/loganalysis/item/MiscLogcatItem.java
new file mode 100644
index 0000000..c835bb9
--- /dev/null
+++ b/src/com/android/loganalysis/item/MiscLogcatItem.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2013 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.loganalysis.item;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * An {@link IItem} used to store miscellaneous logcat info.
+ */
+public class MiscLogcatItem extends GenericLogcatItem {
+ public static final String TYPE = "MISC LOGCAT";
+
+ private static final String CATEGORY = "CATEGORY";
+ private static final String MESSAGE = "MESSAGE";
+
+ private static final Set<String> ATTRIBUTES = new HashSet<String>(Arrays.asList(
+ CATEGORY, MESSAGE));
+
+ /**
+ * The constructor for {@link MiscLogcatItem}.
+ */
+ public MiscLogcatItem() {
+ super(TYPE, ATTRIBUTES);
+ }
+
+ /**
+ * Get the category of the event.
+ */
+ public String getCategory() {
+ return (String) getAttribute(CATEGORY);
+ }
+
+ /**
+ * Set the category of the event.
+ */
+ public void setCategory(String category) {
+ setAttribute(CATEGORY, category);
+ }
+
+ /**
+ * Get the message for the event.
+ */
+ public String getMessage() {
+ return (String) getAttribute(MESSAGE);
+ }
+
+ /**
+ * Set the message for the event.
+ */
+ public void setMessage(String message) {
+ setAttribute(MESSAGE, message);
+ }
+}
diff --git a/src/com/android/loganalysis/parser/LogcatParser.java b/src/com/android/loganalysis/parser/LogcatParser.java
index 9edbede..88f029a 100644
--- a/src/com/android/loganalysis/parser/LogcatParser.java
+++ b/src/com/android/loganalysis/parser/LogcatParser.java
@@ -17,7 +17,10 @@
import com.android.loganalysis.item.GenericLogcatItem;
import com.android.loganalysis.item.LogcatItem;
+import com.android.loganalysis.item.MiscLogcatItem;
import com.android.loganalysis.util.ArrayUtil;
+import com.android.loganalysis.util.LogPatternUtil;
+import com.android.loganalysis.util.LogTailUtil;
import java.io.BufferedReader;
import java.io.IOException;
@@ -28,7 +31,6 @@
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
-import java.util.ListIterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -43,6 +45,9 @@
* </p>
*/
public class LogcatParser implements IParser {
+ public static final String HIGH_CPU_USAGE = "HIGH_CPU_USAGE";
+ public static final String HIGH_MEMORY_USAGE = "HIGH_MEMORY_USAGE";
+ public static final String RUNTIME_RESTART = "RUNTIME_RESTART";
/**
* Match a single line of `logcat -v threadtime`, such as:
@@ -86,11 +91,9 @@
}
}
- private static final int MAX_BUFF_SIZE = 500;
- private static final int MAX_LAST_PREAMBLE_SIZE = 15;
- private static final int MAX_PROC_PREAMBLE_SIZE = 15;
+ private LogPatternUtil mPatternUtil = new LogPatternUtil();
+ private LogTailUtil mPreambleUtil = new LogTailUtil();
- private LinkedList<String> mRingBuffer = new LinkedList<String>();
private String mYear = null;
LogcatItem mLogcat = new LogcatItem();
@@ -105,6 +108,7 @@
* Constructor for {@link LogcatParser}.
*/
public LogcatParser() {
+ initPatterns();
}
/**
@@ -113,6 +117,7 @@
* @param year The year as a string.
*/
public LogcatParser(String year) {
+ this();
setYear(year);
}
@@ -201,8 +206,8 @@
String key = encodeLine(pid, tid, level, tag);
LogcatData data;
if (!mDataMap.containsKey(key) || AnrParser.START.matcher(msg).matches()) {
- data = new LogcatData(pid, tid, time, level, tag, getLastPreamble(),
- getProcPreamble(pid));
+ data = new LogcatData(pid, tid, time, level, tag, mPreambleUtil.getLastTail(),
+ mPreambleUtil.getIdTail(pid));
mDataMap.put(key, data);
mDataList.add(data);
} else {
@@ -217,8 +222,8 @@
String key = encodeLine(pid, tid, level, tag);
LogcatData data;
if (!mDataMap.containsKey(key)) {
- data = new LogcatData(pid, tid, time, level, tag, getLastPreamble(),
- getProcPreamble(pid));
+ data = new LogcatData(pid, tid, time, level, tag, mPreambleUtil.getLastTail(),
+ mPreambleUtil.getIdTail(pid));
mDataMap.put(key, data);
mDataList.add(data);
} else {
@@ -227,11 +232,16 @@
data.mLines.add(msg);
}
- // After parsing the line, add it the the buffer for the preambles.
- mRingBuffer.add(line);
- if (mRingBuffer.size() > MAX_BUFF_SIZE) {
- mRingBuffer.removeFirst();
+ // Check the message here but add it in commit()
+ if (mPatternUtil.checkMessage(msg) != null) {
+ LogcatData data = new LogcatData(pid, tid, time, level, tag,
+ mPreambleUtil.getLastTail(), mPreambleUtil.getIdTail(pid));
+ data.mLines.add(msg);
+ mDataList.add(data);
}
+
+ // After parsing the line, add it the the buffer for the preambles.
+ mPreambleUtil.addLine(pid, line);
}
/**
@@ -249,6 +259,15 @@
} else if ("I".equals(data.mLevel) && "DEBUG".equals(data.mTag)) {
// CLog.v("Parsing native crash: %s", data.mLines);
item = new NativeCrashParser().parse(data.mLines);
+ } else {
+ String msg = ArrayUtil.join("\n", data.mLines);
+ String category = mPatternUtil.checkMessage(msg);
+ if (category != null) {
+ MiscLogcatItem logcatItem = new MiscLogcatItem();
+ logcatItem.setCategory(category);
+ logcatItem.setMessage(msg);
+ item = logcatItem;
+ }
}
if (item != null) {
item.setEventTime(data.mTime);
@@ -298,55 +317,17 @@
}
}
- /**
- * Get the last {@value #MAX_LAST_PREAMBLE_SIZE} lines of logcat.
- */
- private String getLastPreamble() {
- final int size = mRingBuffer.size();
- List<String> preamble;
- if (size > getLastPreambleSize()) {
- preamble = mRingBuffer.subList(size - getLastPreambleSize(), size);
- } else {
- preamble = mRingBuffer;
- }
- return ArrayUtil.join("\n", preamble).trim();
- }
+ private void initPatterns() {
+ // High CPU usage
+ mPatternUtil.addPattern(Pattern.compile(".* timed out \\(is the CPU pegged\\?\\).*"),
+ HIGH_CPU_USAGE);
- /**
- * Get the last {@value #MAX_PROC_PREAMBLE_SIZE} lines of logcat which match the given pid.
- */
- private String getProcPreamble(int pid) {
- LinkedList<String> preamble = new LinkedList<String>();
+ // High memory usage
+ mPatternUtil.addPattern(Pattern.compile(
+ "GetBufferLock timed out for thread \\d+ buffer .*"), HIGH_MEMORY_USAGE);
- ListIterator<String> li = mRingBuffer.listIterator(mRingBuffer.size());
- while (li.hasPrevious()) {
- String line = li.previous();
-
- Matcher m = THREADTIME_LINE.matcher(line);
- Matcher tm = TIME_LINE.matcher(line);
- if ((m.matches() && pid == Integer.parseInt(m.group(2))) ||
- (tm.matches() && pid == Integer.parseInt(tm.group(4)))) {
- preamble.addFirst(line);
- }
-
- if (preamble.size() == getProcPreambleSize()) {
- return ArrayUtil.join("\n", preamble).trim();
- }
- }
- return ArrayUtil.join("\n", preamble).trim();
- }
-
- /**
- * Get the number of lines in the last preamble. Exposed for unit testing.
- */
- int getLastPreambleSize() {
- return MAX_LAST_PREAMBLE_SIZE;
- }
-
- /**
- * Get the number of lines in the process preamble. Exposed for unit testing.
- */
- int getProcPreambleSize() {
- return MAX_PROC_PREAMBLE_SIZE;
+ // Runtime restarts
+ mPatternUtil.addPattern(Pattern.compile("\\*\\*\\* WATCHDOG KILLING SYSTEM PROCESS.*"),
+ RUNTIME_RESTART);
}
}
diff --git a/tests/src/com/android/loganalysis/parser/LogcatParserTest.java b/tests/src/com/android/loganalysis/parser/LogcatParserTest.java
index 37a39b6..0ac0338 100644
--- a/tests/src/com/android/loganalysis/parser/LogcatParserTest.java
+++ b/tests/src/com/android/loganalysis/parser/LogcatParserTest.java
@@ -16,6 +16,7 @@
package com.android.loganalysis.parser;
import com.android.loganalysis.item.LogcatItem;
+import com.android.loganalysis.item.MiscLogcatItem;
import com.android.loganalysis.util.ArrayUtil;
import junit.framework.TestCase;
@@ -103,6 +104,40 @@
logcat.getNativeCrashes().get(0).getEventTime());
}
+ public void testParse_misc_events() throws ParseException {
+ List<String> lines = Arrays.asList(
+ "04-25 18:33:27.273 1676 1821 W AudioTrack: obtainBuffer timed out (is the CPU pegged?) 0x361378 user=0000116a, server=00000000",
+ "04-25 18:33:28.273 7813 7813 E gralloc : GetBufferLock timed out for thread 7813 buffer 0x61 usage 0x200 LockState 1",
+ "04-25 18:33:29.273 395 637 W Watchdog: *** WATCHDOG KILLING SYSTEM PROCESS: null");
+
+ LogcatItem logcat = new LogcatParser("2012").parse(lines);
+ assertNotNull(logcat);
+ assertEquals(parseTime("2012-04-25 18:33:27.273"), logcat.getStartTime());
+ assertEquals(parseTime("2012-04-25 18:33:29.273"), logcat.getStopTime());
+ assertEquals(3, logcat.getEvents().size());
+ assertEquals(1, logcat.getMiscEvents(LogcatParser.HIGH_CPU_USAGE).size());
+ assertEquals(1, logcat.getMiscEvents(LogcatParser.HIGH_MEMORY_USAGE).size());
+ assertEquals(1, logcat.getMiscEvents(LogcatParser.RUNTIME_RESTART).size());
+
+ MiscLogcatItem item = logcat.getMiscEvents(LogcatParser.HIGH_CPU_USAGE).get(0);
+
+ assertEquals(1676, item.getPid().intValue());
+ assertEquals(1821, item.getTid().intValue());
+ assertEquals(parseTime("2012-04-25 18:33:27.273"), item.getEventTime());
+
+ item = logcat.getMiscEvents(LogcatParser.HIGH_MEMORY_USAGE).get(0);
+
+ assertEquals(7813, item.getPid().intValue());
+ assertEquals(7813, item.getTid().intValue());
+ assertEquals(parseTime("2012-04-25 18:33:28.273"), item.getEventTime());
+
+ item = logcat.getMiscEvents(LogcatParser.RUNTIME_RESTART).get(0);
+
+ assertEquals(395, item.getPid().intValue());
+ assertEquals(637, item.getTid().intValue());
+ assertEquals(parseTime("2012-04-25 18:33:29.273"), item.getEventTime());
+ }
+
/**
* Test that multiple events can be parsed.
*/
@@ -225,9 +260,9 @@
}
/**
- * Test that the preambles are set correctly if there's only partial preambles.
+ * Test that the preambles are set correctly.
*/
- public void testParse_partial_preambles() throws ParseException {
+ public void testParse_preambles() throws ParseException {
List<String> lines = Arrays.asList(
"04-25 09:15:47.799 123 3082 I tag: message 1",
"04-25 09:20:47.799 3064 3082 I tag: message 2",
@@ -275,61 +310,6 @@
}
/**
- * Test that the preambles are set correctly if there's only full preambles.
- */
- public void testParse_preambles() throws ParseException {
- List<String> lines = Arrays.asList(
- "04-25 09:43:47.799 3064 3082 I tag: message 1",
- "04-25 09:44:47.799 123 3082 I tag: message 2",
- "04-25 09:45:47.799 3064 3082 I tag: message 3",
- "04-25 09:46:47.799 234 3082 I tag: message 4",
- "04-25 09:47:47.799 3064 3082 I tag: message 5",
- "04-25 09:48:47.799 345 3082 I tag: message 6",
- "04-25 09:49:47.799 3064 3082 I tag: message 7",
- "04-25 09:50:47.799 456 3082 I tag: message 8",
- "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception",
- "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)",
- "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)",
- "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)");
-
- List<String> expectedLastPreamble = Arrays.asList(
- "04-25 09:48:47.799 345 3082 I tag: message 6",
- "04-25 09:49:47.799 3064 3082 I tag: message 7",
- "04-25 09:50:47.799 456 3082 I tag: message 8");
-
- List<String> expectedProcPreamble = Arrays.asList(
- "04-25 09:45:47.799 3064 3082 I tag: message 3",
- "04-25 09:47:47.799 3064 3082 I tag: message 5",
- "04-25 09:49:47.799 3064 3082 I tag: message 7");
-
- LogcatItem logcat = new LogcatParser("2012") {
- @Override
- int getLastPreambleSize() {
- return 3;
- }
-
- @Override
- int getProcPreambleSize() {
- return 3;
- }
- }.parse(lines);
-
- assertNotNull(logcat);
- assertEquals(parseTime("2012-04-25 09:43:47.799"), logcat.getStartTime());
- assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime());
- assertEquals(1, logcat.getEvents().size());
- assertEquals(1, logcat.getJavaCrashes().size());
- assertEquals(3064, logcat.getJavaCrashes().get(0).getPid().intValue());
- assertEquals(3082, logcat.getJavaCrashes().get(0).getTid().intValue());
- assertEquals(ArrayUtil.join("\n", expectedLastPreamble),
- logcat.getJavaCrashes().get(0).getLastPreamble());
- assertEquals(ArrayUtil.join("\n", expectedProcPreamble),
- logcat.getJavaCrashes().get(0).getProcessPreamble());
- assertEquals(parseTime("2012-04-25 09:55:47.799"),
- logcat.getJavaCrashes().get(0).getEventTime());
- }
-
- /**
* Test that the time logcat format can be parsed.
*/
public void testParse_time() throws ParseException {