Skip to content

Commit 4231e39

Browse files
committed
Capture event name in logback/log4j/jboss-logmanager instrumentation
Added a new capture-event-name configuration option to logback/log4j/jboss-logmanager library/javaagent instrumentation that, when true, 1. captures the log event name from the recently undeprecated semantic attribute named `event.name`, and 2. removes the `event.name` attribute from the log event. This allows the log event name to be specified when logging using standard log APIs, rather than having to use the OpenTelemetry SDK log APIs directly. The `event.name` attribute can be captured using any attribute capturing mechanism supported by the log instrumentation. For example, if logback-appender's `captureKeyValuePairAttributes` is true, then an application can specify the `event.name` attribute via an slf4j key/value when logging. Capturing the event name is enabled with the following configuration values, depending on what you're using: * logback-appender-1.0/library - `io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender` - `captureEventName` * logback-appender-1.0/javaagent - `otel.instrumentation.logback-appender.experimental.capture-event-name` * log4j-appender-2.17/library - `io.opentelemetry.instrumentation.log4j.appender.v2_17.OpenTelemetryAppender` - `captureEventName` * log4j-appender-2.17/javaagent - `otel.instrumentation.log4j-appender.experimental.capture-event-name` * jboss-logmanager-appender-1.1/javaagent - `otel.instrumentation.jboss-logmanager.experimental.capture-event-name` Fixes: gh-14632
1 parent f44456e commit 4231e39

File tree

21 files changed

+194
-44
lines changed

21 files changed

+194
-44
lines changed
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Settings for the JBoss Log Manager instrumentation
22

3-
| System property | Type | Default | Description |
4-
|-----------------------------------------------------------------------------|---------|---------|--------------------------------------------------------------------------------------------------------------|
5-
| `otel.instrumentation.jboss-logmanager.experimental-log-attributes` | Boolean | `false` | Enable the capture of experimental log attributes `thread.name` and `thread.id`. |
6-
| `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. |
3+
| System property | Type | Default | Description |
4+
|-----------------------------------------------------------------------------|---------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
5+
| `otel.instrumentation.jboss-logmanager.experimental-log-attributes` | Boolean | `false` | Enable the capture of experimental log attributes `thread.name` and `thread.id`. |
6+
| `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. |
7+
| `otel.instrumentation.jboss-logmanager.experimental.capture-event-name` | Boolean | `true` | Enable the capture of the log event name from the `event.name` attribute (captured via one of the above means). When true, the `event.name` attribute will be used as the log event name, and the `event.name` attribute will be removed. |

