1 /* 2 * Copyright (C) 2015 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.google.common.annotations.VisibleForTesting; 19 20 import com.android.loganalysis.item.DvmLockSampleItem; 21 22 import java.io.BufferedReader; 23 import java.io.IOException; 24 import java.util.ArrayList; 25 import java.util.Arrays; 26 import java.util.List; 27 import java.util.regex.Matcher; 28 import java.util.regex.Pattern; 29 30 /** 31 * A {@link IParser} to parse DVM lock sample allocation logs 32 */ 33 public class DvmLockSampleParser implements IParser { 34 35 private static final String NAME_REGEX = "([^,]+)"; 36 private static final String FILE_REGEX = "(-|[A-Za-z]+\\.[A-Za-z]+)"; 37 private static final String INT_REGEX = "(\\d+)"; 38 39 /** 40 * Matches the DVM lock sample log format: 41 * 42 * <p>09-04 05:40:07.809 1026 10592 I dvm_lock_sample: 43 * [system_server,1,Binder:1026_F,46,NetworkPolicyManagerService.java,2284,-,802,9] 44 */ 45 private static final Pattern LOG_CONTENTION_EVENT_PATTERN = 46 Pattern.compile( 47 "\\[" 48 + String.join( 49 ",\\s*", 50 Arrays.asList( 51 NAME_REGEX, // Process name 52 INT_REGEX, // Process sensitivity flag 53 NAME_REGEX, // Waiting thread name 54 INT_REGEX, // Wait time 55 FILE_REGEX, // Waiting Source File 56 INT_REGEX, // Waiting Source Line 57 FILE_REGEX, // Owner File Name ("-" if the same) 58 INT_REGEX, // Owner Acquire Source Line 59 INT_REGEX // Sample Percentage 60 )) 61 + "\\]"); 62 63 private DvmLockSampleItem mItem = new DvmLockSampleItem(); 64 65 /** 66 * Parse a dvm log from a {@link BufferedReader} into a {@link DvmLockSampleItem}. 67 * 68 * @return The {@link DvmLockSampleItem}. 69 * @see #parse(List) 70 */ 71 public DvmLockSampleItem parse(BufferedReader input) throws IOException { 72 List<String> lines = new ArrayList<>(); 73 74 for(String line = input.readLine(); line != null; line = input.readLine()) { 75 lines.add(line); 76 } 77 78 return parse(lines); 79 } 80 81 /** 82 * {@inheritDoc} 83 * 84 * @return The {@link DvmLockSampleItem}. 85 */ 86 @Override 87 public DvmLockSampleItem parse(List<String> lines) { 88 DvmLockSampleItem mItem = new DvmLockSampleItem(); 89 90 for (String line : lines) { 91 Matcher m = LOG_CONTENTION_EVENT_PATTERN.matcher(line); 92 93 if(m.matches()) { 94 mItem.setAttribute(DvmLockSampleItem.PROCESS_NAME, 95 m.group(1)); 96 97 mItem.setAttribute(DvmLockSampleItem.SENSITIVITY_FLAG, 98 1 == Integer.parseInt(m.group(2))); 99 100 mItem.setAttribute(DvmLockSampleItem.WAITING_THREAD_NAME, 101 m.group(3)); 102 103 mItem.setAttribute(DvmLockSampleItem.WAIT_TIME, 104 Integer.parseInt(m.group(4))); 105 106 mItem.setAttribute(DvmLockSampleItem.WAITING_SOURCE_FILE, 107 m.group(5)); 108 109 mItem.setAttribute(DvmLockSampleItem.WAITING_SOURCE_LINE, 110 Integer.parseInt(m.group(6))); 111 112 // If the owner file name is -, the dvm log format specification 113 // says that we should use the waiting source file. 114 mItem.setAttribute(DvmLockSampleItem.OWNER_FILE_NAME, 115 m.group(7).equals("-") ? m.group(5) : m.group(7)); 116 117 mItem.setAttribute(DvmLockSampleItem.OWNER_ACQUIRE_SOURCE_LINE, 118 Integer.parseInt(m.group(8))); 119 120 mItem.setAttribute(DvmLockSampleItem.SAMPLE_PERCENTAGE, 121 Integer.parseInt(m.group(9))); 122 } 123 } 124 125 System.out.println(mItem.toJson().toString()); 126 return mItem; 127 } 128 129 @VisibleForTesting 130 DvmLockSampleItem getItem() { 131 return mItem; 132 } 133 } 134