diff options
author | Robert Sloan <varomodt@google.com> | 2016-09-09 13:29:10 -0700 |
---|---|---|
committer | Robert Sloan <varomodt@google.com> | 2016-09-27 14:08:25 -0700 |
commit | 45899d059086a7715333a213ea268b52f2b1963b (patch) | |
tree | 2198215c793b0e7a94c64560e837a86d0d0e3e9e /src | |
parent | 448ab592cdf0a57230861f7e8ba05e7e5457f2fe (diff) | |
download | loganalysis-45899d059086a7715333a213ea268b52f2b1963b.tar.gz |
Add loganalysis facility for parsing DVM lock logs.
BUG: 31382082
Change-Id: Ib33f186b5869cdf1cb72f80bd457a6ce7fb5def8
Diffstat (limited to 'src')
-rw-r--r-- | src/com/android/loganalysis/LogAnalyzer.java | 27 | ||||
-rw-r--r-- | src/com/android/loganalysis/item/DvmLockSampleItem.java | 87 | ||||
-rw-r--r-- | src/com/android/loganalysis/parser/DvmLockSampleParser.java | 128 |
3 files changed, 241 insertions, 1 deletions
diff --git a/src/com/android/loganalysis/LogAnalyzer.java b/src/com/android/loganalysis/LogAnalyzer.java index a0a49a1..5a16c23 100644 --- a/src/com/android/loganalysis/LogAnalyzer.java +++ b/src/com/android/loganalysis/LogAnalyzer.java @@ -16,12 +16,14 @@ package com.android.loganalysis; import com.android.loganalysis.item.BugreportItem; +import com.android.loganalysis.item.DvmLockSampleItem; import com.android.loganalysis.item.IItem; import com.android.loganalysis.item.KernelLogItem; import com.android.loganalysis.item.LogcatItem; import com.android.loganalysis.item.MemoryHealthItem; import com.android.loganalysis.item.MonkeyLogItem; import com.android.loganalysis.parser.BugreportParser; +import com.android.loganalysis.parser.DvmLockSampleParser; import com.android.loganalysis.parser.KernelLogParser; import com.android.loganalysis.parser.LogcatParser; import com.android.loganalysis.parser.MemoryHealthParser; @@ -84,6 +86,9 @@ public class LogAnalyzer { @Option(name="print", description="Print the result type") private List<ResultType> mResultType = new ArrayList<ResultType>(); + @Option(name="events-log", description="The path to the events log") + private String mEventsLogPath = null; + /** Constant for JSON output */ private static final String RAW_DATA = "RAW"; /** Constant for JSON output */ @@ -141,6 +146,16 @@ public class LogAnalyzer { printMemoryHealthLog(item); return; } + + if (mEventsLogPath != null) { + reader = getBufferedReader(mEventsLogPath); + + // The only log we know how to parse in the Events log are + // DVM lock samples. + DvmLockSampleItem item = new DvmLockSampleParser().parse(reader); + printDVMLog(item); + return; + } } catch (FileNotFoundException e) { System.err.println(e.getMessage()); } catch (IOException e) { @@ -250,6 +265,16 @@ public class LogAnalyzer { } /** + * Print a DVM log entry to stdout. + */ + private void printDVMLog(DvmLockSampleItem dvmLog) { + if (OutputFormat.JSON.equals(mOutputFormat)) { + printJson(dvmLog); + } + // TODO: Print DVM log in human readable form. + } + + /** * Print an {@link IItem} to stdout. */ private void printJson(IItem item) { @@ -322,7 +347,7 @@ public class LogAnalyzer { * Print the usage for the command. */ private void printUsage() { - System.err.println("Usage: loganalysis [--bugreport FILE | --logcat FILE | " + + System.err.println("Usage: loganalysis [--bugreport FILE | --events-log FILE | --logcat FILE | " + "--kernel-log FILE | --monkey-log FILE]"); } diff --git a/src/com/android/loganalysis/item/DvmLockSampleItem.java b/src/com/android/loganalysis/item/DvmLockSampleItem.java new file mode 100644 index 0000000..fa3e7a8 --- /dev/null +++ b/src/com/android/loganalysis/item/DvmLockSampleItem.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2015 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 org.json.JSONException; +import org.json.JSONObject; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * An {@link IItem} used to store DVM Lock allocation Info + */ +public class DvmLockSampleItem extends GenericItem { + + public static final String PROCESS_NAME = "PROCESS_NAME"; + public static final String SENSITIVITY_FLAG = "SENSITIVITY_FLAG"; + public static final String WAITING_THREAD_NAME = "WAITING_THREAD_NAME"; + public static final String WAIT_TIME = "WAIT_TIME"; + public static final String WAITING_SOURCE_FILE = "WAITING_SOURCE_FILE"; + public static final String WAITING_SOURCE_LINE = "WAITING_SOURCE_LINE"; + public static final String OWNER_FILE_NAME = "OWNER_FILE_NAME"; + public static final String OWNER_ACQUIRE_SOURCE_LINE = "OWNER_ACQUIRE_SOURCE_LINE"; + public static final String SAMPLE_PERCENTAGE = "SAMPLE_PERCENTAGE"; + + private static final Set<String> ATTRIBUTES = new HashSet<String>(Arrays.asList( + PROCESS_NAME, SENSITIVITY_FLAG, WAITING_THREAD_NAME, WAIT_TIME, + WAITING_SOURCE_FILE, WAITING_SOURCE_LINE, OWNER_FILE_NAME, + OWNER_ACQUIRE_SOURCE_LINE, SAMPLE_PERCENTAGE)); + + private static final Map<String, Class<?>> TYPES = new HashMap<String, Class<?>>() {{ + put(PROCESS_NAME, String.class); + put(SENSITIVITY_FLAG, Boolean.class); + put(WAITING_THREAD_NAME, String.class); + put(WAIT_TIME, Integer.class); + put(WAITING_SOURCE_FILE, String.class); + put(WAITING_SOURCE_LINE, Integer.class); + put(OWNER_FILE_NAME, String.class); + put(OWNER_ACQUIRE_SOURCE_LINE, Integer.class); + put(SAMPLE_PERCENTAGE, Integer.class); + }}; + + public DvmLockSampleItem() { + super(ATTRIBUTES); + } + + /** + * {@inheritDoc} + */ + public void setAttribute(String attribute, Object value) throws IllegalArgumentException { + if(ATTRIBUTES.contains(attribute)) { + if (TYPES.get(attribute).isAssignableFrom(value.getClass())) { + super.setAttribute(attribute, value); + } else { + throw new IllegalArgumentException( + "Invalid attribute type for " + attribute + + ": found " + value.getClass().getCanonicalName() + + " expected " + TYPES.get(attribute).getCanonicalName()); + } + } else { + throw new IllegalArgumentException("Invalid attribute key: " + attribute); + } + } + + /** + * {@inheritDoc} + */ + public Object getAttribute(String attribute) throws IllegalArgumentException { + return super.getAttribute(attribute); + } +} diff --git a/src/com/android/loganalysis/parser/DvmLockSampleParser.java b/src/com/android/loganalysis/parser/DvmLockSampleParser.java new file mode 100644 index 0000000..5de5f94 --- /dev/null +++ b/src/com/android/loganalysis/parser/DvmLockSampleParser.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2015 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.parser; + +import com.google.common.annotations.VisibleForTesting; + +import com.android.loganalysis.item.DvmLockSampleItem; + +import java.io.BufferedReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * A {@link IParser} to parse DVM lock sample allocation logs + */ +public class DvmLockSampleParser implements IParser { + + private static final String nameRegex = "([^,]+)"; + private static final String fileRegex = "(-|[A-Za-z]+\\.[A-Za-z]+)"; + private static final String intRegex = "(\\d+)"; + + /** + * Matches the DVM lock sample log format: + * + * 09-04 05:40:07.809 1026 10592 I dvm_lock_sample: + * [system_server,1,Binder:1026_F,46,NetworkPolicyManagerService.java,2284,-,802,9] + */ + private static final Pattern logContentionEventPattern = Pattern.compile( + "\\[" + String.join(",\\s*", Arrays.asList( + nameRegex, // Process name + intRegex, // Process sensitivity flag + nameRegex, // Waiting thread name + intRegex, // Wait time + fileRegex, // Waiting Source File + intRegex, // Waiting Source Line + fileRegex, // Owner File Name ("-" if the same) + intRegex, // Owner Acquire Source Line + intRegex // Sample Percentage + )) + "\\]"); + + private DvmLockSampleItem mItem = new DvmLockSampleItem(); + + /** + * Parse a dvm log from a {@link BufferedReader} into a {@link DvmLockSampleItem}. + * + * @return The {@link DvmLockSampleItem}. + * @see #parse(List) + */ + public DvmLockSampleItem parse(BufferedReader input) throws IOException { + List<String> lines = new ArrayList<>(); + + for(String line = input.readLine(); line != null; line = input.readLine()) { + lines.add(line); + } + + return parse(lines); + } + + /** + * {@inheritDoc} + * + * @return The {@link DvmLockSampleItem}. + */ + @Override + public DvmLockSampleItem parse(List<String> lines) { + DvmLockSampleItem mItem = new DvmLockSampleItem(); + + for (String line : lines) { + Matcher m = logContentionEventPattern.matcher(line); + + if(m.matches()) { + mItem.setAttribute(DvmLockSampleItem.PROCESS_NAME, + m.group(1)); + + mItem.setAttribute(DvmLockSampleItem.SENSITIVITY_FLAG, + 1 == Integer.parseInt(m.group(2))); + + mItem.setAttribute(DvmLockSampleItem.WAITING_THREAD_NAME, + m.group(3)); + + mItem.setAttribute(DvmLockSampleItem.WAIT_TIME, + Integer.parseInt(m.group(4))); + + mItem.setAttribute(DvmLockSampleItem.WAITING_SOURCE_FILE, + m.group(5)); + + mItem.setAttribute(DvmLockSampleItem.WAITING_SOURCE_LINE, + Integer.parseInt(m.group(6))); + + // If the owner file name is -, the dvm log format specification + // says that we should use the waiting source file. + mItem.setAttribute(DvmLockSampleItem.OWNER_FILE_NAME, + m.group(7).equals("-") ? m.group(5) : m.group(7)); + + mItem.setAttribute(DvmLockSampleItem.OWNER_ACQUIRE_SOURCE_LINE, + Integer.parseInt(m.group(8))); + + mItem.setAttribute(DvmLockSampleItem.SAMPLE_PERCENTAGE, + Integer.parseInt(m.group(9))); + } + } + + System.out.println(mItem.toJson().toString()); + return mItem; + } + + @VisibleForTesting + DvmLockSampleItem getItem() { + return mItem; + } +} |