ACRA analyzer enhanced

This commit is contained in:
serso 2014-09-20 11:02:51 +02:00
parent 0a5bf4d9c3
commit e0ff803442
2 changed files with 114 additions and 35 deletions

View File

@ -0,0 +1,24 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Acra Analyzer" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.solovyev.acraanalyzer.AcraAnalyzer" />
<option name="VM_PARAMETERS" value="" />
<option name="PROGRAM_PARAMETERS" value="--file=$USER_HOME$/downloads/cpp/mails.mbox --out=./acra.txt" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" value="" />
<option name="ENABLE_SWING_INSPECTOR" value="false" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<module name="core" />
<envs />
<RunnerSettings RunnerId="Debug">
<option name="DEBUG_PORT" value="" />
<option name="TRANSPORT" value="0" />
<option name="LOCAL" value="true" />
</RunnerSettings>
<RunnerSettings RunnerId="Run" />
<ConfigurationWrapper RunnerId="Debug" />
<ConfigurationWrapper RunnerId="Run" />
<method />
</configuration>
</component>

View File

@ -23,16 +23,16 @@
package org.solovyev.acraanalyzer; package org.solovyev.acraanalyzer;
import org.apache.commons.cli.*; import org.apache.commons.cli.*;
import org.solovyev.common.text.Strings;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.util.*; import java.util.*;
import static org.solovyev.common.collections.Collections.getFirstCollectionElement; import static org.solovyev.common.collections.Collections.getFirstCollectionElement;
import static org.solovyev.common.text.Strings.isEmpty;
/** /**
* User: serso * User: serso
@ -43,22 +43,41 @@ public final class AcraAnalyzer {
private static final String NEW_LINE = System.getProperty("line.separator"); private static final String NEW_LINE = System.getProperty("line.separator");
public static void main(String[] args) throws ParseException { public static void main(String[] args) throws ParseException, FileNotFoundException {
final Options options = new Options(); final Options options = new Options();
options.addOption("path", true, "Path to the ACRA reports"); options.addOption("path", true, "Path to the ACRA reports");
options.addOption("file", true, "File name of MBOX file");
options.addOption("version", true, "Version of the app"); options.addOption("version", true, "Version of the app");
options.addOption("out", true, "Output file");
final CommandLineParser parser = new GnuParser(); final CommandLineParser parser = new GnuParser();
final CommandLine cmd = parser.parse(options, args); final CommandLine cmd = parser.parse(options, args);
final String path = cmd.getOptionValue("path"); final String path = cmd.getOptionValue("path");
final String file = cmd.getOptionValue("file");
final String version = cmd.getOptionValue("version"); final String version = cmd.getOptionValue("version");
final String out = cmd.getOptionValue("out");
if (Strings.isEmpty(path)) { if (isEmpty(path) && isEmpty(file)) {
throw new IllegalArgumentException("Path should be specified"); throw new IllegalArgumentException("Either path or filename should be specified");
} else if (!isEmpty(path) && !isEmpty(file)) {
throw new IllegalArgumentException("Specify either path or filename");
} else { } else {
final Map<String, List<AcraReport>> reports = new HashMap<String, List<AcraReport>>(); final Map<String, List<AcraReport>> reports = new HashMap<String, List<AcraReport>>();
scanFiles(path, reports, version); if (!isEmpty(path)) {
scanFiles(path, reports, version);
} else {
scanMbox(file, reports, version);
}
PrintStream outIs;
if(!isEmpty(out)) {
final File outFile = new File(out);
outIs = new PrintStream(outFile);
System.out.println("Output will be written to " + outFile.getPath());
} else {
outIs = System.out;
}
final List<List<AcraReport>> sortedReports = new ArrayList<List<AcraReport>>(reports.size()); final List<List<AcraReport>> sortedReports = new ArrayList<List<AcraReport>>(reports.size());
for (Map.Entry<String, List<AcraReport>> entry : reports.entrySet()) { for (Map.Entry<String, List<AcraReport>> entry : reports.entrySet()) {
@ -78,11 +97,36 @@ public final class AcraAnalyzer {
} }
}); });
for (Collection<AcraReport> sortedReport : sortedReports) { if (!sortedReports.isEmpty()) {
final AcraReport report = getFirstCollectionElement(sortedReport); for (Collection<AcraReport> sortedReport : sortedReports) {
System.out.println("Count: " + sortedReport.size()); final AcraReport report = getFirstCollectionElement(sortedReport);
System.out.println("App version: " + report.appVersion); outIs.println("Count: " + sortedReport.size());
System.out.println("Stack trace: " + report.stackTrace); outIs.println("App version: " + report.appVersion);
outIs.println("Stack trace: " + report.stackTrace);
}
} else {
outIs.println("No ACRA reports found");
}
}
}
private static void scanMbox(@Nonnull String filename, @Nonnull Map<String, List<AcraReport>> reports, @Nullable String version) {
final File file = new File(filename);
if (!file.isDirectory()) {
Scanner scanner = null;
try {
scanner = new Scanner(file);
while (scanner.hasNextLine()) {
final AcraReport report = readReport(scanner);
putReport(reports, report, version);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (scanner != null) {
scanner.close();
}
} }
} }
} }
@ -109,7 +153,11 @@ public final class AcraAnalyzer {
private static void analyzeFile(File file, Map<String, List<AcraReport>> reports, @Nullable String version) { private static void analyzeFile(File file, Map<String, List<AcraReport>> reports, @Nullable String version) {
final AcraReport report = readReport(file); final AcraReport report = readReport(file);
if (!Strings.isEmpty(report.stackTrace) && (version == null || version.equals(report.appVersion))) { putReport(reports, report, version);
}
private static void putReport(@Nonnull Map<String, List<AcraReport>> reports, @Nonnull AcraReport report, @Nullable String version) {
if (!isEmpty(report.stackTrace) && (version == null || version.equals(report.appVersion))) {
List<AcraReport> acraReports = reports.get(report.stackTrace); List<AcraReport> acraReports = reports.get(report.stackTrace);
if (acraReports == null) { if (acraReports == null) {
acraReports = new ArrayList<AcraReport>(); acraReports = new ArrayList<AcraReport>();
@ -119,30 +167,12 @@ public final class AcraAnalyzer {
} }
} }
private static AcraReport readReport(File file) { private static AcraReport readReport(@Nonnull File file) {
final AcraReport result = new AcraReport();
Scanner scanner = null; Scanner scanner = null;
try { try {
scanner = new Scanner(file); scanner = new Scanner(file);
while (scanner.hasNextLine()) { return readReport(scanner);
final String line = scanner.nextLine();
if (line.startsWith("STACK_TRACE")) {
result.stackTrace = readStackTrace(line.substring("STACK_TRACE=".length()), scanner);
break;
} else if (line.startsWith("ANDROID_VERSION")) {
result.androidVersion = line.substring("ANDROID_VERSION=".length());
} else if (line.startsWith("APP_VERSION_NAME")) {
result.appVersion = line.substring("APP_VERSION_NAME=".length());
} else if (line.startsWith("BRAND")) {
result.brand = line.substring("BRAND=".length());
} else if (line.startsWith("USER_COMMENT")) {
result.userComment = line.substring("USER_COMMENT=".length());
} else if (line.startsWith("PHONE_MODEL")) {
result.phoneModel = line.substring("PHONE_MODEL=".length());
}
}
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
e.printStackTrace(); e.printStackTrace();
} finally { } finally {
@ -151,6 +181,31 @@ public final class AcraAnalyzer {
} }
} }
return new AcraReport();
}
@Nonnull
private static AcraReport readReport(@Nonnull Scanner scanner) {
final AcraReport result = new AcraReport();
while (scanner.hasNextLine()) {
final String line = scanner.nextLine();
if (line.startsWith("STACK_TRACE")) {
result.stackTrace = readStackTrace(line.substring("STACK_TRACE=".length()), scanner);
break;
} else if (line.startsWith("ANDROID_VERSION")) {
result.androidVersion = line.substring("ANDROID_VERSION=".length());
} else if (line.startsWith("APP_VERSION_NAME")) {
result.appVersion = line.substring("APP_VERSION_NAME=".length());
} else if (line.startsWith("BRAND")) {
result.brand = line.substring("BRAND=".length());
} else if (line.startsWith("USER_COMMENT")) {
result.userComment = line.substring("USER_COMMENT=".length());
} else if (line.startsWith("PHONE_MODEL")) {
result.phoneModel = line.substring("PHONE_MODEL=".length());
}
}
return result; return result;
} }
@ -160,10 +215,10 @@ public final class AcraAnalyzer {
while (scanner.hasNextLine()) { while (scanner.hasNextLine()) {
final String line = scanner.nextLine().trim(); final String line = scanner.nextLine().trim();
if (line.startsWith("at")) { if (isEmpty(line)) {
sb.append(line).append(newLine());
} else {
break; break;
} else {
sb.append(line).append(newLine());
} }
} }