Skip to content

Commit

Permalink
Preserve attribute type for logback key value pairs (#10781)
Browse files Browse the repository at this point in the history
  • Loading branch information
laurit authored Mar 12, 2024
1 parent f979851 commit 2df9001
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,21 @@ private static void captureKeyValuePairAttributes(
List<KeyValuePair> keyValuePairs = loggingEvent.getKeyValuePairs();
if (keyValuePairs != null) {
for (KeyValuePair keyValuePair : keyValuePairs) {
Object value = keyValuePair.value;
if (keyValuePair.value != null) {
attributes.put(getAttributeKey(keyValuePair.key), keyValuePair.value.toString());
// preserve type for boolean and numeric values, everything else is converted to String
if (value instanceof Boolean) {
attributes.put(keyValuePair.key, (Boolean) keyValuePair.value);
} else if (value instanceof Byte
|| value instanceof Integer
|| value instanceof Long
|| value instanceof Short) {
attributes.put(keyValuePair.key, ((Number) keyValuePair.value).longValue());
} else if (value instanceof Double || value instanceof Float) {
attributes.put(keyValuePair.key, ((Number) keyValuePair.value).doubleValue());
} else {
attributes.put(getAttributeKey(keyValuePair.key), keyValuePair.value.toString());
}
}
}
}
Expand All @@ -236,7 +249,7 @@ private static void captureLoggerContext(
}

public static AttributeKey<String> getAttributeKey(String key) {
return attributeKeys.computeIfAbsent(key, k -> AttributeKey.stringKey(k));
return attributeKeys.computeIfAbsent(key, AttributeKey::stringKey);
}

private static boolean supportsKeyValuePairs() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package io.opentelemetry.instrumentation.logback.appender.v1_0;

import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;

import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.sdk.OpenTelemetrySdk;
Expand Down Expand Up @@ -55,18 +56,37 @@ void setup() {

@Test
void keyValue() {
logger.atInfo().setMessage("log message 1").addKeyValue("key", "value").log();
logger
.atInfo()
.setMessage("log message 1")
.addKeyValue("string key", "string value")
.addKeyValue("boolean key", true)
.addKeyValue("byte key", (byte) 1)
.addKeyValue("short key", (short) 2)
.addKeyValue("int key", 3)
.addKeyValue("long key", 4L)
.addKeyValue("float key", 5.0f)
.addKeyValue("double key", 6.0)
.log();

List<LogRecordData> logDataList = logRecordExporter.getFinishedLogRecordItems();
assertThat(logDataList).hasSize(1);
LogRecordData logData = logDataList.get(0);
assertThat(logData.getResource()).isEqualTo(resource);
assertThat(logData.getInstrumentationScopeInfo()).isEqualTo(instrumentationScopeInfo);
assertThat(logData.getBody().asString()).isEqualTo("log message 1");
assertThat(logData.getAttributes().size()).isEqualTo(5); // 4 code attributes + 1 key value pair
assertThat(logData.getAttributes())
.hasEntrySatisfying(
AttributeKey.stringKey("key"), value -> assertThat(value).isEqualTo("value"));
assertThat(logData.getAttributes().size())
.isEqualTo(12); // 4 code attributes + 8 key value pairs
assertThat(logData)
.hasAttributesSatisfying(
equalTo(AttributeKey.stringKey("string key"), "string value"),
equalTo(AttributeKey.booleanKey("boolean key"), true),
equalTo(AttributeKey.longKey("byte key"), 1),
equalTo(AttributeKey.longKey("short key"), 2),
equalTo(AttributeKey.longKey("int key"), 3),
equalTo(AttributeKey.longKey("long key"), 4),
equalTo(AttributeKey.doubleKey("float key"), 5.0),
equalTo(AttributeKey.doubleKey("double key"), 6.0));
}

@Test
Expand Down

0 comments on commit 2df9001

Please sign in to comment.