diff --git a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/processors/DelegatingLogData.java b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/processors/DelegatingLogData.java index 6a1d395ec43..f598ff20218 100644 --- a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/processors/DelegatingLogData.java +++ b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/processors/DelegatingLogData.java @@ -6,6 +6,7 @@ import static java.util.Objects.requireNonNull; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.Value; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; @@ -59,10 +60,16 @@ public String getSeverityText() { } @Override + @SuppressWarnings("deprecation") // Implementation of deprecated method public Body getBody() { return delegate.getBody(); } + @Override + public Value getBodyValue() { + return delegate.getBodyValue(); + } + @Override public Attributes getAttributes() { return delegate.getAttributes(); @@ -100,8 +107,8 @@ public String toString() { + "severityText=" + getSeverityText() + ", " - + "body=" - + getBody() + + "bodyValue=" + + getBodyValue() + "}"; } } diff --git a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/processors/ExporterWithLogProcessor.java b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/processors/ExporterWithLogProcessor.java index 5d5ba53b0ba..751c8354cb5 100644 --- a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/processors/ExporterWithLogProcessor.java +++ b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/processors/ExporterWithLogProcessor.java @@ -5,6 +5,8 @@ import com.microsoft.applicationinsights.agent.internal.configuration.Configuration.ProcessorConfig; import com.microsoft.applicationinsights.agent.internal.processors.AgentProcessor.IncludeExclude; +import io.opentelemetry.api.common.Value; +import io.opentelemetry.api.common.ValueType; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.logs.export.LogRecordExporter; @@ -36,12 +38,22 @@ public CompletableResultCode export(Collection logs) { private LogRecordData process(LogRecordData log) { IncludeExclude include = logProcessor.getInclude(); - if (include != null && !include.isMatch(log.getAttributes(), log.getBody().asString())) { + Value bodyValue = log.getBodyValue(); + String body; + if (bodyValue == null) { + body = ""; + } else if (bodyValue.getType() == ValueType.STRING) { + body = bodyValue.asString(); + } else { + // TODO (trask) support complex log bodies + body = ""; + } + if (include != null && !include.isMatch(log.getAttributes(), body)) { // If Not included we can skip further processing return log; } IncludeExclude exclude = logProcessor.getExclude(); - if (exclude != null && exclude.isMatch(log.getAttributes(), log.getBody().asString())) { + if (exclude != null && exclude.isMatch(log.getAttributes(), body)) { return log; } diff --git a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/processors/LogProcessor.java b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/processors/LogProcessor.java index b089da9b3e5..5ccbd0d46ad 100644 --- a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/processors/LogProcessor.java +++ b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/processors/LogProcessor.java @@ -10,7 +10,6 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.AttributesBuilder; -import io.opentelemetry.sdk.logs.data.Body; import io.opentelemetry.sdk.logs.data.LogRecordData; import java.util.ArrayList; import java.util.List; @@ -84,7 +83,7 @@ public LogRecordData processFromAttributes(LogRecordData log) { updatedLogBuffer.setLength(updatedLogBuffer.length() - separator.length()); } - return new MyLogData(log, existingLogAttributes, Body.string(updatedLogBuffer.toString())); + return new MyLogData(log, existingLogAttributes, updatedLogBuffer.toString()); } return log; @@ -107,7 +106,7 @@ public LogRecordData processToAttributes(LogRecordData log) { applyRule(groupNames.get(i), toAttributeRulePatterns.get(i), bodyAsString, builder); } - return new MyLogData(log, builder.build(), Body.string(bodyAsString)); + return new MyLogData(log, builder.build(), bodyAsString); } public static boolean logHasAllFromAttributeKeys( diff --git a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/processors/MyLogData.java b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/processors/MyLogData.java index b5df5e2850c..47355329ba6 100644 --- a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/processors/MyLogData.java +++ b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/processors/MyLogData.java @@ -4,25 +4,40 @@ package com.microsoft.applicationinsights.agent.internal.processors; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.Value; import io.opentelemetry.sdk.logs.data.Body; import io.opentelemetry.sdk.logs.data.LogRecordData; +// backwards compatibility is just in case any extensions out there are using custom log processors +@SuppressWarnings("deprecation") // using deprecated Body for backwards compatibility public class MyLogData extends DelegatingLogData { private final Attributes attributes; private final Body body; + private final Value bodyValue; public MyLogData(LogRecordData delegate, Attributes attributes) { - this(delegate, attributes, delegate.getBody()); + this(delegate, attributes, delegate.getBodyValue(), delegate.getBody()); } - public MyLogData(LogRecordData delegate, Attributes attributes, Body body) { + public MyLogData(LogRecordData delegate, Attributes attributes, String body) { + this(delegate, attributes, Value.of(body), Body.string(body)); + } + + private MyLogData(LogRecordData delegate, Attributes attributes, Value bodyValue, Body body) { super(delegate); this.attributes = attributes; this.body = body; + this.bodyValue = bodyValue; + } + + @Override + public Value getBodyValue() { + return bodyValue; } @Override + @Deprecated public Body getBody() { return body; } diff --git a/agent/agent-tooling/src/test/java/com/microsoft/applicationinsights/agent/internal/processors/ExporterWithLogProcessorTest.java b/agent/agent-tooling/src/test/java/com/microsoft/applicationinsights/agent/internal/processors/ExporterWithLogProcessorTest.java index 4fddc756373..121b0756bed 100644 --- a/agent/agent-tooling/src/test/java/com/microsoft/applicationinsights/agent/internal/processors/ExporterWithLogProcessorTest.java +++ b/agent/agent-tooling/src/test/java/com/microsoft/applicationinsights/agent/internal/processors/ExporterWithLogProcessorTest.java @@ -13,6 +13,8 @@ import com.microsoft.applicationinsights.agent.internal.configuration.Configuration.ToAttributeConfig; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.Value; +import io.opentelemetry.api.common.ValueType; import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.logs.export.LogRecordExporter; import io.opentelemetry.sdk.testing.logs.TestLogRecordData; @@ -85,7 +87,10 @@ void simpleRenameLogMessageTest() { // verify that resulting logs are filtered in the way we want List result = mockExporter.getLogs(); LogRecordData resultLog = result.get(0); - assertThat(resultLog.getBody().asString()).isEqualTo("locationget1234"); + Value bodyValue = resultLog.getBodyValue(); + assertThat(bodyValue).isNotNull(); + assertThat(bodyValue.getType()).isEqualTo(ValueType.STRING); + assertThat(bodyValue.asString()).isEqualTo("locationget1234"); } @Test @@ -104,7 +109,10 @@ void simpleRenameLogWithSeparatorTest() { // verify that resulting logs are filtered in the way we want List result = mockExporter.getLogs(); LogRecordData resultLog = result.get(0); - assertThat(resultLog.getBody().asString()).isEqualTo("location::get::1234"); + Value bodyValue = resultLog.getBodyValue(); + assertThat(bodyValue).isNotNull(); + assertThat(bodyValue.getType()).isEqualTo(ValueType.STRING); + assertThat(bodyValue.asString()).isEqualTo("location::get::1234"); } @Test @@ -124,7 +132,10 @@ void simpleRenameLogWithMissingKeysTest() { // verify that resulting logs are filtered in the way we want List result = mockExporter.getLogs(); LogRecordData resultLog = result.get(0); - assertThat(resultLog.getBody().asString()).isEqualTo("location::get::1234"); + Value bodyValue = resultLog.getBodyValue(); + assertThat(bodyValue).isNotNull(); + assertThat(bodyValue.getType()).isEqualTo(ValueType.STRING); + assertThat(bodyValue.asString()).isEqualTo("location::get::1234"); } @Test @@ -169,7 +180,10 @@ void simpleToAttributesTest() { Objects.requireNonNull( resultLog.getAttributes().get(AttributeKey.stringKey("documentId")))) .isEqualTo("12345678"); - assertThat(resultLog.getBody().asString()).isEqualTo("/api/v1/document/{documentId}/update"); + Value bodyValue = resultLog.getBodyValue(); + assertThat(bodyValue).isNotNull(); + assertThat(bodyValue.getType()).isEqualTo(ValueType.STRING); + assertThat(bodyValue.asString()).isEqualTo("/api/v1/document/{documentId}/update"); } @Test @@ -228,7 +242,10 @@ void multiRuleToAttributesTest() { Objects.requireNonNull( resultA.getAttributes().get(AttributeKey.stringKey("password2")))) .isEqualTo("555"); // The first match is taken to populate the attribute - assertThat(resultA.getBody().asString()) + Value bodyValueA = resultA.getBodyValue(); + assertThat(bodyValueA).isNotNull(); + assertThat(bodyValueA.getType()).isEqualTo(ValueType.STRING); + assertThat(bodyValueA.asString()) .isEqualTo("yyyPassword={password1} aba Pass={password2} xyx Pass={password2} zzz"); assertThat( Objects.requireNonNull( @@ -238,7 +255,10 @@ void multiRuleToAttributesTest() { Objects.requireNonNull( resultB.getAttributes().get(AttributeKey.stringKey("password1")))) .isEqualTo("****"); - assertThat(resultB.getBody().asString()).isEqualTo("yyyPassword={password1} aba"); + Value bodyValueB = resultB.getBodyValue(); + assertThat(bodyValueB).isNotNull(); + assertThat(bodyValueB.getType()).isEqualTo(ValueType.STRING); + assertThat(bodyValueB.asString()).isEqualTo("yyyPassword={password1} aba"); } @Test @@ -264,7 +284,10 @@ void multiMatch() { List result = mockExporter.getLogs(); LogRecordData resultA = result.get(0); - assertThat(resultA.getBody().asString()).isEqualTo("yyyPassword={x} aba Password={x} xyx"); + Value bodyValueA = resultA.getBodyValue(); + assertThat(bodyValueA).isNotNull(); + assertThat(bodyValueA.getType()).isEqualTo(ValueType.STRING); + assertThat(bodyValueA.asString()).isEqualTo("yyyPassword={x} aba Password={x} xyx"); } @Test @@ -292,6 +315,9 @@ void simpleRenameLogTestWithLogProcessor() { // verify that resulting logs are not modified List result = mockExporter.getLogs(); LogRecordData resultLog = result.get(0); - assertThat(resultLog.getBody().asString()).isEqualTo("locationget1234"); + Value bodyValue = resultLog.getBodyValue(); + assertThat(bodyValue).isNotNull(); + assertThat(bodyValue.getType()).isEqualTo(ValueType.STRING); + assertThat(bodyValue.asString()).isEqualTo("locationget1234"); } }