instrumentation/jboss-logmanager/jboss-logmanager-appender-1.1/javaagent/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ if (latestDepTest) {
3333
tasks.withType<Test>().configureEach {
3434
// TODO run tests both with and without experimental log attributes
3535
jvmArgs("-Dotel.instrumentation.jboss-logmanager.experimental.capture-mdc-attributes=*")
36+
jvmArgs("-Dotel.instrumentation.jboss-logmanager.experimental.capture-event-name=true")
3637
jvmArgs("-Dotel.instrumentation.jboss-logmanager.experimental-log-attributes=true")
3738
jvmArgs("-Dotel.instrumentation.java-util-logging.experimental-log-attributes=true")
3839
}

instrumentation/jboss-logmanager/jboss-logmanager-appender-1.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jbosslogmanager/appender/v1_1/LoggingEventMapper.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ public final class LoggingEventMapper {
3030

3131
public static final LoggingEventMapper INSTANCE = new LoggingEventMapper();
3232

33+
// copied from EventIncubatingAttributes
34+
private static final AttributeKey<String> EVENT_NAME = AttributeKey.stringKey("event.name");
3335
private static final Cache<String, AttributeKey<String>> mdcAttributeKeys = Cache.bounded(100);
3436

3537
private final List<String> captureMdcAttributes;
@@ -41,6 +43,11 @@ public final class LoggingEventMapper {
4143
// cached as an optimization
4244
private final boolean captureAllMdcAttributes;
4345

46+
private final boolean captureEventName =
47+
AgentInstrumentationConfig.get()
48+
.getBoolean(
49+
"otel.instrumentation.jboss-logmanager.experimental.capture-event-name", false);
50+
4451
private LoggingEventMapper() {
4552
this.captureMdcAttributes =
4653
AgentInstrumentationConfig.get()
@@ -90,7 +97,21 @@ public void capture(Logger logger, ExtLogRecord record) {
9097
attributes.put(ThreadIncubatingAttributes.THREAD_ID, currentThread.getId());
9198
}
9299

93-
builder.setAllAttributes(attributes.build());
100+
Attributes realizedAttributes = attributes.build();
101+
if (captureEventName) {
102+
realizedAttributes.forEach(
103+
(attributeKey, value) -> {
104+
if (attributeKey.equals(EVENT_NAME)) {
105+
builder.setEventName(String.valueOf(value));
106+
} else {
107+
@SuppressWarnings("unchecked")
108+
AttributeKey<Object> attributeKeyAsObject = (AttributeKey<Object>) attributeKey;
109+
builder.setAttribute(attributeKeyAsObject, value);
110+
}
111+
});
112+
} else {
113+
builder.setAllAttributes(realizedAttributes);
114+
}
94115

95116
builder.setContext(Context.current());
96117

instrumentation/jboss-logmanager/jboss-logmanager-appender-1.1/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jbosslogmanager/appender/v1_1/JbossLogmanagerTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,11 +202,13 @@ private static void performLogging(
202202
void testMdc() {
203203
MDC.put("key1", "val1");
204204
MDC.put("key2", "val2");
205+
MDC.put("event.name", "MyEventName");
205206
try {
206207
logger.info("xyz");
207208
} finally {
208209
MDC.remove("key1");
209210
MDC.remove("key2");
211+
MDC.remove("event.name");
210212
}
211213

212214
testing.waitAndAssertLogRecords(
@@ -216,6 +218,7 @@ void testMdc() {
216218
.hasInstrumentationScope(InstrumentationScopeInfo.builder("abc").build())
217219
.hasSeverity(Severity.INFO)
218220
.hasSeverityText("INFO")
221+
.hasEventName("MyEventName")
219222
.hasAttributesSatisfyingExactly(
220223
equalTo(AttributeKey.stringKey("key1"), "val1"),
221224
equalTo(AttributeKey.stringKey("key2"), "val2"),
Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
# Settings for the Log4j Appender instrumentation
22

3-
| System property | Type | Default | Description |
4-
|-----------------------------------------------------------------------------------|---------|---------|-----------------------------------------------------------------------------------------------------------------------------------------------|
5-
| `otel.instrumentation.log4j-appender.experimental-log-attributes` | Boolean | `false` | Enable the capture of experimental log attributes `thread.name` and `thread.id`. |
6-
| `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. |
7-
| `otel.instrumentation.log4j-appender.experimental.capture-map-message-attributes` | Boolean | `false` | Enable the capture of `MapMessage` attributes. |
8-
| `otel.instrumentation.log4j-appender.experimental.capture-marker-attribute` | Boolean | `false` | Enable the capture of Log4j markers as attributes. |
9-
| `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. |
3+
| System property | Type | Default | Description |
4+
|-----------------------------------------------------------------------------------|---------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
5+
| `otel.instrumentation.log4j-appender.experimental-log-attributes` | Boolean | `false` | Enable the capture of experimental log attributes `thread.name` and `thread.id`. |
6+
| `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. |
7+
| `otel.instrumentation.log4j-appender.experimental.capture-map-message-attributes` | Boolean | `false` | Enable the capture of `MapMessage` attributes. |
8+
| `otel.instrumentation.log4j-appender.experimental.capture-marker-attribute` | Boolean | `false` | Enable the capture of Log4j markers as attributes. |
9+
| `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. |
10+
| `otel.instrumentation.log4j-appender.experimental.capture-event-name` | Boolean | `false` | Enable the capture of the log event name from the `event.name` attribute (captured via one of the above means). When true, the `event.name` attribute will be used as the log event name, and the `event.name` attribute will be removed. |
1011

1112
[source code attributes]: https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/attributes.md#source-code-attributes

instrumentation/log4j/log4j-appender-2.17/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/log4j/appender/v2_17/Log4jHelper.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ public final class Log4jHelper {
5252
List<String> captureContextDataAttributes =
5353
config.getList(
5454
"otel.instrumentation.log4j-appender.experimental.capture-mdc-attributes", emptyList());
55+
boolean captureEventName =
56+
config.getBoolean(
57+
"otel.instrumentation.log4j-appender.experimental.capture-event-name", false);
5558

5659
mapper =
5760
new LogEventMapper<>(
@@ -60,7 +63,8 @@ public final class Log4jHelper {
6063
captureCodeAttributes,
6164
captureMapMessageAttributes,
6265
captureMarkerAttribute,
63-
captureContextDataAttributes);
66+
captureContextDataAttributes,
67+
captureEventName);
6468
}
6569

6670
public static void capture(

instrumentation/log4j/log4j-appender-2.17/library/README.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,14 @@ Setting can be configured as XML attributes, for example:
9292

9393
The available settings are:
9494

95-
| XML Attribute | Type | Default | Description |
96-
|------------------------------------|---------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
97-
| `captureExperimentalAttributes` | Boolean | `false` | Enable the capture of experimental log attributes `thread.name` and `thread.id`. |
98-
| `captureCodeAttributes` | Boolean | `false` | Enable the capture of [source code attributes]. Note that capturing source code attributes at logging sites might add a performance overhead. |
99-
| `captureMapMessageAttributes` | Boolean | `false` | Enable the capture of `MapMessage` attributes. |
100-
| `captureMarkerAttribute` | Boolean | `false` | Enable the capture of Log4j markers as attributes. |
101-
| `captureContextDataAttributes` | String | | Comma separated list of context data attributes to capture. Use the wildcard character `*` to capture all attributes. |
102-
| `numLogsCapturedBeforeOtelInstall` | Integer | 1000 | Log telemetry is emitted after the initialization of the OpenTelemetry Log4j appender with an OpenTelemetry object. This setting allows you to modify the size of the cache used to replay the first logs. |
95+
| XML Attribute | Type | Default | Description |
96+
|------------------------------------|---------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
97+
| `captureExperimentalAttributes` | Boolean | `false` | Enable the capture of experimental log attributes `thread.name` and `thread.id`. |
98+
| `captureCodeAttributes` | Boolean | `false` | Enable the capture of [source code attributes]. Note that capturing source code attributes at logging sites might add a performance overhead. |
99+
| `captureMapMessageAttributes` | Boolean | `false` | Enable the capture of `MapMessage` attributes. |
100+
| `captureMarkerAttribute` | Boolean | `false` | Enable the capture of Log4j markers as attributes. |
101+
| `captureContextDataAttributes` | String | | Comma separated list of context data attributes to capture. Use the wildcard character `*` to capture all attributes. |
102+
| `captureEventName` | Boolean | `false` | Enable the capture of the log event name from the `event.name` attribute (captured via one of the above means). When true, the `event.name` attribute will be used as the log event name, and the `event.name` attribute will be removed. |
103+
| `numLogsCapturedBeforeOtelInstall` | Integer | 1000 | Log telemetry is emitted after the initialization of the OpenTelemetry Log4j appender with an OpenTelemetry object. This setting allows you to modify the size of the cache used to replay the first logs. |
103104

104105
[source code attributes]: https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/attributes.md#source-code-attributes

instrumentation/log4j/log4j-appender-2.17/library/src/main/java/io/opentelemetry/instrumentation/log4j/appender/v2_17/OpenTelemetryAppender.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ public static class Builder<B extends Builder<B>> extends AbstractAppender.Build
101101
@PluginBuilderAttribute private boolean captureMapMessageAttributes;
102102
@PluginBuilderAttribute private boolean captureMarkerAttribute;
103103
@PluginBuilderAttribute private String captureContextDataAttributes;
104+
@PluginBuilderAttribute private boolean captureEventName;
104105
@PluginBuilderAttribute private int numLogsCapturedBeforeOtelInstall;
105106

106107
@Nullable private OpenTelemetry openTelemetry;
@@ -155,6 +156,24 @@ public B setCaptureContextDataAttributes(String captureContextDataAttributes) {
155156
return asBuilder();
156157
}
157158

159+
/**
160+
* Sets whether the value of the {@code event.name} attribute is used as the log event name.
161+
*
162+
* <p>The {@code event.name} attribute is captured via any other mechanism supported by this
163+
* appender, such as when {@code captureContextDataAttributes} includes {@code event.name}.
164+
*
165+
* <p>When {@code captureEventName} is true, then the value of the {@code event.name} attribute
166+
* will be used as the log event name, and {@code event.name} attribute will be removed.
167+
*
168+
* @param captureEventName to enable or disable capturing the {@code event.name} attribute as
169+
* the log event name
170+
*/
171+
@CanIgnoreReturnValue
172+
public B setCaptureEventName(boolean captureEventName) {
173+
this.captureEventName = captureEventName;
174+
return asBuilder();
175+
}
176+
158177
/**
159178
* Log telemetry is emitted after the initialization of the OpenTelemetry Logback appender with
160179
* an {@link OpenTelemetry} object. This setting allows you to modify the size of the cache used
@@ -188,6 +207,7 @@ public OpenTelemetryAppender build() {
188207
captureMapMessageAttributes,
189208
captureMarkerAttribute,
190209
captureContextDataAttributes,
210+
captureEventName,
191211
numLogsCapturedBeforeOtelInstall,
192212
openTelemetry);
193213
}
@@ -204,6 +224,7 @@ private OpenTelemetryAppender(
204224
boolean captureMapMessageAttributes,
205225
boolean captureMarkerAttribute,
206226
String captureContextDataAttributes,
227+
boolean captureEventName,
207228
int numLogsCapturedBeforeOtelInstall,
208229
OpenTelemetry openTelemetry) {
209230

@@ -215,7 +236,8 @@ private OpenTelemetryAppender(
215236
captureCodeAttributes,
216237
captureMapMessageAttributes,
217238
captureMarkerAttribute,
218-
splitAndFilterBlanksAndNulls(captureContextDataAttributes));
239+
splitAndFilterBlanksAndNulls(captureContextDataAttributes),
240+
captureEventName);
219241
this.openTelemetry = openTelemetry;
220242
this.captureCodeAttributes = captureCodeAttributes;
221243
if (numLogsCapturedBeforeOtelInstall != 0) {

0 commit comments

Comments
 (0)