Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
36d986e
Support excluding MDC attributes from capture-all
philsttr Jun 5, 2026
0e328af
Updated log4j-appender-1.2 test to verify excluded keys
philsttr Jun 5, 2026
4b36914
Ignore mdc/contextData exclusions unless `*` is included.
philsttr Jun 5, 2026
58c5e03
Updated jboss-logmanager-appender-1.1 test to verify excluded keys
philsttr Jun 5, 2026
25b8aed
use unmodifiableSet for mdc/contextData exclusions
philsttr Jun 5, 2026
f24c067
capture !foo literally, unless * is specified
philsttr Jun 5, 2026
ad15f97
Merge remote-tracking branch 'upstream/main' into exclude_mdc_entries
philsttr Jun 12, 2026
6971127
Use separate include/exclude properties with IncludeExcludePredicate …
philsttr Jun 12, 2026
4a55609
Merge remote-tracking branch 'upstream/main' into exclude_mdc_entries
philsttr Jun 12, 2026
85aa879
allow opentelemetry-sdk-common in muzzle
philsttr Jun 12, 2026
149aea4
update latest-dep-versions.json
philsttr Jun 12, 2026
2a97aea
Merge upstream/main into exclude_mdc_entries
trask Jul 14, 2026
033f947
Fix muzzle validation for SDK common dependency
trask Jul 14, 2026
eb3131a
Merge remote-tracking branch 'upstream/main' into exclude_mdc_entries
philsttr Jul 14, 2026
6211647
update test comment to reflect exclude-mdc-attributes config
philsttr Jul 14, 2026
34e0fc6
Fix MDC filter predicate classloader visibility
trask Jul 14, 2026
e4b64df
Update spring boot additional-spring-configuration-metadata.json for …
philsttr Jul 14, 2026
b030d27
add missing excludeMdcAttributes setting in logback appender readme
philsttr Jul 14, 2026
a82e654
Merge remote-tracking branch 'upstream/main' into exclude_mdc_entries
philsttr Jul 22, 2026
bdb4d99
Merge remote-tracking branch 'upstream/main' into exclude_mdc_entries
philsttr Jul 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions docs/instrumentation-list.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6920,12 +6920,13 @@ libraries:
- name: otel.instrumentation.jboss-logmanager.experimental.capture-mdc-attributes
declarative_name: java.jboss_logmanager.capture_mdc_attributes/development
description: |
Controls which MDC attributes to capture. Use "*" to capture all MDC attributes or provide a comma-separated list of specific keys.
Controls which MDC attributes to capture. Use "*" to capture all MDC attributes or provide a comma-separated list of specific keys. When using "*", prefix a key with "!" to exclude it (e.g. "*,!foo" captures all MDC attributes except "foo").
type: list
default: ''
examples:
- custom-mdc-key
- key1,key2,key3
- '*,!foo'
- name: jboss-logmanager-mdc-1.1
display_name: JBoss Log Manager
description: |
Expand Down Expand Up @@ -9555,12 +9556,13 @@ libraries:
- name: otel.instrumentation.log4j-appender.experimental.capture-mdc-attributes
declarative_name: java.log4j_appender.capture_mdc_attributes/development
description: |
Controls which MDC attributes to capture. Use "*" to capture all MDC attributes or provide a comma-separated list of specific keys.
Controls which MDC attributes to capture. Use "*" to capture all MDC attributes or provide a comma-separated list of specific keys. When using "*", prefix a key with "!" to exclude it (e.g. "*,!foo" captures all MDC attributes except "foo").
type: list
default: ''
examples:
- custom-mdc-key
- key1,key2,key3
- '*,!foo'
- name: otel.instrumentation.log4j-appender.experimental.capture-code-attributes
declarative_name: java.log4j_appender.capture_code_attributes/development
description: |
Expand Down Expand Up @@ -9609,12 +9611,13 @@ libraries:
- name: otel.instrumentation.log4j-appender.experimental.capture-mdc-attributes
declarative_name: java.log4j_appender.capture_mdc_attributes/development
description: |
Controls which MDC attributes to capture. Use "*" to capture all MDC attributes or provide a comma-separated list of specific keys.
Controls which MDC attributes to capture. Use "*" to capture all MDC attributes or provide a comma-separated list of specific keys. When using "*", prefix a key with "!" to exclude it (e.g. "*,!foo" captures all MDC attributes except "foo").
type: list
default: ''
examples:
- '*'
- key1,key2
- '*,!foo'
- name: log4j-context-data-2.7
display_name: Log4j
description: |
Expand Down Expand Up @@ -9807,12 +9810,13 @@ libraries:
- name: otel.instrumentation.logback-appender.experimental.capture-mdc-attributes
declarative_name: java.logback_appender.capture_mdc_attributes/development
description: |
Controls which MDC attributes to capture. Use "*" to capture all MDC attributes or provide a comma-separated list of specific keys.
Controls which MDC attributes to capture. Use "*" to capture all MDC attributes or provide a comma-separated list of specific keys. When using "*", prefix a key with "!" to exclude it (e.g. "*,!foo" captures all MDC attributes except "foo").
type: list
default: ''
examples:
- custom-mdc-key
- key1,key2,key3
- '*,!foo'
- name: logback-mdc-1.0
display_name: Logback
description: |
Expand Down
8 changes: 4 additions & 4 deletions instrumentation/jboss-logmanager/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Settings for the JBoss Log Manager instrumentation

