From c7bcaba872c7d82286960c750edd67e56ee73712 Mon Sep 17 00:00:00 2001 From: Kimberly Kreider Date: Thu, 14 Nov 2019 15:11:53 -0800 Subject: DO NOT MERGE: Adding required loganalysis changes for tradefed merge into qt-dev. Bug: 143908003 Change-Id: Ib3436a42b2ca8c9614939a30fb548ab39bc23e57 Exclude merging into *-plus-aosp branches, since they already include the change. Merged-In: I2ae86ba9706747873268192988c32879005ed0f7 Merged-In: I38efc115f2c691754d481fdffb6630607ef970e8 --- .../loganalysis/item/DmesgActionInfoItem.java | 28 ++- .../loganalysis/item/GenericTimingItem.java | 79 +++++++ .../loganalysis/item/SystemServicesTimingItem.java | 84 +++++++ .../android/loganalysis/parser/DmesgParser.java | 21 +- .../loganalysis/parser/TimingsLogParser.java | 246 +++++++++++++++++++++ 5 files changed, 441 insertions(+), 17 deletions(-) create mode 100644 src/com/android/loganalysis/item/GenericTimingItem.java create mode 100644 src/com/android/loganalysis/item/SystemServicesTimingItem.java create mode 100644 src/com/android/loganalysis/parser/TimingsLogParser.java (limited to 'src/com/android/loganalysis') diff --git a/src/com/android/loganalysis/item/DmesgActionInfoItem.java b/src/com/android/loganalysis/item/DmesgActionInfoItem.java index ac73b8e..482b426 100644 --- a/src/com/android/loganalysis/item/DmesgActionInfoItem.java +++ b/src/com/android/loganalysis/item/DmesgActionInfoItem.java @@ -26,13 +26,15 @@ import java.util.Set; */ public class DmesgActionInfoItem extends GenericItem { + /** Constant for JSON output */ + public static final String SOURCE_NAME = "SOURCE_NAME"; /** Constant for JSON output */ public static final String ACTION_NAME = "ACTION_NAME"; /** Constant for JSON output */ public static final String ACTION_START_TIME = "ACTION_START_TIME"; private static final Set ATTRIBUTES = new HashSet(Arrays.asList( - ACTION_NAME, ACTION_START_TIME)); + SOURCE_NAME, ACTION_NAME, ACTION_START_TIME)); /** * The constructor for {@link DmesgActionInfoItem}. @@ -44,12 +46,27 @@ public class DmesgActionInfoItem extends GenericItem { /** * The constructor for {@link DmesgActionInfoItem}. */ - public DmesgActionInfoItem(String name, Long startTime) { + public DmesgActionInfoItem(String source, String name, Long startTime) { super(ATTRIBUTES); + setAttribute(SOURCE_NAME, source); setAttribute(ACTION_NAME, name); setAttribute(ACTION_START_TIME, startTime); } + /** + * Get the name of the source + */ + public String getSourceName() { + return (String) getAttribute(SOURCE_NAME); + } + + /** + * Set the name of the source + */ + public void setSourceName(String sourceName) { + setAttribute(SOURCE_NAME, sourceName); + } + /** * Get the name of the action */ @@ -80,8 +97,11 @@ public class DmesgActionInfoItem extends GenericItem { @Override public String toString() { - return "ActionInfoItem [getActionName()=" + getActionName() + ", getStartTime()=" - + getStartTime() + "]"; + return "ActionInfoItem [" + + "getSourceName()=" + getSourceName() + + ", getActionName()=" + getActionName() + + ", getStartTime()=" + getStartTime() + + "]"; } } diff --git a/src/com/android/loganalysis/item/GenericTimingItem.java b/src/com/android/loganalysis/item/GenericTimingItem.java new file mode 100644 index 0000000..088d15b --- /dev/null +++ b/src/com/android/loganalysis/item/GenericTimingItem.java @@ -0,0 +1,79 @@ +/* + * 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.item; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +public class GenericTimingItem extends GenericItem { + /** Constant for JSON output */ + public static final String NAME = "NAME"; + /** Constant for JSON output */ + public static final String START_TIME = "START_TIME"; + /** Constant for JSON output */ + public static final String END_TIME = "END_TIME"; + + private static final Set ATTRIBUTES = + new HashSet<>(Arrays.asList(NAME, END_TIME, START_TIME)); + + public GenericTimingItem() { + super(ATTRIBUTES); + } + + protected GenericTimingItem(Set attributes) { + super(getAllAttributes(attributes)); + } + + /** Get the name of the generic timing item */ + public String getName() { + return (String) getAttribute(NAME); + } + + /** Set the name of the generic timing item */ + public void setName(String name) { + setAttribute(NAME, name); + } + + /** Get the duration value for the generic timing, it is timestamp in milliseconds */ + public Double getDuration() { + return (Double) getAttribute(END_TIME) - (Double) getAttribute(START_TIME); + } + + /** Get the start time value for the generic timing, it is timestamp in milliseconds */ + public Double getStartTime() { + return (Double) getAttribute(START_TIME); + } + + /** Get the end time value for the generic timing, it is timestamp in milliseconds */ + public Double getEndTime() { + return (Double) getAttribute(END_TIME); + } + + /** Set the start and end time value for the generic timing, it is timestamp in milliseconds */ + public void setStartAndEnd(double startTime, double endTime) { + setAttribute(START_TIME, startTime); + setAttribute(END_TIME, endTime); + } + + /** Combine an array of attributes with the internal list of attributes. */ + private static Set getAllAttributes(Set attributes) { + Set allAttributes = new HashSet(ATTRIBUTES); + allAttributes.addAll(attributes); + return allAttributes; + } +} diff --git a/src/com/android/loganalysis/item/SystemServicesTimingItem.java b/src/com/android/loganalysis/item/SystemServicesTimingItem.java new file mode 100644 index 0000000..79671a2 --- /dev/null +++ b/src/com/android/loganalysis/item/SystemServicesTimingItem.java @@ -0,0 +1,84 @@ +/* + * 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.item; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * An {@link IItem} used to store timing information for system services like System Server, Zygote, + * System UI, BootAnimation e.t.c. + */ +public class SystemServicesTimingItem extends GenericItem { + /** Constant for JSON output */ + public static final String COMPONENT = "COMPONENT"; + /** Constant for JSON output */ + public static final String SUBCOMPONENT = "SUBCOMPONENT"; + /** Constant for JSON output */ + public static final String DURATION = "DURATION"; + /** Constant for JSON output */ + public static final String START_TIME = "START_TIME"; + + private static final Set ATTRIBUTES = + new HashSet<>(Arrays.asList(COMPONENT, SUBCOMPONENT, DURATION, START_TIME)); + + /** Constructor for {@link SystemServicesTimingItem} */ + public SystemServicesTimingItem() { + super(ATTRIBUTES); + } + + /** Get the component name for system services timing */ + public String getComponent() { + return (String) getAttribute(COMPONENT); + } + + /** Set the component name for system service timing */ + public void setComponent(String component) { + setAttribute(COMPONENT, component); + } + + /** Get the sub-component name for system service timing */ + public String getSubcomponent() { + return (String) getAttribute(SUBCOMPONENT); + } + + /** Set the sub-component name for system service timing */ + public void setSubcomponent(String subcomponent) { + setAttribute(SUBCOMPONENT, subcomponent); + } + + /** Get the duration value for system service timing */ + public Double getDuration() { + return (Double) getAttribute(DURATION); + } + + /** Set the duration value for system service timing */ + public void setDuration(double duration) { + setAttribute(DURATION, duration); + } + + /** Get the start time value for system service timing */ + public Double getStartTime() { + return (Double) getAttribute(START_TIME); + } + + /** Set the start time value for system service timing */ + public void setStartTime(double startTime) { + setAttribute(START_TIME, startTime); + } +} diff --git a/src/com/android/loganalysis/parser/DmesgParser.java b/src/com/android/loganalysis/parser/DmesgParser.java index be292ff..9fce9b8 100644 --- a/src/com/android/loganalysis/parser/DmesgParser.java +++ b/src/com/android/loganalysis/parser/DmesgParser.java @@ -40,6 +40,7 @@ public class DmesgParser implements IParser { private static final String TIMESTAMP = "TIMESTAMP"; private static final String STAGE = "STAGE"; private static final String ACTION = "ACTION"; + private static final String SOURCE = "SOURCE"; private static final String DURATION = "DURATION"; private static final String UEVENTD = "ueventd"; private static final String INIT = "init"; @@ -74,21 +75,13 @@ public class DmesgParser implements IParser { // Matches: init: processing action (early-init) from (/init.rc:14) private static final String START_PROCESSING_ACTION_PREFIX = - String.format("processing action \\((?<%s>.*)\\) from.*$", ACTION); - - // Matches: init: processing action (early-init) - private static final String START_PROCESSING_ACTION_PREFIX_LEGACY = - String.format("processing action \\((?<%s>.*)\\).*$", ACTION); + String.format("processing action \\((?<%s>[^)]*)\\)( from \\((?<%s>.*)\\)|.*)$", + ACTION, SOURCE); // Matches: init: processing action (early-init) from (/init.rc:14) private static final Pattern START_PROCESSING_ACTION = Pattern.compile(String.format("%s%s", SERVICE_PREFIX, START_PROCESSING_ACTION_PREFIX)); - // Matches: init: processing action (early-init) - private static final Pattern START_PROCESSING_ACTION_LEGACY = - Pattern.compile( - String.format("%s%s", SERVICE_PREFIX, START_PROCESSING_ACTION_PREFIX_LEGACY)); - // Matches: [ 3.791635] ueventd: Coldboot took 0.695055 seconds private static final String STAGE_SUFFIX= String.format( "(?<%s>.*)\\s+took\\s+(?<%s>.*)\\s+seconds$", STAGE, DURATION); @@ -242,9 +235,11 @@ public class DmesgParser implements IParser { @VisibleForTesting boolean parseActionInfo(String line) { Matcher match = null; - if ((match = matches(START_PROCESSING_ACTION, line)) != null - || (match = matches(START_PROCESSING_ACTION_LEGACY, line)) != null) { + if ((match = matches(START_PROCESSING_ACTION, line)) != null) { DmesgActionInfoItem actionInfoItem = new DmesgActionInfoItem(); + if (match.group(SOURCE) != null) { + actionInfoItem.setSourceName(match.group(SOURCE)); + } actionInfoItem.setActionName(match.group(ACTION)); actionInfoItem.setStartTime((long) (Double.parseDouble( match.group(TIMESTAMP)) * 1000)); @@ -283,4 +278,4 @@ public class DmesgParser implements IParser { return mDmesgItem.getActionInfoItems(); } -} +} \ No newline at end of file diff --git a/src/com/android/loganalysis/parser/TimingsLogParser.java b/src/com/android/loganalysis/parser/TimingsLogParser.java new file mode 100644 index 0000000..ee3535f --- /dev/null +++ b/src/com/android/loganalysis/parser/TimingsLogParser.java @@ -0,0 +1,246 @@ +/* + * 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.GenericTimingItem; +import com.android.loganalysis.item.IItem; +import com.android.loganalysis.item.SystemServicesTimingItem; + +import java.io.BufferedReader; +import java.io.IOException; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +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. + * + */ +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*(?.*):\\s*(?\\S*)\\s*"; + private static final String SYSTEM_SERVICES_TIME_SUFFIX = ":\\s*(?