下面列出了怎么用org.apache.log4j.spi.ThrowableInformation的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public String format(LoggingEvent event) {
StringBuilder builder = new StringBuilder();
EcsJsonSerializer.serializeObjectStart(builder, event.getTimeStamp());
EcsJsonSerializer.serializeLogLevel(builder, event.getLevel().toString());
EcsJsonSerializer.serializeFormattedMessage(builder, event.getRenderedMessage());
EcsJsonSerializer.serializeServiceName(builder, serviceName);
EcsJsonSerializer.serializeEventDataset(builder, eventDataset);
EcsJsonSerializer.serializeThreadName(builder, event.getThreadName());
EcsJsonSerializer.serializeLoggerName(builder, event.getLoggerName());
EcsJsonSerializer.serializeMDC(builder, event.getProperties());
EcsJsonSerializer.serializeTag(builder, event.getNDC());
if (includeOrigin) {
LocationInfo locationInformation = event.getLocationInformation();
if (locationInformation != null) {
EcsJsonSerializer.serializeOrigin(builder, locationInformation.getFileName(), locationInformation.getMethodName(), getLineNumber(locationInformation));
}
}
ThrowableInformation throwableInformation = event.getThrowableInformation();
if (throwableInformation != null) {
EcsJsonSerializer.serializeException(builder, throwableInformation.getThrowable(), stackTraceAsArray);
}
EcsJsonSerializer.serializeObjectEnd(builder);
return builder.toString();
}
private String getLoggingMesage( LoggingEvent event ) {
Throwable throwable = null;
ThrowableInformation throwableInfo = event.getThrowableInformation();
if (throwableInfo != null && throwableInfo.getThrowable() != null) {
// logging through methods like error(new Exception);
throwable = throwableInfo.getThrowable();
} else if (event.getMessage() instanceof Throwable) {
// logging through methods like error("some message", new Exception);
throwable = (Throwable) event.getMessage();
}
// first format the message using the layout
String message = layout.format(event);
// then append the exception stack trace
if (throwable != null) {
message = getExceptionMsg(throwable, message);
}
return message;
}
@Test
public void testException() throws Throwable {
Exception e =
new NoRouteToHostException("that box caught fire 3 years ago");
ThrowableInformation ti = new ThrowableInformation(e);
Log4Json l4j = new Log4Json();
long timeStamp = Time.now();
String outcome = l4j.toJson(new StringWriter(),
"testException",
timeStamp,
"INFO",
"quoted\"",
"new line\n and {}",
ti)
.toString();
println("testException", outcome);
}
private String getThrowableStr(LoggingEvent event) {
ThrowableInformation throwable = event.getThrowableInformation();
if (throwable == null) {
return null;
}
StringBuilder sb = new StringBuilder();
boolean isFirst = true;
for (String s : throwable.getThrowableStrRep()) {
if (isFirst) {
isFirst = false;
} else {
sb.append(System.getProperty("line.separator"));
}
sb.append(s);
}
return sb.toString();
}
@Test
public void testException() throws Throwable {
Exception e =
new NoRouteToHostException("that box caught fire 3 years ago");
ThrowableInformation ti = new ThrowableInformation(e);
Log4Json l4j = new Log4Json();
long timeStamp = Time.now();
String outcome = l4j.toJson(new StringWriter(),
"testException",
timeStamp,
"INFO",
"quoted\"",
"new line\n and {}",
ti)
.toString();
println("testException", outcome);
}
@Override
protected void append(final LoggingEvent loggingEvent) {
final StringBuilder buf = new StringBuilder();
buf.append(getLayout().format(loggingEvent));
final ThrowableInformation ti = loggingEvent.getThrowableInformation();
if (ti != null) {
final String[] cause = ti.getThrowableStrRep();
for (final String line : cause) {
buf.append(line).append('\n');
}
}
j2DClient.get().addEventLine(new HeaderLessEventLine(buf.toString(), NotificationType.CLIENT));
}
@BeforeClass
public static void setupBeforeClass() throws Exception {
Logger xenqtt = Logger.getLogger("xenqtt");
assertNotNull(xenqtt);
Appender console = Logger.getRootLogger().getAppender("console");
assertNotNull(console);
console.addFilter(new Filter() {
@Override
public int decide(LoggingEvent event) {
entries.add(event.getRenderedMessage());
ThrowableInformation info = event.getThrowableInformation();
if (info != null) {
Throwable t = info.getThrowable();
if (t != null) {
entries.add(t.getMessage());
}
}
return Filter.ACCEPT;
}
});
}
private static String extractStacktrace(ThrowableInformation throwableInformation) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
Throwable t = throwableInformation.getThrowable();
if (t != null) {
t.printStackTrace(pw);
return sw.toString();
} else {
return null;
}
}
@Override
public Throwable getThrowable() {
ThrowableInformation ti = loggingEvent.getThrowableInformation();
if (ti != null) {
return ti.getThrowable();
}
return null;
}
public int countExceptionsWithMessage(final String text) {
int count = 0;
for (LoggingEvent e: getLog()) {
ThrowableInformation t = e.getThrowableInformation();
if (t != null) {
String m = t.getThrowable().getMessage();
if (m.contains(text)) {
count++;
}
}
}
return count;
}
/**
* Convert an event to JSON
*
* @param writer the destination writer
* @param event the event -must not be null
* @return the writer
* @throws IOException on problems generating the JSON
*/
public Writer toJson(final Writer writer, final LoggingEvent event)
throws IOException {
ThrowableInformation ti = event.getThrowableInformation();
toJson(writer,
event.getLoggerName(),
event.getTimeStamp(),
event.getLevel().toString(),
event.getThreadName(),
event.getRenderedMessage(),
ti);
return writer;
}
/**
* Build a JSON entry from the parameters. This is public for testing.
*
* @param writer destination
* @param loggerName logger name
* @param timeStamp time_t value
* @param level level string
* @param threadName name of the thread
* @param message rendered message
* @param ti nullable thrown information
* @return the writer
* @throws IOException on any problem
*/
public Writer toJson(final Writer writer,
final String loggerName,
final long timeStamp,
final String level,
final String threadName,
final String message,
final ThrowableInformation ti) throws IOException {
JsonGenerator json = factory.createJsonGenerator(writer);
json.writeStartObject();
json.writeStringField(NAME, loggerName);
json.writeNumberField(TIME, timeStamp);
Date date = new Date(timeStamp);
json.writeStringField(DATE, dateFormat.format(date));
json.writeStringField(LEVEL, level);
json.writeStringField(THREAD, threadName);
json.writeStringField(MESSAGE, message);
if (ti != null) {
//there is some throwable info, but if the log event has been sent over the wire,
//there may not be a throwable inside it, just a summary.
Throwable thrown = ti.getThrowable();
String eclass = (thrown != null) ?
thrown.getClass().getName()
: "";
json.writeStringField(EXCEPTION_CLASS, eclass);
String[] stackTrace = ti.getThrowableStrRep();
json.writeArrayFieldStart(STACK);
for (String row : stackTrace) {
json.writeString(row);
}
json.writeEndArray();
}
json.writeEndObject();
json.flush();
json.close();
return writer;
}
@Test
public void testNestedException() throws Throwable {
Exception e =
new NoRouteToHostException("that box caught fire 3 years ago");
Exception ioe = new IOException("Datacenter problems", e);
ThrowableInformation ti = new ThrowableInformation(ioe);
Log4Json l4j = new Log4Json();
long timeStamp = Time.now();
String outcome = l4j.toJson(new StringWriter(),
"testNestedException",
timeStamp,
"INFO",
"quoted\"",
"new line\n and {}",
ti)
.toString();
println("testNestedException", outcome);
ContainerNode rootNode = Log4Json.parse(outcome);
assertEntryEquals(rootNode, Log4Json.LEVEL, "INFO");
assertEntryEquals(rootNode, Log4Json.NAME, "testNestedException");
assertEntryEquals(rootNode, Log4Json.TIME, timeStamp);
assertEntryEquals(rootNode, Log4Json.EXCEPTION_CLASS,
ioe.getClass().getName());
JsonNode node = assertNodeContains(rootNode, Log4Json.STACK);
assertTrue("Not an array: " + node, node.isArray());
node = assertNodeContains(rootNode, Log4Json.DATE);
assertTrue("Not a string: " + node, node.isTextual());
//rather than try and make assertions about the format of the text
//message equalling another ISO date, this test asserts that the hypen
//and colon characters are in the string.
String dateText = node.getTextValue();
assertTrue("No '-' in " + dateText, dateText.contains("-"));
assertTrue("No '-' in " + dateText, dateText.contains(":"));
}
@Override
public String format(LoggingEvent event) {
BenderLogEntry entry = new BenderLogEntry();
entry.threadName = event.getThreadName();
entry.posixTimestamp = event.getTimeStamp();
entry.timestamp = FORMATTER.print(entry.posixTimestamp);
entry.message = event.getRenderedMessage();
entry.level = event.getLevel().toString();
entry.logger = event.getLogger().getName();
entry.alias = ALIAS;
entry.version = VERSION;
if (event.getThrowableInformation() != null) {
final ThrowableInformation throwableInfo = event.getThrowableInformation();
ExceptionLog ex = new ExceptionLog();
if (throwableInfo.getThrowable().getClass().getCanonicalName() != null) {
ex.clazz = throwableInfo.getThrowable().getClass().getCanonicalName();
}
if (throwableInfo.getThrowable().getMessage() != null) {
ex.message = throwableInfo.getThrowable().getMessage();
}
if (throwableInfo.getThrowableStrRep() != null) {
Arrays.asList(throwableInfo.getThrowableStrRep()).forEach(m -> {
ex.stacktrace.add(m.replaceAll("\\t", " "));
});
}
entry.exception = ex;
}
LocationInfo locinfo = event.getLocationInformation();
entry.file = locinfo.getFileName();
entry.lineNumber = Integer.parseInt(locinfo.getLineNumber());
entry.method = locinfo.getMethodName();
entry.clazz = locinfo.getClassName();
return GSON.toJson(entry) + "\n";
}
public int countExceptionsWithMessage(final String text) {
int count = 0;
for (LoggingEvent e: getLog()) {
ThrowableInformation t = e.getThrowableInformation();
if (t != null) {
String m = t.getThrowable().getMessage();
if (m.contains(text)) {
count++;
}
}
}
return count;
}
/**
* Convert an event to JSON
*
* @param writer the destination writer
* @param event the event -must not be null
* @return the writer
* @throws IOException on problems generating the JSON
*/
public Writer toJson(final Writer writer, final LoggingEvent event)
throws IOException {
ThrowableInformation ti = event.getThrowableInformation();
toJson(writer,
event.getLoggerName(),
event.getTimeStamp(),
event.getLevel().toString(),
event.getThreadName(),
event.getRenderedMessage(),
ti);
return writer;
}
/**
* Build a JSON entry from the parameters. This is public for testing.
*
* @param writer destination
* @param loggerName logger name
* @param timeStamp time_t value
* @param level level string
* @param threadName name of the thread
* @param message rendered message
* @param ti nullable thrown information
* @return the writer
* @throws IOException on any problem
*/
public Writer toJson(final Writer writer,
final String loggerName,
final long timeStamp,
final String level,
final String threadName,
final String message,
final ThrowableInformation ti) throws IOException {
JsonGenerator json = factory.createJsonGenerator(writer);
json.writeStartObject();
json.writeStringField(NAME, loggerName);
json.writeNumberField(TIME, timeStamp);
Date date = new Date(timeStamp);
json.writeStringField(DATE, dateFormat.format(date));
json.writeStringField(LEVEL, level);
json.writeStringField(THREAD, threadName);
json.writeStringField(MESSAGE, message);
if (ti != null) {
//there is some throwable info, but if the log event has been sent over the wire,
//there may not be a throwable inside it, just a summary.
Throwable thrown = ti.getThrowable();
String eclass = (thrown != null) ?
thrown.getClass().getName()
: "";
json.writeStringField(EXCEPTION_CLASS, eclass);
String[] stackTrace = ti.getThrowableStrRep();
json.writeArrayFieldStart(STACK);
for (String row : stackTrace) {
json.writeString(row);
}
json.writeEndArray();
}
json.writeEndObject();
json.flush();
json.close();
return writer;
}
@Test
public void testNestedException() throws Throwable {
Exception e =
new NoRouteToHostException("that box caught fire 3 years ago");
Exception ioe = new IOException("Datacenter problems", e);
ThrowableInformation ti = new ThrowableInformation(ioe);
Log4Json l4j = new Log4Json();
long timeStamp = Time.now();
String outcome = l4j.toJson(new StringWriter(),
"testNestedException",
timeStamp,
"INFO",
"quoted\"",
"new line\n and {}",
ti)
.toString();
println("testNestedException", outcome);
ContainerNode rootNode = Log4Json.parse(outcome);
assertEntryEquals(rootNode, Log4Json.LEVEL, "INFO");
assertEntryEquals(rootNode, Log4Json.NAME, "testNestedException");
assertEntryEquals(rootNode, Log4Json.TIME, timeStamp);
assertEntryEquals(rootNode, Log4Json.EXCEPTION_CLASS,
ioe.getClass().getName());
JsonNode node = assertNodeContains(rootNode, Log4Json.STACK);
assertTrue("Not an array: " + node, node.isArray());
node = assertNodeContains(rootNode, Log4Json.DATE);
assertTrue("Not a string: " + node, node.isTextual());
//rather than try and make assertions about the format of the text
//message equalling another ISO date, this test asserts that the hypen
//and colon characters are in the string.
String dateText = node.getTextValue();
assertTrue("No '-' in " + dateText, dateText.contains("-"));
assertTrue("No '-' in " + dateText, dateText.contains(":"));
}
/**
* Set stack trace information associated with this Log4JLogRecord.
* When this method is called, the stack trace in a
* String-based format is made
* available via the getThrownStackTrace() method.
*
* @param throwableInfo An org.apache.log4j.spi.ThrowableInformation to
* associate with this Log4JLogRecord.
* @see #getThrownStackTrace()
*/
public void setThrownStackTrace(ThrowableInformation throwableInfo) {
String[] stackTraceArray = throwableInfo.getThrowableStrRep();
StringBuffer stackTrace = new StringBuffer();
String nextLine;
for (int i = 0; i < stackTraceArray.length; i++) {
nextLine = stackTraceArray[i] + "\n";
stackTrace.append(nextLine);
}
_thrownStackTrace = stackTrace.toString();
}
@Override
public void append(LoggingEvent event)
{
debugLogBox.log(this.layout.format(event));
ThrowableInformation info = event.getThrowableInformation();
if (info != null && info.getThrowable() != null)
{
Throwable t = info.getThrowable();
debugLogBox.log(throwableToString(t));
}
}
@Override protected void append(LoggingEvent event) {
final LevelTag level = LevelTag.get(event.getLevel());
registry.counter(numMessages[level.ordinal()]).increment();
ThrowableInformation info = event.getThrowableInformation();
if (info != null) {
LocationInfo loc = event.getLocationInformation();
final String file = (loc == null) ? "unknown" : loc.getFileName();
Id stackTraceId = numStackTraces[level.ordinal()]
.withTag("exception", info.getThrowable().getClass().getSimpleName())
.withTag("file", file);
registry.counter(stackTraceId).increment();
}
}
private void tryPrintMessage(String message, ThrowableInformation info) {
try {
stream.println(message);
if (info != null) {
Throwable throwable = info.getThrowable();
if (throwable != null) {
stream.println(throwable.getMessage());
throwable.printStackTrace(new PrintStream(stream));
}
}
} catch (Exception e) {
}
}
/**
Returns the throwable information contained within this
event. May be <code>null</code> if there is no such information.
<p>Note that the {@link Throwable} object contained within a
{@link ThrowableInformation} does not survive serialization.
@since 1.1 */
@Override
public
ThrowableInformation getThrowableInformation() {
if (event.getThrown() != null) {
return new ThrowableInformation(event.getThrown());
}
return null;
}
LoggingEvent asLoggingEvent() {
// The fully qualified class name of the logger instance is normally used to compute the log
// location (file, class, method, line number) from the stacktrace. Since we already have the
// log location in hand we don't need this computation. By passing in null as fully qualified
// class name of the logger instance we ensure that the log location computation is disabled.
// this is important since the log location computation is very expensive.
String fqnOfCategoryClass = null;
// The Nested Diagnostic Context (NDC) allows to include additional metadata into logs which
// are written from the current thread.
//
// Example:
// NDC.push("user.id=" + userId);
// // do business logic that triggers logs
// NDC.pop();
// NDC.remove();
//
// By using '%x' in the ConversionPattern of an appender this data can be included in the logs.
//
// We could include this data here by doing 'NDC.get()', but we don't want to encourage people
// using the log4j specific NDC. Instead this should be supported by a LoggingContext and usage
// of Flogger tags.
String nestedDiagnosticContext = "";
// The Mapped Diagnostic Context (MDC) allows to include additional metadata into logs which
// are written from the current thread.
//
// Example:
// MDC.put("user.id", userId);
// // do business logic that triggers logs
// MDC.clear();
//
// By using '%X{key}' in the ConversionPattern of an appender this data can be included in the
// logs.
//
// We could include this data here by doing 'MDC.getContext()', but we don't want to encourage
// people using the log4j specific MDC. Instead this should be supported by a LoggingContext and
// usage of Flogger tags.
Map<String, String> mdcProperties = Collections.emptyMap();
return new LoggingEvent(
fqnOfCategoryClass,
logger,
TimeUnit.NANOSECONDS.toMillis(logData.getTimestampNanos()),
level,
message,
Thread.currentThread().getName(),
thrown != null ? new ThrowableInformation(thrown) : null,
nestedDiagnosticContext,
getLocationInfo(),
mdcProperties);
}
/**
* Encodes a LoggingEvent into a HashMap using the logstash JSON format.
*
* @param loggingEvent
* The LoggingEvent to encode.
* @param includeLocationInfo
* Whether to include LocationInfo in the map, or not.
* @return A Map representing the LoggingEvent, which is suitable to be
* serialized by a JSON encoder such as Jackson.
*/
@SuppressWarnings("rawtypes")
public static Map<String, Object> encodeToMap(LoggingEvent loggingEvent, boolean includeLocationInfo) {
Map<String, Object> logstashEvent = new LoggingEventMap();
String threadName = loggingEvent.getThreadName();
long timestamp = loggingEvent.getTimeStamp();
HashMap<String, Object> exceptionInformation = new HashMap<String, Object>();
Map mdc = loggingEvent.getProperties();
String ndc = loggingEvent.getNDC();
logstashEvent.put("@version", VERSION);
logstashEvent.put("@timestamp", dateFormat(timestamp));
logstashEvent.put("source_host", getHostname());
logstashEvent.put("message", loggingEvent.getRenderedMessage());
if (loggingEvent.getThrowableInformation() != null) {
final ThrowableInformation throwableInformation = loggingEvent.getThrowableInformation();
if (throwableInformation.getThrowable().getClass().getCanonicalName() != null) {
exceptionInformation.put("exception_class", throwableInformation.getThrowable().getClass().getCanonicalName());
}
if (throwableInformation.getThrowable().getMessage() != null) {
exceptionInformation.put("exception_message", throwableInformation.getThrowable().getMessage());
}
if (throwableInformation.getThrowableStrRep() != null) {
StringBuilder stackTrace = new StringBuilder();
for (String line : throwableInformation.getThrowableStrRep()) {
stackTrace.append(line);
stackTrace.append("\n");
}
exceptionInformation.put("stacktrace", stackTrace);
}
logstashEvent.put("exception", exceptionInformation);
}
if (includeLocationInfo) {
LocationInfo info = loggingEvent.getLocationInformation();
logstashEvent.put("file", info.getFileName());
logstashEvent.put("line_number", info.getLineNumber());
logstashEvent.put("class", info.getClassName());
logstashEvent.put("method", info.getMethodName());
}
logstashEvent.put("logger_name", loggingEvent.getLoggerName());
logstashEvent.put("mdc", mdc);
logstashEvent.put("ndc", ndc);
logstashEvent.put("level", loggingEvent.getLevel().toString());
logstashEvent.put("thread_name", threadName);
return logstashEvent;
}
private LoggingEvent newLoggingEvent(String message) {
return new LoggingEvent(this.getClass().getName(), new NOPLogger(new NOPLoggerRepository(), "NOP"),
System.currentTimeMillis(), Level.INFO, message,
Thread.currentThread().getName(), new ThrowableInformation((Throwable)null), null,
new LocationInfo(null, null), new Properties());
}
@Override
public Throwable getThrowable(LoggingEvent record) {
ThrowableInformation throwableInformation = record.getThrowableInformation();
return throwableInformation != null ? throwableInformation.getThrowable() : null;
}
@Override
public ThrowableInformation getThrowableInformation() {
// 例外情報を返さない
return null;
}
/**
* Returns the throwable information contained within this
* event. May be <code>null</code> if there is no such information.
*
* <p>Note that the {@link Throwable} object contained within a
* {@link ThrowableInformation} does not survive serialization.
*
* @since 1.1
*/
@Override
public ThrowableInformation getThrowableInformation() {
if (event.getThrown() != null) {
return new ThrowableInformation(event.getThrown());
}
return null;
}