Skip to content

Commit 7f02648

Browse files
committed
Add event naming capturing for log4j-appender-1.2
1 parent 7588ee5 commit 7f02648

File tree

4 files changed

+50
-26
lines changed

4 files changed

+50
-26
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Settings for the Log4j Appender instrumentation
2+
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-mdc-attributes` | String | | Comma separated list of context data attributes to capture. Use the wildcard character `*` to capture all attributes. |
8+
| `otel.instrumentation.log4j-appender.experimental.capture-event-name` | Boolean | `false` | Enable moving the `event.name` attribute (captured by one of the other mechanisms of capturing attributes) to the log event name. |
9+
10+
[source code attributes]: https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/attributes.md#source-code-attributes

instrumentation/log4j/log4j-appender-1.2/javaagent/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ tasks.withType<Test>().configureEach {
3535
// TODO run tests both with and without experimental log attributes
3636
jvmArgs("-Dotel.instrumentation.log4j-appender.experimental.capture-mdc-attributes=*")
3737
jvmArgs("-Dotel.instrumentation.log4j-appender.experimental.capture-code-attributes=true")
38-
jvmArgs("-Dotel.instrumentation.log4j-appender.experimental-log-attributes=true")
38+
jvmArgs("-Dotel.instrumentation.log4j-appender.experimental.capture-event-name=true")
3939
jvmArgs("-Dotel.instrumentation.log4j-appender.experimental-log-attributes=true")
4040
jvmArgs("-Dotel.instrumentation.common.experimental.controller-telemetry.enabled=true")
4141
}

instrumentation/log4j/log4j-appender-1.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/log4j/appender/v1_2/LogEventMapper.java

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99

1010
import io.opentelemetry.api.GlobalOpenTelemetry;
1111
import io.opentelemetry.api.common.AttributeKey;
12-
import io.opentelemetry.api.common.Attributes;
13-
import io.opentelemetry.api.common.AttributesBuilder;
1412
import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder;
1513
import io.opentelemetry.api.logs.LogRecordBuilder;
1614
import io.opentelemetry.api.logs.Severity;
@@ -44,6 +42,8 @@ public final class LogEventMapper {
4442
private static final AttributeKey<Long> CODE_LINENO = AttributeKey.longKey("code.lineno");
4543
private static final AttributeKey<String> CODE_NAMESPACE =
4644
AttributeKey.stringKey("code.namespace");
45+
// copied from EventIncubatingAttributes
46+
private static final AttributeKey<String> EVENT_NAME = AttributeKey.stringKey("event.name");
4747
// copied from org.apache.log4j.Level because it was only introduced in 1.2.12
4848
private static final int TRACE_INT = 5000;
4949

@@ -56,6 +56,10 @@ public final class LogEventMapper {
5656
// cached as an optimization
5757
private final boolean captureAllMdcAttributes;
5858

59+
private final boolean captureEventName =
60+
AgentInstrumentationConfig.get()
61+
.getBoolean("otel.instrumentation.log4j-appender.experimental.capture-event-name", false);
62+
5963
private LogEventMapper() {
6064
List<String> captureMdcAttributes =
6165
AgentInstrumentationConfig.get()
@@ -98,49 +102,47 @@ public void capture(
98102
builder.setSeverityText(level.toString());
99103
}
100104

101-
AttributesBuilder attributes = Attributes.builder();
102-
103105
// throwable
104106
if (throwable != null) {
105107
if (builder instanceof ExtendedLogRecordBuilder) {
106108
((ExtendedLogRecordBuilder) builder).setException(throwable);
107109
} else {
108-
attributes.put(ExceptionAttributes.EXCEPTION_TYPE, throwable.getClass().getName());
109-
attributes.put(ExceptionAttributes.EXCEPTION_MESSAGE, throwable.getMessage());
110+
builder.setAttribute(ExceptionAttributes.EXCEPTION_TYPE, throwable.getClass().getName());
111+
builder.setAttribute(ExceptionAttributes.EXCEPTION_MESSAGE, throwable.getMessage());
110112
StringWriter writer = new StringWriter();
111113
throwable.printStackTrace(new PrintWriter(writer));
112-
attributes.put(ExceptionAttributes.EXCEPTION_STACKTRACE, writer.toString());
114+
builder.setAttribute(ExceptionAttributes.EXCEPTION_STACKTRACE, writer.toString());
113115
}
114116
}
115117

116-
captureMdcAttributes(attributes);
118+
captureMdcAttributes(builder);
117119

118120
if (captureExperimentalAttributes) {
119121
Thread currentThread = Thread.currentThread();
120-
attributes.put(ThreadIncubatingAttributes.THREAD_NAME, currentThread.getName());
121-
attributes.put(ThreadIncubatingAttributes.THREAD_ID, currentThread.getId());
122+
builder.setAttribute(ThreadIncubatingAttributes.THREAD_NAME, currentThread.getName());
123+
builder.setAttribute(ThreadIncubatingAttributes.THREAD_ID, currentThread.getId());
122124
}
123125

124126
if (captureCodeAttributes) {
125127
LocationInfo locationInfo = new LocationInfo(new Throwable(), fqcn);
126128
String fileName = locationInfo.getFileName();
127129
if (fileName != null) {
128130
if (SemconvStability.isEmitStableCodeSemconv()) {
129-
attributes.put(CodeAttributes.CODE_FILE_PATH, fileName);
131+
builder.setAttribute(CodeAttributes.CODE_FILE_PATH, fileName);
130132
}
131133
if (SemconvStability.isEmitOldCodeSemconv()) {
132-
attributes.put(CODE_FILEPATH, fileName);
134+
builder.setAttribute(CODE_FILEPATH, fileName);
133135
}
134136
}
135137

136138
if (SemconvStability.isEmitStableCodeSemconv()) {
137-
attributes.put(
139+
builder.setAttribute(
138140
CodeAttributes.CODE_FUNCTION_NAME,
139141
locationInfo.getClassName() + "." + locationInfo.getMethodName());
140142
}
141143
if (SemconvStability.isEmitOldCodeSemconv()) {
142-
attributes.put(CODE_NAMESPACE, locationInfo.getClassName());
143-
attributes.put(CODE_FUNCTION, locationInfo.getMethodName());
144+
builder.setAttribute(CODE_NAMESPACE, locationInfo.getClassName());
145+
builder.setAttribute(CODE_FUNCTION, locationInfo.getMethodName());
144146
}
145147

146148
String lineNumber = locationInfo.getLineNumber();
@@ -154,49 +156,58 @@ public void capture(
154156
}
155157
if (codeLineNo >= 0) {
156158
if (SemconvStability.isEmitStableCodeSemconv()) {
157-
attributes.put(CodeAttributes.CODE_LINE_NUMBER, codeLineNo);
159+
builder.setAttribute(CodeAttributes.CODE_LINE_NUMBER, (long) codeLineNo);
158160
}
159161
if (SemconvStability.isEmitOldCodeSemconv()) {
160-
attributes.put(CODE_LINENO, codeLineNo);
162+
builder.setAttribute(CODE_LINENO, (long) codeLineNo);
161163
}
162164
}
163165
}
164166

165-
builder.setAllAttributes(attributes.build());
166-
167167
// span context
168168
builder.setContext(Context.current());
169169

170170
builder.setTimestamp(Instant.now());
171171
builder.emit();
172172
}
173173

174-
private void captureMdcAttributes(AttributesBuilder attributes) {
174+
private void captureMdcAttributes(LogRecordBuilder builder) {
175175

176176
Hashtable<?, ?> context = MDC.getContext();
177177

178178
if (captureAllMdcAttributes) {
179179
if (context != null) {
180180
for (Map.Entry<?, ?> entry : context.entrySet()) {
181-
attributes.put(
182-
getMdcAttributeKey(String.valueOf(entry.getKey())), String.valueOf(entry.getValue()));
181+
setAttributeOrEventName(
182+
builder,
183+
getMdcAttributeKey(String.valueOf(entry.getKey())),
184+
String.valueOf(entry.getValue()));
183185
}
184186
}
185187
return;
186188
}
187189

188190
for (Map.Entry<String, AttributeKey<String>> entry : captureMdcAttributes.entrySet()) {
189191
Object value = context.get(entry.getKey());
190-
if (value != null) {
191-
attributes.put(entry.getValue(), value.toString());
192-
}
192+
setAttributeOrEventName(builder, getMdcAttributeKey(entry.getKey()), value);
193193
}
194194
}
195195

196196
private static AttributeKey<String> getMdcAttributeKey(String key) {
197197
return mdcAttributeKeys.computeIfAbsent(key, AttributeKey::stringKey);
198198
}
199199

200+
private void setAttributeOrEventName(
201+
LogRecordBuilder builder, AttributeKey<String> key, Object value) {
202+
if (value != null) {
203+
if (captureEventName && key.equals(EVENT_NAME)) {
204+
builder.setEventName(value.toString());
205+
} else {
206+
builder.setAttribute(key, value.toString());
207+
}
208+
}
209+
}
210+
200211
private static Severity levelToSeverity(Priority level) {
201212
int lev = level.toInt();
202213
if (lev <= TRACE_INT) {

instrumentation/log4j/log4j-appender-1.2/javaagent/src/test/java/io/opentelemetry/instrumentation/log4j/appender/v1_2/Log4j1Test.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,13 @@ private static void test(
176176
void testMdc() {
177177
MDC.put("key1", "val1");
178178
MDC.put("key2", "val2");
179+
MDC.put("event.name", "MyEventName");
179180
try {
180181
logger.info("xyz");
181182
} finally {
182183
MDC.remove("key1");
183184
MDC.remove("key2");
185+
MDC.remove("event.name");
184186
}
185187

186188
List<AttributeAssertion> assertions =
@@ -195,6 +197,7 @@ void testMdc() {
195197
logRecord ->
196198
logRecord
197199
.hasBody("xyz")
200+
.hasEventName("MyEventName")
198201
.hasInstrumentationScope(InstrumentationScopeInfo.builder("abc").build())
199202
.hasSeverity(Severity.INFO)
200203
.hasSeverityText("INFO")

0 commit comments

Comments
 (0)