summaryrefslogtreecommitdiff
path: root/src/com/android/loganalysis/parser
diff options
context:
space:
mode:
authorChao Yan <aceyansf@google.com>2019-06-10 15:27:46 -0700
committerChao Yan <aceyansf@google.com>2019-06-17 15:25:18 -0700
commit4021c75b78c5c41f3f37944977ee5961e589e560 (patch)
treea85c957a397cb72774dcdd82e053eab34d734d75 /src/com/android/loganalysis/parser
parent8c9637105ba68f4ecd61512203cb1ba257f4cf96 (diff)
downloadloganalysis-4021c75b78c5c41f3f37944977ee5961e589e560.tar.gz
Added a new parser for timing metrics from logcat
The new parser will be used for analyze logcat to parse timing related metrics, e.g. can be used for boot time metrics parsing Test: tools/tradefederation/core/tests/run_tradefed_tests.sh --class com.android.loganalysis.UnitTests Bug: 133166326 Change-Id: I0a17a813fd0f5b7908279d76c38d4d8e0fbf1e96
Diffstat (limited to 'src/com/android/loganalysis/parser')
-rw-r--r--src/com/android/loganalysis/parser/TimingsLogParser.java128
1 files changed, 128 insertions, 0 deletions
diff --git a/src/com/android/loganalysis/parser/TimingsLogParser.java b/src/com/android/loganalysis/parser/TimingsLogParser.java
new file mode 100644
index 0000000..2bafd30
--- /dev/null
+++ b/src/com/android/loganalysis/parser/TimingsLogParser.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2019 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.android.loganalysis.item.IItem;
+import com.android.loganalysis.item.SystemServicesTimingItem;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * An {@link IParser} to parse boot metrics from logcat. It currently assumes "threadtime" format of
+ * logcat. It will parse duration metrics for some system services like System Server, Zygote,
+ * System UI, e.t.c.
+ *
+ * <p>TODO(b/133166326): Add support for parsing thread time info from log lines, and also support
+ * dynamically adding new log line patterns.
+ */
+public class TimingsLogParser implements IParser {
+
+ private static final String SYSTEM_SERVICES_TIME_PREFIX =
+ "^\\d*-\\d*\\s*\\d*:\\d*:\\d*.\\d*\\s*"
+ + "\\d*\\s*\\d*\\s*D\\s*(?<componentname>.*):\\s*(?<subname>\\S*)\\s*";
+ private static final String SYSTEM_SERVICES_TIME_SUFFIX = ":\\s*(?<time>.*)ms\\s*$";
+
+ /**
+ * Match the line with system services duration info like:
+ *
+ * <p>03-10 21:43:40.328 1005 1005 D SystemServerTiming:
+ * StartKeyAttestationApplicationIdProviderService took to complete: 3474ms
+ */
+ private static final Pattern SYSTEM_SERVICES_DURATION =
+ Pattern.compile(
+ String.format(
+ "%stook to complete%s",
+ SYSTEM_SERVICES_TIME_PREFIX, SYSTEM_SERVICES_TIME_SUFFIX));
+ /**
+ * Match the line with system services start time info like:
+ *
+ * <p>01-10 01:25:57.249 989 989 D BootAnimation: BootAnimationStartTiming start time: 8343ms
+ */
+ private static final Pattern SYSTEM_SERVICES_START_TIME =
+ Pattern.compile(
+ String.format(
+ "%sstart time%s",
+ SYSTEM_SERVICES_TIME_PREFIX, SYSTEM_SERVICES_TIME_SUFFIX));
+
+ @Override
+ public IItem parse(List<String> lines) {
+ throw new UnsupportedOperationException(
+ "Method has not been implemented in lieu of others");
+ }
+
+ /**
+ * A method that parses the logcat input for system services timing information. It will ignore
+ * duplicated log lines and will keep multiple values for the same timing metric generated at
+ * different time in the log
+ *
+ * @param input Logcat input as a {@link BufferedReader}
+ * @return a list of {@link SystemServicesTimingItem}
+ * @throws IOException
+ */
+ public List<SystemServicesTimingItem> parseSystemServicesTimingItems(BufferedReader input)
+ throws IOException {
+ Set<String> matchedLines = new HashSet<>();
+ List<SystemServicesTimingItem> items = new ArrayList<>();
+ String line;
+ while ((line = input.readLine()) != null) {
+ if (matchedLines.contains(line)) {
+ continue;
+ }
+ SystemServicesTimingItem item = parseSystemServicesTimingItem(line);
+ if (item == null) {
+ continue;
+ }
+ items.add(item);
+ matchedLines.add(line);
+ }
+ return items;
+ }
+
+ /**
+ * Parse a particular log line to see if it matches the system service timing pattern and return
+ * a {@link SystemServicesTimingItem} if matches, otherwise return null.
+ *
+ * @param line a single log line
+ * @return a {@link SystemServicesTimingItem}
+ */
+ private SystemServicesTimingItem parseSystemServicesTimingItem(String line) {
+ Matcher matcher = SYSTEM_SERVICES_DURATION.matcher(line);
+ boolean durationMatched = matcher.matches();
+ if (!durationMatched) {
+ matcher = SYSTEM_SERVICES_START_TIME.matcher(line);
+ }
+ if (!matcher.matches()) {
+ return null;
+ }
+ SystemServicesTimingItem item = new SystemServicesTimingItem();
+ item.setComponent(matcher.group("componentname").trim());
+ item.setSubcomponent(matcher.group("subname").trim());
+ if (durationMatched) {
+ item.setDuration(Double.parseDouble(matcher.group("time")));
+ } else {
+ item.setStartTime(Double.parseDouble(matcher.group("time")));
+ }
+ return item;
+ }
+}