Support custom exception handling (#14493)

Co-authored-by: otelbot <197425009+otelbot@users.noreply.github.com>
This commit is contained in:
Trask Stalnaker 2025-08-25 07:11:39 -07:00 committed by GitHub
parent 38765f5abd
commit c607938924
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 42 additions and 45 deletions

View File

@ -9,14 +9,12 @@ import application.java.util.logging.Logger;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder;
import io.opentelemetry.api.logs.LogRecordBuilder;
import io.opentelemetry.api.logs.Severity;
import io.opentelemetry.context.Context;
import io.opentelemetry.javaagent.bootstrap.internal.AgentInstrumentationConfig;
import io.opentelemetry.semconv.ExceptionAttributes;
import io.opentelemetry.semconv.incubating.ThreadIncubatingAttributes;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.concurrent.TimeUnit;
import java.util.logging.Formatter;
import java.util.logging.Level;
@ -85,13 +83,8 @@ public final class JavaUtilLoggingHelper {
// throwable
Throwable throwable = logRecord.getThrown();
if (throwable != null) {
// TODO (trask) extract method for recording exception into
// io.opentelemetry:opentelemetry-api
attributes.put(ExceptionAttributes.EXCEPTION_TYPE, throwable.getClass().getName());
attributes.put(ExceptionAttributes.EXCEPTION_MESSAGE, throwable.getMessage());
StringWriter writer = new StringWriter();
throwable.printStackTrace(new PrintWriter(writer));
attributes.put(ExceptionAttributes.EXCEPTION_STACKTRACE, writer.toString());
// this cast is safe within java agent instrumentation
((ExtendedLogRecordBuilder) builder).setException(throwable);
}
if (captureExperimentalAttributes) {

View File

@ -12,15 +12,13 @@ import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder;
import io.opentelemetry.api.logs.LogRecordBuilder;
import io.opentelemetry.api.logs.Severity;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.internal.cache.Cache;
import io.opentelemetry.javaagent.bootstrap.internal.AgentInstrumentationConfig;
import io.opentelemetry.semconv.ExceptionAttributes;
import io.opentelemetry.semconv.incubating.ThreadIncubatingAttributes;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;
import java.util.Map;
import org.jboss.logmanager.ExtLogRecord;
@ -81,13 +79,8 @@ public final class LoggingEventMapper {
Throwable throwable = record.getThrown();
if (throwable != null) {
// TODO (trask) extract method for recording exception into
// io.opentelemetry:opentelemetry-api
attributes.put(ExceptionAttributes.EXCEPTION_TYPE, throwable.getClass().getName());
attributes.put(ExceptionAttributes.EXCEPTION_MESSAGE, throwable.getMessage());
StringWriter writer = new StringWriter();
throwable.printStackTrace(new PrintWriter(writer));
attributes.put(ExceptionAttributes.EXCEPTION_STACKTRACE, writer.toString());
// this cast is safe within java agent instrumentation
((ExtendedLogRecordBuilder) builder).setException(throwable);
}
captureMdcAttributes(attributes);

View File

@ -11,6 +11,7 @@ import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder;
import io.opentelemetry.api.logs.LogRecordBuilder;
import io.opentelemetry.api.logs.Severity;
import io.opentelemetry.context.Context;
@ -101,13 +102,15 @@ public final class LogEventMapper {
// throwable
if (throwable != null) {
// TODO (trask) extract method for recording exception into
// io.opentelemetry:opentelemetry-api
attributes.put(ExceptionAttributes.EXCEPTION_TYPE, throwable.getClass().getName());
attributes.put(ExceptionAttributes.EXCEPTION_MESSAGE, throwable.getMessage());
StringWriter writer = new StringWriter();
throwable.printStackTrace(new PrintWriter(writer));
attributes.put(ExceptionAttributes.EXCEPTION_STACKTRACE, writer.toString());
if (builder instanceof ExtendedLogRecordBuilder) {
((ExtendedLogRecordBuilder) builder).setException(throwable);
} else {
attributes.put(ExceptionAttributes.EXCEPTION_TYPE, throwable.getClass().getName());
attributes.put(ExceptionAttributes.EXCEPTION_MESSAGE, throwable.getMessage());
StringWriter writer = new StringWriter();
throwable.printStackTrace(new PrintWriter(writer));
attributes.put(ExceptionAttributes.EXCEPTION_STACKTRACE, writer.toString());
}
}
captureMdcAttributes(attributes);

View File

@ -8,6 +8,7 @@ package io.opentelemetry.instrumentation.log4j.appender.v2_17.internal;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder;
import io.opentelemetry.api.logs.LogRecordBuilder;
import io.opentelemetry.api.logs.Severity;
import io.opentelemetry.context.Context;
@ -117,7 +118,7 @@ public final class LogEventMapper<T> {
}
if (throwable != null) {
setThrowable(attributes, throwable);
setThrowable(builder, attributes, throwable);
}
captureContextDataAttributes(attributes, contextData);
@ -233,14 +234,17 @@ public final class LogEventMapper<T> {
key, k -> AttributeKey.stringKey("log4j.map_message." + k));
}
private static void setThrowable(AttributesBuilder attributes, Throwable throwable) {
// TODO (trask) extract method for recording exception into
// io.opentelemetry:opentelemetry-api
attributes.put(ExceptionAttributes.EXCEPTION_TYPE, throwable.getClass().getName());
attributes.put(ExceptionAttributes.EXCEPTION_MESSAGE, throwable.getMessage());
StringWriter writer = new StringWriter();
throwable.printStackTrace(new PrintWriter(writer));
attributes.put(ExceptionAttributes.EXCEPTION_STACKTRACE, writer.toString());
private static void setThrowable(
LogRecordBuilder builder, AttributesBuilder attributes, Throwable throwable) {
if (builder instanceof ExtendedLogRecordBuilder) {
((ExtendedLogRecordBuilder) builder).setException(throwable);
} else {
attributes.put(ExceptionAttributes.EXCEPTION_TYPE, throwable.getClass().getName());
attributes.put(ExceptionAttributes.EXCEPTION_MESSAGE, throwable.getMessage());
StringWriter writer = new StringWriter();
throwable.printStackTrace(new PrintWriter(writer));
attributes.put(ExceptionAttributes.EXCEPTION_STACKTRACE, writer.toString());
}
}
private static Severity levelToSeverity(Level level) {

View File

@ -17,6 +17,7 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder;
import io.opentelemetry.api.logs.LogRecordBuilder;
import io.opentelemetry.api.logs.LoggerProvider;
import io.opentelemetry.api.logs.Severity;
@ -147,7 +148,7 @@ public final class LoggingEventMapper {
throwable = ((ThrowableProxy) throwableProxy).getThrowable();
}
if (throwable != null) {
setThrowable(attributes, throwable);
setThrowable(builder, attributes, throwable);
}
captureMdcAttributes(attributes, loggingEvent.getMDCPropertyMap());
@ -269,14 +270,17 @@ public final class LoggingEventMapper {
return mdcAttributeKeys.computeIfAbsent(key, AttributeKey::stringKey);
}
private static void setThrowable(AttributesBuilder attributes, Throwable throwable) {
// TODO (trask) extract method for recording exception into
// io.opentelemetry:opentelemetry-api
attributes.put(ExceptionAttributes.EXCEPTION_TYPE, throwable.getClass().getName());
attributes.put(ExceptionAttributes.EXCEPTION_MESSAGE, throwable.getMessage());
StringWriter writer = new StringWriter();
throwable.printStackTrace(new PrintWriter(writer));
attributes.put(ExceptionAttributes.EXCEPTION_STACKTRACE, writer.toString());
private static void setThrowable(
LogRecordBuilder builder, AttributesBuilder attributes, Throwable throwable) {
if (builder instanceof ExtendedLogRecordBuilder) {
((ExtendedLogRecordBuilder) builder).setException(throwable);
} else {
attributes.put(ExceptionAttributes.EXCEPTION_TYPE, throwable.getClass().getName());
attributes.put(ExceptionAttributes.EXCEPTION_MESSAGE, throwable.getMessage());
StringWriter writer = new StringWriter();
throwable.printStackTrace(new PrintWriter(writer));
attributes.put(ExceptionAttributes.EXCEPTION_STACKTRACE, writer.toString());
}
}
private static Severity levelToSeverity(Level level) {