Skip to content

Commit 07ef9f9

Browse files
committed
Add option for logback to capture message template
Added a new `captureTemplate` option to the logback `OpenTelemetryAppender`. Default is false. The new option captures the unformatted log message template in the `log.body.template` log event attribute. Enable in the library by configuring the `OpenTelemetryAppender` with `<captureTemplate>true</captureTemplate>`. Enable in the javaagent by setting `otel.instrumentation.logback-appender.experimental.capture-template=true`. The existing `captureArguments` option previously enabled both capturing the template and arguments. Now `captureArguments` only enables capturing arguments (not the message template). This is a backwards incompatible change to an experimental config option. Users currently setting `captureArguments=true` would now need to set both `captureArguments=true` and `captureTemplate=true` to maintain previous behavior.
1 parent 1951761 commit 07ef9f9

File tree

7 files changed

+48
-11
lines changed

7 files changed

+48
-11
lines changed

instrumentation/logback/logback-appender-1.0/javaagent/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
| `otel.instrumentation.logback-appender.experimental.capture-marker-attribute` | Boolean | `false` | Enable the capture of Logback markers as attributes. |
88
| `otel.instrumentation.logback-appender.experimental.capture-key-value-pair-attributes` | Boolean | `false` | Enable the capture of Logback key value pairs as attributes. |
99
| `otel.instrumentation.logback-appender.experimental.capture-logger-context-attributes` | Boolean | `false` | Enable the capture of Logback logger context properties as attributes. |
10-
| `otel.instrumentation.logback-appender.experimental.capture-arguments` | Boolean | `false` | Enable the capture of Logback logger arguments. |
10+
| `otel.instrumentation.logback-appender.experimental.capture-template` | Boolean | `false` | Enable the capture of Logback log event message template. |
11+
| `otel.instrumentation.logback-appender.experimental.capture-arguments` | Boolean | `false` | Enable the capture of Logback log event arguments. |
1112
| `otel.instrumentation.logback-appender.experimental.capture-logstash-marker-attributes` | Boolean | `false` | Enable the capture of Logstash markers, supported are those added to logs via `Markers.append()`, `Markers.appendEntries()`, `Markers.appendArray()` and `Markers.appendRaw()` methods. |
1213
| `otel.instrumentation.logback-appender.experimental.capture-logstash-structured-arguments` | Boolean | `false` | Enable the capture of Logstash StructuredArguments as attributes (e.g., `StructuredArguments.v()` and `StructuredArguments.keyValue()`). |
1314
| `otel.instrumentation.logback-appender.experimental.capture-mdc-attributes` | String | | Comma separated list of MDC attributes to capture. Use the wildcard character `*` to capture all attributes. |

