gecko-dev/build/mobile/robocop/StructuredLogger.java

189 строки
6.0 KiB
Java

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko;
import java.util.HashSet;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.json.JSONObject;
// This implements the structured logging API described here: http://mozbase.readthedocs.org/en/latest/mozlog_structured.html
public class StructuredLogger {
private final static HashSet<String> validTestStatus = new HashSet<String>(Arrays.asList("PASS", "FAIL", "TIMEOUT", "NOTRUN", "ASSERT"));
private final static HashSet<String> validTestEnd = new HashSet<String>(Arrays.asList("PASS", "FAIL", "OK", "ERROR", "TIMEOUT",
"CRASH", "ASSERT", "SKIP"));
private String mName;
private String mComponent;
private LoggerCallback mCallback;
static public interface LoggerCallback {
public void call(String output);
}
/* A default logger callback that prints the JSON output to stdout.
* This is not to be used in robocop as we write to a log file. */
static class StandardLoggerCallback implements LoggerCallback {
public void call(String output) {
System.out.println(output);
}
}
public StructuredLogger(String name, String component, LoggerCallback callback) {
mName = name;
mComponent = component;
mCallback = callback;
}
public StructuredLogger(String name, String component) {
this(name, component, new StandardLoggerCallback());
}
public StructuredLogger(String name, LoggerCallback callback) {
this(name, null, callback);
}
public StructuredLogger(String name) {
this(name, null, new StandardLoggerCallback());
}
public void suiteStart(List<String> tests, Map<String, Object> runInfo) {
HashMap<String, Object> data = new HashMap<String, Object>();
data.put("tests", tests);
if (runInfo != null) {
data.put("run_info", runInfo);
}
this.logData("suite_start", data);
}
public void suiteStart(List<String> tests) {
this.suiteStart(tests, null);
}
public void suiteEnd() {
this.logData("suite_end");
}
public void testStart(String test) {
HashMap<String, Object> data = new HashMap<String, Object>();
data.put("test", test);
this.logData("test_start", data);
}
public void testStatus(String test, String subtest, String status, String expected, String message) {
status = status.toUpperCase();
if (!StructuredLogger.validTestStatus.contains(status)) {
throw new IllegalArgumentException("Unrecognized status: " + status);
}
HashMap<String, Object> data = new HashMap<String, Object>();
data.put("test", test);
data.put("subtest", subtest);
data.put("status", status);
if (message != null) {
data.put("message", message);
}
if (!expected.equals(status)) {
data.put("expected", expected);
}
this.logData("test_status", data);
}
public void testStatus(String test, String subtest, String status, String message) {
this.testStatus(test, subtest, status, "PASS", message);
}
public void testEnd(String test, String status, String expected, String message, Map<String, Object> extra) {
status = status.toUpperCase();
if (!StructuredLogger.validTestEnd.contains(status)) {
throw new IllegalArgumentException("Unrecognized status: " + status);
}
HashMap<String, Object> data = new HashMap<String, Object>();
data.put("test", test);
data.put("status", status);
if (message != null) {
data.put("message", message);
}
if (extra != null) {
data.put("extra", extra);
}
if (!expected.equals(status) && !status.equals("SKIP")) {
data.put("expected", expected);
}
this.logData("test_end", data);
}
public void testEnd(String test, String status, String expected, String message) {
this.testEnd(test, status, expected, message, null);
}
public void testEnd(String test, String status, String message) {
this.testEnd(test, status, "OK", message, null);
}
public void debug(String message) {
this.log("debug", message);
}
public void info(String message) {
this.log("info", message);
}
public void warning(String message) {
this.log("warning", message);
}
public void error(String message) {
this.log("error", message);
}
public void critical(String message) {
this.log("critical", message);
}
private void log(String level, String message) {
HashMap<String, Object> data = new HashMap<String, Object>();
data.put("message", message);
data.put("level", level);
this.logData("log", data);
}
private HashMap<String, Object> makeLogData(String action, Map<String, Object> data) {
HashMap<String, Object> allData = new HashMap<String, Object>();
allData.put("action", action);
allData.put("time", System.currentTimeMillis());
allData.put("thread", JSONObject.NULL);
allData.put("pid", JSONObject.NULL);
allData.put("source", mName);
if (mComponent != null) {
allData.put("component", mComponent);
}
allData.putAll(data);
return allData;
}
private void logData(String action, Map<String, Object> data) {
HashMap<String, Object> logData = this.makeLogData(action, data);
JSONObject jsonObject = new JSONObject(logData);
mCallback.call(jsonObject.toString());
}
private void logData(String action) {
this.logData(action, new HashMap<String, Object>());
}
}