blob: a0a49a1ca5cc44c6a15caba05c535f68dbebdd4d [file] [log] [blame]
/*
* Copyright (C) 2013 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;
import com.android.loganalysis.item.BugreportItem;
import com.android.loganalysis.item.IItem;
import com.android.loganalysis.item.KernelLogItem;
import com.android.loganalysis.item.LogcatItem;
import com.android.loganalysis.item.MemoryHealthItem;
import com.android.loganalysis.item.MonkeyLogItem;
import com.android.loganalysis.parser.BugreportParser;
import com.android.loganalysis.parser.KernelLogParser;
import com.android.loganalysis.parser.LogcatParser;
import com.android.loganalysis.parser.MemoryHealthParser;
import com.android.loganalysis.parser.MonkeyLogParser;
import com.android.loganalysis.rule.RuleEngine;
import com.android.loganalysis.rule.RuleEngine.RuleType;
import com.android.loganalysis.util.config.ArgsOptionParser;
import com.android.loganalysis.util.config.ConfigurationException;
import com.android.loganalysis.util.config.Option;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* A command line tool to parse a bugreport, logcat, or kernel log file and return the output.
*/
public class LogAnalyzer {
private enum OutputFormat{
// TODO: Add text output support.
JSON;
}
private enum ResultType {
RAW, ANALYSIS;
}
@Option(name="bugreport", description="The path to the bugreport")
private String mBugreportPath = null;
@Option(name="logcat", description="The path to the logcat")
private String mLogcatPath = null;
@Option(name="kernel-log", description="The path to the kernel log")
private String mKernelLogPath = null;
@Option(name="monkey-log", description="The path to the monkey log")
private String mMonkeyLogPath = null;
@Option(name="memory-health", description="The path to the memory health log")
private String mMemoryHealthLogPath = null;
@Option(name="output", description="The output format, currently only JSON")
private OutputFormat mOutputFormat = OutputFormat.JSON;
@Option(name="rule-type", description="The type of rules to be applied")
private RuleType mRuleType = RuleType.ALL;
@Option(name="print", description="Print the result type")
private List<ResultType> mResultType = new ArrayList<ResultType>();
/** Constant for JSON output */
private static final String RAW_DATA = "RAW";
/** Constant for JSON output */
private static final String ANALYSIS_DATA = "ANALYSIS";
/**
* Run the command line tool
*/
public void run(String[] args) {
try {
initArgs(args);
} catch (ConfigurationException e) {
printUsage();
return;
}
if (!checkPreconditions()) {
printUsage();
return;
}
BufferedReader reader = null;
try {
if (mBugreportPath != null) {
reader = getBufferedReader(mBugreportPath);
BugreportItem bugreport = new BugreportParser().parse(reader);
printBugreport(bugreport);
return;
}
if (mLogcatPath != null) {
reader = getBufferedReader(mLogcatPath);
LogcatItem logcat = new LogcatParser().parse(reader);
printLogcat(logcat);
return;
}
if (mKernelLogPath != null) {
reader = getBufferedReader(mKernelLogPath);
KernelLogItem kernelLog = new KernelLogParser().parse(reader);
printKernelLog(kernelLog);
return;
}
if (mMonkeyLogPath != null) {
reader = getBufferedReader(mMonkeyLogPath);
MonkeyLogItem monkeyLog = new MonkeyLogParser().parse(reader);
printMonkeyLog(monkeyLog);
return;
}
if (mMemoryHealthLogPath != null) {
reader = getBufferedReader(mMemoryHealthLogPath);
MemoryHealthItem item = new MemoryHealthParser().parse(reader);
printMemoryHealthLog(item);
return;
}
} catch (FileNotFoundException e) {
System.err.println(e.getMessage());
} catch (IOException e) {
System.err.println(e.getMessage());
} finally {
close(reader);
}
// Should never reach here.
printUsage();
}
private void printMemoryHealthLog(MemoryHealthItem item) {
System.out.println(item.toJson().toString());
}
/**
* Print the bugreport to stdout.
*/
private void printBugreport(BugreportItem bugreport) {
if (OutputFormat.JSON.equals(mOutputFormat)) {
if (mResultType.size() == 0) {
printJson(bugreport);
} else if (mResultType.size() == 1) {
switch (mResultType.get(0)) {
case RAW:
printJson(bugreport);
break;
case ANALYSIS:
printBugreportAnalysis(getBugreportAnalysis(bugreport));
break;
default:
// should not get here
return;
}
} else {
JSONObject result = new JSONObject();
try {
for (ResultType resultType : mResultType) {
switch (resultType) {
case RAW:
result.put(RAW_DATA, bugreport.toJson());
break;
case ANALYSIS:
result.put(ANALYSIS_DATA, getBugreportAnalysis(bugreport));
break;
default:
// should not get here
break;
}
}
} catch (JSONException e) {
// Ignore
}
printJson(result);
}
}
}
private JSONArray getBugreportAnalysis(BugreportItem bugreport) {
RuleEngine ruleEngine = new RuleEngine(bugreport);
ruleEngine.registerRules(mRuleType);
ruleEngine.executeRules();
if (ruleEngine.getAnalysis() != null) {
return ruleEngine.getAnalysis();
} else {
return new JSONArray();
}
}
private void printBugreportAnalysis(JSONArray analysis) {
if (analysis != null && analysis.length() > 0) {
System.out.println(analysis.toString());
} else {
System.out.println(new JSONObject().toString());
}
}
/**
* Print the logcat to stdout.
*/
private void printLogcat(LogcatItem logcat) {
if (OutputFormat.JSON.equals(mOutputFormat)) {
printJson(logcat);
}
// TODO: Print logcat in human readable form.
}
/**
* Print the kernel log to stdout.
*/
private void printKernelLog(KernelLogItem kernelLog) {
if (OutputFormat.JSON.equals(mOutputFormat)) {
printJson(kernelLog);
}
// TODO: Print kernel log in human readable form.
}
/**
* Print the monkey log to stdout.
*/
private void printMonkeyLog(MonkeyLogItem monkeyLog) {
if (OutputFormat.JSON.equals(mOutputFormat)) {
printJson(monkeyLog);
}
// TODO: Print monkey log in human readable form.
}
/**
* Print an {@link IItem} to stdout.
*/
private void printJson(IItem item) {
if (item != null && item.toJson() != null) {
printJson(item.toJson());
} else {
printJson(new JSONObject());
}
}
/**
* Print an {@link JSONObject} to stdout
*/
private void printJson(JSONObject json) {
if (json != null) {
System.out.println(json.toString());
} else {
System.out.println(new JSONObject().toString());
}
}
/**
* Get a {@link BufferedReader} from a given filepath.
* @param filepath the path to the file.
* @return The {@link BufferedReader} containing the contents of the file.
* @throws FileNotFoundException if the file could not be found.
*/
private BufferedReader getBufferedReader(String filepath) throws FileNotFoundException {
return new BufferedReader(new FileReader(new File(filepath)));
}
/**
* Helper to close a {@link Closeable}.
*/
private void close(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException e) {
// Ignore
}
}
}
/**
* Parse the command line options and set {@link Option} annotated fields.
*/
private void initArgs(String[] args) throws ConfigurationException {
ArgsOptionParser opt = new ArgsOptionParser(this);
opt.parse(args);
}
/**
* Checks the arguments to see if they are valid.
*
* @return true if they are valid, false if they are not.
*/
private boolean checkPreconditions() {
// Check to see that exactly one log is set.
int logCount = 0;
if (mBugreportPath != null) logCount++;
if (mLogcatPath != null) logCount++;
if (mKernelLogPath != null) logCount++;
if (mMonkeyLogPath != null) logCount++;
if (mMemoryHealthLogPath != null) logCount++;
return (logCount == 1);
}
/**
* Print the usage for the command.
*/
private void printUsage() {
System.err.println("Usage: loganalysis [--bugreport FILE | --logcat FILE | " +
"--kernel-log FILE | --monkey-log FILE]");
}
/**
* Run the LogAnalyzer from the command line.
*/
public static void main(String[] args) {
LogAnalyzer analyzer = new LogAnalyzer();
analyzer.run(args);
}
}