instrumentation/logback/logback-appender-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/logback/appender/v1_0/LogbackSingletons.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ public final class LogbackSingletons {
3737
config.getBoolean(
3838
"otel.instrumentation.logback-appender.experimental.capture-logger-context-attributes",
3939
false);
40+
boolean captureTemplate =
41+
config.getBoolean(
42+
"otel.instrumentation.logback-appender.experimental.capture-template", false);
4043
boolean captureArguments =
4144
config.getBoolean(
4245
"otel.instrumentation.logback-appender.experimental.capture-arguments", false);
@@ -66,6 +69,7 @@ public final class LogbackSingletons {
6669
.setCaptureMarkerAttribute(captureMarkerAttribute)
6770
.setCaptureKeyValuePairAttributes(captureKeyValuePairAttributes)
6871
.setCaptureLoggerContext(captureLoggerContext)
72+
.setCaptureTemplate(captureTemplate)
6973
.setCaptureArguments(captureArguments)
7074
.setCaptureLogstashMarkerAttributes(captureLogstashMarkerAttributes)
7175
.setCaptureLogstashStructuredArguments(captureLogstashStructuredArguments)

instrumentation/logback/logback-appender-1.0/library/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,10 @@ The available settings are:
100100
| `captureMarkerAttribute` | Boolean | `false` | Enable the capture of Logback markers as attributes. |
101101
| `captureKeyValuePairAttributes` | Boolean | `false` | Enable the capture of Logback key value pairs as attributes. |
102102
| `captureLoggerContext` | Boolean | `false` | Enable the capture of Logback logger context properties as attributes. |
103-
| `captureArguments` | Boolean | `false` | Enable the capture of Logback logger arguments. |
103+
| `captureTemplate` | Boolean | `false` | Enable the capture of Logback log event message template. |
104+
| `captureArguments` | Boolean | `false` | Enable the capture of Logback log event arguments. |
104105
| `captureLogstashMarkerAttributes` | Boolean | `false` | Enable the capture of Logstash markers, supported are those added to logs via `Markers.append()`, `Markers.appendEntries()`, `Markers.appendArray()` and `Markers.appendRaw()` methods. |
105-
| `captureLogstashStructuredArguments` | Boolean | `false` | Enable the capture of Logstash StructuredArguments as attributes (e.g., `StructuredArguments.v()` and `StructuredArguments.keyValue()`). |
106+
| `captureLogstashStructuredArguments` | Boolean | `false` | Enable the capture of Logstash StructuredArguments as attributes (e.g., `StructuredArguments.v()` and `StructuredArguments.keyValue()`). |
106107
| `captureMdcAttributes` | String | | Comma separated list of MDC attributes to capture. Use the wildcard character `*` to capture all attributes. |
107108
| `captureEventName` | Boolean | `false` | Enable moving the `event.name` attribute (captured by one of the other mechanisms of capturing attributes) to the log event name. |
108109
| `numLogsCapturedBeforeOtelInstall` | Integer | 1000 | Log telemetry is emitted after the initialization of the OpenTelemetry Logback appender with an OpenTelemetry object. This setting allows you to modify the size of the cache used to replay the first logs. thread.id attribute is not captured. |

instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/OpenTelemetryAppender.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public class OpenTelemetryAppender extends UnsynchronizedAppenderBase<ILoggingEv
3535
private boolean captureMarkerAttribute = false;
3636
private boolean captureKeyValuePairAttributes = false;
3737
private boolean captureLoggerContext = false;
38+
private boolean captureTemplate = false;
3839
private boolean captureArguments = false;
3940
private boolean captureLogstashMarkerAttributes = false;
4041
private boolean captureLogstashStructuredArguments = false;
@@ -88,6 +89,7 @@ public void start() {
8889
.setCaptureMarkerAttribute(captureMarkerAttribute)
8990
.setCaptureKeyValuePairAttributes(captureKeyValuePairAttributes)
9091
.setCaptureLoggerContext(captureLoggerContext)
92+
.setCaptureTemplate(captureTemplate)
9193
.setCaptureArguments(captureArguments)
9294
.setCaptureLogstashMarkerAttributes(captureLogstashMarkerAttributes)
9395
.setCaptureLogstashStructuredArguments(captureLogstashStructuredArguments)
@@ -177,6 +179,15 @@ public void setCaptureLoggerContext(boolean captureLoggerContext) {
177179
this.captureLoggerContext = captureLoggerContext;
178180
}
179181

182+
/**
183+
* Sets whether the message template should be captured in logs
184+
*
185+
* @param captureTemplate whether the message template should be captured in logs
186+
*/
187+
public void setCaptureTemplate(boolean captureTemplate) {
188+
this.captureTemplate = captureTemplate;
189+
}
190+
180191
/**
181192
* Sets whether the arguments should be set to logs.
182193
*

instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ public final class LoggingEventMapper {
8484
private final boolean captureMarkerAttribute;
8585
private final boolean captureKeyValuePairAttributes;
8686
private final boolean captureLoggerContext;
87+
private final boolean captureTemplate;
8788
private final boolean captureArguments;
8889
private final boolean captureLogstashMarkerAttributes;
8990
private final boolean captureLogstashStructuredArguments;
@@ -96,6 +97,7 @@ private LoggingEventMapper(Builder builder) {
9697
this.captureMarkerAttribute = builder.captureMarkerAttribute;
9798
this.captureKeyValuePairAttributes = builder.captureKeyValuePairAttributes;
9899
this.captureLoggerContext = builder.captureLoggerContext;
100+
this.captureTemplate = builder.captureTemplate;
99101
this.captureArguments = builder.captureArguments;
100102
this.captureLogstashMarkerAttributes = builder.captureLogstashMarkerAttributes;
101103
this.captureLogstashStructuredArguments = builder.captureLogstashStructuredArguments;
@@ -215,10 +217,14 @@ private void mapLoggingEvent(
215217
captureLoggerContext(builder, loggingEvent.getLoggerContextVO().getPropertyMap());
216218
}
217219

220+
if (captureTemplate) {
221+
captureTemplate(builder, loggingEvent);
222+
}
223+
218224
if (captureArguments
219225
&& loggingEvent.getArgumentArray() != null
220226
&& loggingEvent.getArgumentArray().length > 0) {
221-
captureArguments(builder, loggingEvent.getMessage(), loggingEvent.getArgumentArray());
227+
captureArguments(builder, loggingEvent.getArgumentArray());
222228
}
223229

224230
if (supportsLogstashMarkers && captureLogstashMarkerAttributes) {
@@ -265,8 +271,11 @@ void captureMdcAttributes(LogRecordBuilder builder, Map<String, String> mdcPrope
265271
}
266272
}
267273

268-
void captureArguments(LogRecordBuilder builder, String message, Object[] arguments) {
269-
builder.setAttribute(LOG_BODY_TEMPLATE, message);
274+
private static void captureTemplate(LogRecordBuilder builder, ILoggingEvent loggingEvent) {
275+
builder.setAttribute(LOG_BODY_TEMPLATE, loggingEvent.getMessage());
276+
}
277+
278+
private static void captureArguments(LogRecordBuilder builder, Object[] arguments) {
270279
builder.setAttribute(
271280
LOG_BODY_PARAMETERS,
272281
Arrays.stream(arguments).map(String::valueOf).collect(Collectors.toList()));
@@ -679,6 +688,7 @@ public static final class Builder {
679688
private boolean captureMarkerAttribute;
680689
private boolean captureKeyValuePairAttributes;
681690
private boolean captureLoggerContext;
691+
private boolean captureTemplate;
682692
private boolean captureArguments;
683693
private boolean captureLogstashMarkerAttributes;
684694
private boolean captureLogstashStructuredArguments;
@@ -722,6 +732,12 @@ public Builder setCaptureLoggerContext(boolean captureLoggerContext) {
722732
return this;
723733
}
724734

735+
@CanIgnoreReturnValue
736+
public Builder setCaptureTemplate(boolean captureTemplate) {
737+
this.captureTemplate = captureTemplate;
738+
return this;
739+
}
740+
725741
@CanIgnoreReturnValue
726742
public Builder setCaptureArguments(boolean captureArguments) {
727743
this.captureArguments = captureArguments;

instrumentation/logback/logback-appender-1.0/library/src/slf4j2ApiTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/Slf4j2Test.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ void keyValue() {
6060
.hasResource(resource)
6161
.hasInstrumentationScope(instrumentationScopeInfo)
6262
.hasBody("log message 1")
63-
.hasTotalAttributeCount(codeAttributesLogCount() + 8) // 8 key value pairs
63+
.hasTotalAttributeCount(
64+
codeAttributesLogCount() + 9) // 8 key value pairs + 1 template
6465
.hasEventName("MyEventName")
6566
.hasAttributesSatisfying(
6667
equalTo(AttributeKey.stringKey("string key"), "string value"),
@@ -70,7 +71,8 @@ void keyValue() {
7071
equalTo(AttributeKey.longKey("int key"), 3),
7172
equalTo(AttributeKey.longKey("long key"), 4),
7273
equalTo(AttributeKey.doubleKey("float key"), 5.0),
73-
equalTo(AttributeKey.doubleKey("double key"), 6.0)));
74+
equalTo(AttributeKey.doubleKey("double key"), 6.0),
75+
equalTo(AttributeKey.stringKey("log.body.template"), "log message 1")));
7476
}
7577

7678
@Test
@@ -90,15 +92,16 @@ void multipleMarkers() {
9092
.hasResource(resource)
9193
.hasInstrumentationScope(instrumentationScopeInfo)
9294
.hasBody("log message 1")
93-
.hasTotalAttributeCount(codeAttributesLogCount() + 1) // 1 marker
95+
.hasTotalAttributeCount(codeAttributesLogCount() + 2) // 1 marker + 1 template
9496
.hasAttributesSatisfying(
9597
equalTo(
9698
AttributeKey.stringArrayKey("logback.marker"),
97-
Arrays.asList(markerName1, markerName2))));
99+
Arrays.asList(markerName1, markerName2)),
100+
equalTo(AttributeKey.stringKey("log.body.template"), "log message 1")));
98101
}
99102

100103
@Test
101-
void arguments() {
104+
void argumentsAndTemplate() {
102105
logger
103106
.atInfo()
104107
.setMessage("log message {} and {}, bool {}, long {}")

instrumentation/logback/logback-appender-1.0/library/src/slf4j2ApiTest/resources/logback-test.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<captureCodeAttributes>true</captureCodeAttributes>
1515
<captureMarkerAttribute>true</captureMarkerAttribute>
1616
<captureKeyValuePairAttributes>true</captureKeyValuePairAttributes>
17+
<captureTemplate>true</captureTemplate>
1718
<captureArguments>true</captureArguments>
1819
<captureLogstashMarkerAttributes>true</captureLogstashMarkerAttributes>
1920
<captureLogstashStructuredArguments>true</captureLogstashStructuredArguments>

0 commit comments

Comments
 (0)