• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.loganalysis.parser;
17 
18 import com.android.loganalysis.item.SmartMonkeyLogItem;
19 
20 import java.io.BufferedReader;
21 import java.io.IOException;
22 import java.text.ParseException;
23 import java.text.SimpleDateFormat;
24 import java.util.Date;
25 import java.util.List;
26 import java.util.regex.Matcher;
27 import java.util.regex.Pattern;
28 
29 /**
30  * A {@link IParser} to parse monkey logs.
31  */
32 public class SmartMonkeyLogParser implements IParser {
33 
34     private static final String TIME_STAMP_GROUP =
35             "^(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}.\\d{3}): ";
36     private static final String INVOKE_NUM_GROUP = "\\[.*?(\\d+)\\]";
37     private static final String SEQ_NUM_GROUP = "\\(Seq:.*?(\\d+)\\)";
38 
39     private static final Pattern START_TIME = Pattern.compile(
40             TIME_STAMP_GROUP + "Starting.*");
41 
42     private static final Pattern START_UPTIME = Pattern.compile(
43             TIME_STAMP_GROUP + "Device uptime: (\\d+) sec$");
44 
45     private static final Pattern STOP_UPTIME = Pattern.compile(
46             TIME_STAMP_GROUP + "Device uptime: (\\d+) sec, Monkey run duration: (\\d+) sec$");
47 
48     private static final Pattern THROTTLE = Pattern.compile(
49             TIME_STAMP_GROUP + "Throttle: (\\d+).*");
50 
51     private static final Pattern TARGET_INVOCATIONS = Pattern.compile(
52             TIME_STAMP_GROUP + "Target invocation count: (\\d+)");
53 
54     private static final Pattern INTERMEDIATE_COUNT = Pattern.compile(
55             TIME_STAMP_GROUP + INVOKE_NUM_GROUP + SEQ_NUM_GROUP + ".*");
56 
57     private static final Pattern INTERMEDIATE_TIME = Pattern.compile(TIME_STAMP_GROUP + ".*");
58 
59     private static final Pattern FINISHED = Pattern.compile(
60             TIME_STAMP_GROUP + "Monkey finished");
61 
62     private static final Pattern FINAL_COUNT = Pattern.compile(
63             TIME_STAMP_GROUP + "Invocations completed: (\\d+)");
64 
65     private static final Pattern APPS_PACKAGES = Pattern.compile(
66             TIME_STAMP_GROUP + "Starting \\[(.*)\\]\\[(.*)\\]");
67 
68     private static final Pattern ABORTED = Pattern.compile(
69             TIME_STAMP_GROUP + "Monkey aborted.");
70 
71     private static final Pattern UI_ANR = Pattern.compile(
72             TIME_STAMP_GROUP + INVOKE_NUM_GROUP + SEQ_NUM_GROUP + "-UI Exception: ANR: (.*)");
73 
74     private static final Pattern UI_CRASH = Pattern.compile(
75             TIME_STAMP_GROUP + INVOKE_NUM_GROUP + SEQ_NUM_GROUP + "-UI Exception: CRASH: (.*)");
76 
77     private final SmartMonkeyLogItem mSmartMonkeyLog = new SmartMonkeyLogItem();
78 
79     /**
80      * Parse a monkey log from a {@link BufferedReader} into an {@link SmartMonkeyLogItem}
81      * object.
82      *
83      * @param input a {@link BufferedReader}.
84      * @return The {@link SmartMonkeyLogItem}.
85      * @see #parse(List)
86      */
parse(BufferedReader input)87     public SmartMonkeyLogItem parse(BufferedReader input) throws IOException {
88         String line;
89         while ((line = input.readLine()) != null) {
90             parseLine(line);
91         }
92         return mSmartMonkeyLog;
93     }
94 
95     /**
96      * {@inheritDoc}
97      *
98      * @return The {@link SmartMonkeyLogItem}.
99      */
100     @Override
parse(List<String> lines)101     public SmartMonkeyLogItem parse(List<String> lines) {
102         for (String line : lines) {
103             parseLine(line);
104         }
105 
106         if (mSmartMonkeyLog.getStopUptimeDuration() == 0)
107             mSmartMonkeyLog.setIsFinished(false);
108         else
109             mSmartMonkeyLog.setIsFinished(true);
110 
111         return mSmartMonkeyLog;
112     }
113 
114     /**
115      * Parse a line of input.
116      */
parseLine(String line)117     private void parseLine(String line) {
118         Matcher m = THROTTLE.matcher(line);
119         if (m.matches()) {
120             mSmartMonkeyLog.setThrottle(Integer.parseInt(m.group(2)));
121         }
122         m = TARGET_INVOCATIONS.matcher(line);
123         if (m.matches()) {
124             mSmartMonkeyLog.setTargetInvocations(Integer.parseInt(m.group(2)));
125         }
126         m = APPS_PACKAGES.matcher(line);
127         if (m.matches()) {
128             String apps = m.group(2);
129             String packages = m.group(3);
130 
131             String[] appsArray = apps.split("\\|");
132             for (String a : appsArray) {
133                 mSmartMonkeyLog.addApplication(a);
134             }
135 
136             String[] pkgsArray = packages.split("\\|");
137             for (String p : pkgsArray) {
138                 mSmartMonkeyLog.addPackage(p);
139             }
140         }
141         m = INTERMEDIATE_COUNT.matcher(line);
142         if (m.matches()) {
143             mSmartMonkeyLog.setIntermediateCount(Integer.parseInt(m.group(2)));
144         }
145         m = START_TIME.matcher(line);
146         if (m.matches()) {
147             mSmartMonkeyLog.setStartTime(parseTime(m.group(1)));
148         }
149         m = START_UPTIME.matcher(line);
150         if (m.matches()) {
151             mSmartMonkeyLog.setStartUptimeDuration(Long.parseLong(m.group(2)));
152         }
153         m = STOP_UPTIME.matcher(line);
154         if (m.matches()) {
155             mSmartMonkeyLog.setStopTime(parseTime(m.group(1)));
156             mSmartMonkeyLog.setStopUptimeDuration(Long.parseLong(m.group(2)));
157             mSmartMonkeyLog.setTotalDuration(Long.parseLong(m.group(3)));
158         }
159         m = INTERMEDIATE_TIME.matcher(line);
160         if (m.matches()) {
161             mSmartMonkeyLog.setIntermediateTime(parseTime(m.group(1)));
162         }
163         m = FINAL_COUNT.matcher(line);
164         if (m.matches()) {
165             mSmartMonkeyLog.setFinalCount(Integer.parseInt(m.group(2)));
166         }
167         m = FINISHED.matcher(line);
168         if (m.matches()) {
169             mSmartMonkeyLog.setIsFinished(true);
170         }
171         m = ABORTED.matcher(line);
172         if (m.matches()) {
173             mSmartMonkeyLog.setIsAborted(true);
174         }
175         m = UI_CRASH.matcher(line);
176         if (m.matches()) {
177             mSmartMonkeyLog.addCrashTime(parseTime(m.group(1)));
178         }
179         m = UI_ANR.matcher(line);
180         if (m.matches()) {
181             mSmartMonkeyLog.addAnrTime(parseTime(m.group(1)));
182         }
183     }
184 
185     /**
186      * Parse the timestamp and return a date.
187      *
188      * @param timeStr The timestamp in the format {@code yyyy-MM-dd HH:mm:ss.SSS}
189      * @return The {@link Date}.
190      */
parseTime(String timeStr)191     public static Date parseTime(String timeStr) {
192         try {
193             return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse(timeStr);
194         } catch (ParseException e) {
195         }
196         return null;
197     }
198 
199 }
200