| System property | Type | Default | Description |
|-----------------------------------------------------------------------------|---------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------|
| `otel.instrumentation.jboss-logmanager.experimental-log-attributes` | Boolean | `false` | Enable the capture of experimental log attributes `thread.name` and `thread.id`. |
| `otel.instrumentation.jboss-logmanager.experimental.capture-mdc-attributes` | String | | Comma separated list of MDC attributes to capture. Use the wildcard character `*` to capture all attributes. |
| System property | Type | Default | Description |
|-----------------------------------------------------------------------------|---------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `otel.instrumentation.jboss-logmanager.experimental-log-attributes` | Boolean | `false` | Enable the capture of experimental log attributes `thread.name` and `thread.id`. |
| `otel.instrumentation.jboss-logmanager.experimental.capture-mdc-attributes` | String | | Comma separated list of MDC attributes to capture. Use the wildcard character `*` to capture all attributes. When using `*`, prefix a key with `!` to exclude it (e.g. `*,!foo` captures all attributes except `foo`). |

The `otel.event.name` key is supported in MDC entries. When present, its value is used as the log event name and is not emitted as an attribute.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ if (otelProps.testLatestDeps) {

tasks.test {
// TODO run tests both with and without experimental log attributes
jvmArgs("-Dotel.instrumentation.jboss-logmanager.experimental.capture-mdc-attributes=*")
jvmArgs("-Dotel.instrumentation.jboss-logmanager.experimental.capture-mdc-attributes=*,!excludedKey")
jvmArgs("-Dotel.instrumentation.jboss-logmanager.experimental-log-attributes=true")
jvmArgs("-Dotel.instrumentation.java-util-logging.experimental-log-attributes=true")
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import static io.opentelemetry.semconv.incubating.ThreadIncubatingAttributes.THREAD_ID;
import static io.opentelemetry.semconv.incubating.ThreadIncubatingAttributes.THREAD_NAME;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptySet;
import static java.util.Collections.unmodifiableSet;
import static java.util.concurrent.TimeUnit.MILLISECONDS;

import io.opentelemetry.api.GlobalOpenTelemetry;
Expand All @@ -19,8 +21,10 @@
import io.opentelemetry.instrumentation.api.incubator.config.internal.DeclarativeConfigUtil;
import io.opentelemetry.instrumentation.api.internal.cache.Cache;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jboss.logmanager.ExtLogRecord;
import org.jboss.logmanager.Level;
import org.jboss.logmanager.Logger;
Expand All @@ -40,24 +44,34 @@ public class LoggingEventMapper {

// cached as an optimization
private final boolean captureAllMdcAttributes;
private final Set<String> excludedMdcAttributeKeys;

private LoggingEventMapper() {
List<String> captureMdcAttributes =
DeclarativeConfigUtil.getInstrumentationConfig(
GlobalOpenTelemetry.get(), "jboss_logmanager")
.getScalarList("capture_mdc_attributes/development", String.class, emptyList());
this.captureAllMdcAttributes =
captureMdcAttributes.size() == 1 && captureMdcAttributes.get(0).equals("*");
this.captureAllMdcAttributes = captureMdcAttributes.contains("*");
if (captureAllMdcAttributes) {
this.captureMdcAttributeKeys = emptyList();
Set<String> excluded = new HashSet<>();
for (String key : captureMdcAttributes) {
// an entry of "!<key>" excludes <key>; a bare "!" is ignored
if (key.startsWith("!") && key.length() > 1) {
excluded.add(key.substring(1));
}
}
this.excludedMdcAttributeKeys = unmodifiableSet(excluded);
} else {
List<AttributeKey<String>> keys = new ArrayList<>(captureMdcAttributes.size());
for (String key : captureMdcAttributes) {
if (!OTEL_EVENT_NAME.getKey().equals(key)) {
// "!" prefixed entries are exclusions, which only apply together with "*"; ignore them here
if (!OTEL_EVENT_NAME.getKey().equals(key) && !key.startsWith("!")) {
keys.add(getMdcAttributeKey(key));
}
}
this.captureMdcAttributeKeys = keys;
this.excludedMdcAttributeKeys = emptySet();
}
}

Expand Down Expand Up @@ -118,7 +132,7 @@ private void captureMdcAttributes(LogRecordBuilder builder) {
if (captureAllMdcAttributes) {
for (Map.Entry<String, String> entry : context.entrySet()) {
String key = entry.getKey();
if (!OTEL_EVENT_NAME.getKey().equals(key)) {
if (!OTEL_EVENT_NAME.getKey().equals(key) && !excludedMdcAttributeKeys.contains(key)) {
builder.setAttribute(getMdcAttributeKey(key), entry.getValue());
}
Comment thread
philsttr marked this conversation as resolved.
Outdated
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,12 +197,16 @@ private static void performLogging(
void testMdc() {
MDC.put("key1", "val1");
MDC.put("key2", "val2");
// excludedKey is filtered out by the "!excludedKey" exclusion in the capture-mdc-attributes
// config (see build.gradle.kts); the exact attribute assertions below verify it is not captured
Comment thread
philsttr marked this conversation as resolved.
Outdated
MDC.put("excludedKey", "excludedValue");
MDC.put("otel.event.name", "MyEventName");
try {
logger.info("xyz");
} finally {
MDC.remove("key1");
MDC.remove("key2");
MDC.remove("excludedKey");
MDC.remove("otel.event.name");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ configurations:
declarative_name: java.jboss_logmanager.capture_mdc_attributes/development
description: >
Controls which MDC attributes to capture. Use "*" to capture all MDC attributes or provide a
comma-separated list of specific keys.
comma-separated list of specific keys. When using "*", prefix a key with "!" to exclude it
(e.g. "*,!foo" captures all MDC attributes except "foo").
type: list
default: ''
examples:
- "custom-mdc-key"
- "key1,key2,key3"
- "*,!foo"
10 changes: 5 additions & 5 deletions instrumentation/log4j/log4j-appender-1.2/javaagent/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Settings for the Log4j Appender instrumentation

| System property | Type | Default | Description |
|-----------------------------------------------------------------------------------|---------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `otel.instrumentation.log4j-appender.experimental-log-attributes` | Boolean | `false` | Enable the capture of experimental log attributes `thread.name` and `thread.id`. |
| `otel.instrumentation.log4j-appender.experimental.capture-code-attributes` | Boolean | `false` | Enable the capture of [source code attributes]. Note that capturing source code attributes at logging sites might add a performance overhead. |
| `otel.instrumentation.log4j-appender.experimental.capture-mdc-attributes` | String | | Comma separated list of context data attributes to capture. Use the wildcard character `*` to capture all attributes. |
| System property | Type | Default | Description |
|----------------------------------------------------------------------------|---------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `otel.instrumentation.log4j-appender.experimental-log-attributes` | Boolean | `false` | Enable the capture of experimental log attributes `thread.name` and `thread.id`. |
| `otel.instrumentation.log4j-appender.experimental.capture-code-attributes` | Boolean | `false` | Enable the capture of [source code attributes]. Note that capturing source code attributes at logging sites might add a performance overhead. |
| `otel.instrumentation.log4j-appender.experimental.capture-mdc-attributes` | String | | Comma separated list of context data attributes to capture. Use the wildcard character `*` to capture all attributes. When using `*`, prefix a key with `!` to exclude it (e.g. `*,!foo` captures all attributes except `foo`). |

The `otel.event.name` key is supported in MDC entries. When present, its value is used as the log event name and is not emitted as an attribute.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ configurations {

tasks.withType<Test>().configureEach {
// TODO run tests both with and without experimental log attributes
jvmArgs("-Dotel.instrumentation.log4j-appender.experimental.capture-mdc-attributes=*")
jvmArgs("-Dotel.instrumentation.log4j-appender.experimental.capture-mdc-attributes=*,!excludedKey")
jvmArgs("-Dotel.instrumentation.log4j-appender.experimental.capture-code-attributes=true")
jvmArgs("-Dotel.instrumentation.log4j-appender.experimental-log-attributes=true")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import static io.opentelemetry.semconv.incubating.ThreadIncubatingAttributes.THREAD_ID;
import static io.opentelemetry.semconv.incubating.ThreadIncubatingAttributes.THREAD_NAME;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptySet;
import static java.util.Collections.unmodifiableSet;

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.common.AttributeKey;
Expand All @@ -24,9 +26,11 @@
import io.opentelemetry.instrumentation.api.internal.cache.Cache;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
import org.apache.log4j.Category;
import org.apache.log4j.MDC;
Expand Down Expand Up @@ -55,6 +59,7 @@ public class LogEventMapper {

// cached as an optimization
private final boolean captureAllMdcAttributes;
private final Set<String> excludedMdcAttributeKeys;

private final boolean captureCodeAttributes =
DeclarativeConfigUtil.getInstrumentationConfig(GlobalOpenTelemetry.get(), "log4j_appender")
Expand All @@ -64,18 +69,27 @@ private LogEventMapper() {
List<String> captureMdcAttributes =
DeclarativeConfigUtil.getInstrumentationConfig(GlobalOpenTelemetry.get(), "log4j_appender")
.getScalarList("capture_mdc_attributes/development", String.class, emptyList());
this.captureAllMdcAttributes =
captureMdcAttributes.size() == 1 && captureMdcAttributes.get(0).equals("*");
this.captureAllMdcAttributes = captureMdcAttributes.contains("*");
if (captureAllMdcAttributes) {
this.captureMdcAttributeKeys = emptyList();
Set<String> excluded = new HashSet<>();
for (String key : captureMdcAttributes) {
// an entry of "!<key>" excludes <key>; a bare "!" is ignored
if (key.startsWith("!") && key.length() > 1) {
excluded.add(key.substring(1));
}
}
this.excludedMdcAttributeKeys = unmodifiableSet(excluded);
} else {
List<AttributeKey<String>> keys = new ArrayList<>(captureMdcAttributes.size());
for (String key : captureMdcAttributes) {
if (!OTEL_EVENT_NAME.getKey().equals(key)) {
// "!" prefixed entries are exclusions, which only apply together with "*"; ignore them here
if (!OTEL_EVENT_NAME.getKey().equals(key) && !key.startsWith("!")) {
keys.add(getMdcAttributeKey(key));
}
}
this.captureMdcAttributeKeys = keys;
this.excludedMdcAttributeKeys = emptySet();
}
}

Expand Down Expand Up @@ -182,7 +196,7 @@ private void captureMdcAttributes(LogRecordBuilder builder) {
if (captureAllMdcAttributes) {
for (Map.Entry<?, ?> entry : context.entrySet()) {
String key = String.valueOf(entry.getKey());
if (!OTEL_EVENT_NAME.getKey().equals(key)) {
if (!OTEL_EVENT_NAME.getKey().equals(key) && !excludedMdcAttributeKeys.contains(key)) {
Comment thread
philsttr marked this conversation as resolved.
Outdated
Object value = entry.getValue();
if (value != null) {
builder.setAttribute(getMdcAttributeKey(key), value.toString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,16 @@ private static void test(
void testMdc() {
MDC.put("key1", "val1");
MDC.put("key2", "val2");
// excludedKey is filtered out by the "!excludedKey" exclusion in the capture-mdc-attributes
// config (see build.gradle.kts); the exact attribute assertions below verify it is not captured
Comment thread
philsttr marked this conversation as resolved.
Outdated
MDC.put("excludedKey", "excludedValue");
MDC.put("otel.event.name", "MyEventName");
try {
logger.info("xyz");
} finally {
MDC.remove("key1");
MDC.remove("key2");
MDC.remove("excludedKey");
MDC.remove("otel.event.name");
}

Expand Down
4 changes: 3 additions & 1 deletion instrumentation/log4j/log4j-appender-1.2/metadata.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ configurations:
declarative_name: java.log4j_appender.capture_mdc_attributes/development
description: >
Controls which MDC attributes to capture. Use "*" to capture all MDC attributes or provide a
comma-separated list of specific keys.
comma-separated list of specific keys. When using "*", prefix a key with "!" to exclude it
(e.g. "*,!foo" captures all MDC attributes except "foo").
type: list
default: ''
examples:
- "custom-mdc-key"
- "key1,key2,key3"
- "*,!foo"
- name: otel.instrumentation.log4j-appender.experimental.capture-code-attributes
declarative_name: java.log4j_appender.capture_code_attributes/development
description: >
Expand Down
Loading
Loading