Skip to content

Extended attributes support for log4j-appender-2.17 #13836

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

public final class Log4jHelper {

private static final LogEventMapper<Map<String, String>> mapper;
private static final LogEventMapper<Map<String, ?>> mapper;
private static final boolean captureExperimentalAttributes;
private static final MethodHandle stackTraceMethodHandle = getStackTraceMethodHandle();

Expand Down Expand Up @@ -147,17 +147,17 @@ private static MethodHandle getStackTraceMethodHandle() {
}
}

private enum ContextDataAccessorImpl implements ContextDataAccessor<Map<String, String>> {
private enum ContextDataAccessorImpl implements ContextDataAccessor<Map<String, ?>, Object> {
INSTANCE;

@Override
@Nullable
public String getValue(Map<String, String> contextData, String key) {
public Object getValue(Map<String, ?> contextData, String key) {
return contextData.get(key);
}

@Override
public void forEach(Map<String, String> contextData, BiConsumer<String, String> action) {
public void forEach(Map<String, ?> contextData, BiConsumer<String, Object> action) {
contextData.forEach(action);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ dependencies {
annotationProcessor("org.apache.logging.log4j:log4j-core:2.17.0")

implementation(project(":instrumentation:log4j:log4j-context-data:log4j-context-data-2.17:library-autoconfigure"))
implementation("io.opentelemetry:opentelemetry-api-incubator")

testImplementation("io.opentelemetry:opentelemetry-sdk-testing")
testLibrary("com.lmax:disruptor:3.3.4")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,11 +300,13 @@ private void emit(OpenTelemetry openTelemetry, LogEvent event) {
// when using async logger we'll be executing on a different thread than what started logging
// reconstruct the context from context data
if (context == Context.root()) {
ContextDataAccessor<ReadOnlyStringMap> contextDataAccessor = ContextDataAccessorImpl.INSTANCE;
String traceId = contextDataAccessor.getValue(contextData, ContextDataKeys.TRACE_ID_KEY);
String spanId = contextDataAccessor.getValue(contextData, ContextDataKeys.SPAN_ID_KEY);
ContextDataAccessor<ReadOnlyStringMap, Object> contextDataAccessor =
ContextDataAccessorImpl.INSTANCE;
String traceId =
contextDataAccessor.getStringValue(contextData, ContextDataKeys.TRACE_ID_KEY);
String spanId = contextDataAccessor.getStringValue(contextData, ContextDataKeys.SPAN_ID_KEY);
String traceFlags =
contextDataAccessor.getValue(contextData, ContextDataKeys.TRACE_FLAGS_KEY);
contextDataAccessor.getStringValue(contextData, ContextDataKeys.TRACE_FLAGS_KEY);
if (traceId != null && spanId != null && traceFlags != null) {
context =
Context.root()
Expand Down Expand Up @@ -340,17 +342,17 @@ private void emit(OpenTelemetry openTelemetry, LogEvent event) {
builder.emit();
}

private enum ContextDataAccessorImpl implements ContextDataAccessor<ReadOnlyStringMap> {
private enum ContextDataAccessorImpl implements ContextDataAccessor<ReadOnlyStringMap, Object> {
INSTANCE;

@Override
@Nullable
public String getValue(ReadOnlyStringMap contextData, String key) {
public Object getValue(ReadOnlyStringMap contextData, String key) {
return contextData.getValue(key);
}

@Override
public void forEach(ReadOnlyStringMap contextData, BiConsumer<String, String> action) {
public void forEach(ReadOnlyStringMap contextData, BiConsumer<String, Object> action) {
contextData.forEach(action::accept);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,18 @@
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public interface ContextDataAccessor<T> {
public interface ContextDataAccessor<T, V> {

@Nullable
String getValue(T contextData, String key);
V getValue(T contextData, String key);

void forEach(T contextData, BiConsumer<String, String> action);
default String getStringValue(T contextData, String key) {
Object value = getValue(contextData, key);
if (value != null) {
return value.toString();
}
return null;
}

void forEach(T contextData, BiConsumer<String, V> action);
}
Loading
Loading