Skip to content

Commit

Permalink
More tests and address PR reviews
Browse files Browse the repository at this point in the history
  • Loading branch information
brunobat committed Sep 23, 2024
1 parent a323043 commit 3859533
Show file tree
Hide file tree
Showing 25 changed files with 587 additions and 424 deletions.
5 changes: 5 additions & 0 deletions docs/src/main/asciidoc/logging.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,11 @@ Use a centralized location to efficiently collect, store, and analyze log data f
To send logs to a centralized tool such as Graylog, Logstash, or Fluentd, see the Quarkus xref:centralized-log-management.adoc[Centralized log management] guide.


=== OpenTelemetry logging
Logging entries from all appenders can be sent using OpenTelemetry Logging.

For details, see the Quarkus xref:opentelemetry-logging.adoc[OpenTelemetry Logging] guide.

== Configure logging for `@QuarkusTest`

Enable proper logging for `@QuarkusTest` by setting the `java.util.logging.manager` system property to `org.jboss.logmanager.LogManager`.
Expand Down
6 changes: 2 additions & 4 deletions docs/src/main/asciidoc/opentelemetry-logging.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,6 @@ If you have followed the tracing guide, this class will seem familiar. The main

=== Create the configuration

=== Create the configuration

The only mandatory configuration for OpenTelemetry Logging is the one enabling it:
[source,properties]
----
Expand Down Expand Up @@ -149,10 +147,10 @@ This features a Quarkus Dev service including a Grafana for visualizing data, Lo

==== Logging exporter

You can output all metrics to the console by setting the exporter to `logging` in the `application.properties` file:
You can output all logs to the console by setting the exporter to `logging` in the `application.properties` file:
[source, properties]
----
quarkus.otel.metrics.exporter=logging <1>
quarkus.otel.logs.exporter=logging <1>
----

<1> Set the exporter to `logging`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,6 @@ void handleServices(OTelBuildConfig config,
Set.of("META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider")));
}

// TODO these classes don't exist!
runtimeReinitialized.produce(
new RuntimeReinitializedClassBuildItem("io.opentelemetry.sdk.autoconfigure.TracerProviderConfiguration"));
runtimeReinitialized.produce(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.function.Function;

import io.quarkus.agroal.spi.OpenTelemetryInitBuildItem;
import io.quarkus.arc.deployment.BeanContainerBuildItem;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.BuildSteps;
import io.quarkus.deployment.annotations.Consume;
Expand All @@ -20,8 +21,10 @@ class LogHandlerProcessor {
@BuildStep
@Record(ExecutionTime.RUNTIME_INIT)
@Consume(OpenTelemetryInitBuildItem.class)
LogHandlerBuildItem build(OpenTelemetryLogRecorder recorder, OpenTelemetryLogConfig config) {
return new LogHandlerBuildItem(recorder.initializeHandler(config));
LogHandlerBuildItem build(OpenTelemetryLogRecorder recorder,
OpenTelemetryLogConfig config,
BeanContainerBuildItem beanContainerBuildItem) {
return new LogHandlerBuildItem(recorder.initializeHandler(beanContainerBuildItem.getValue(), config));
}

public static class LogsEnabled implements BooleanSupplier {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.assertj.core.api.Assertions.assertThat;

import java.time.Duration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
Expand Down Expand Up @@ -38,6 +39,15 @@ public List<LogRecordData> getFinishedLogRecordItemsAtLeast(final int count) {
return getFinishedLogRecordItems();
}

public List<LogRecordData> getFinishedLogRecordItemsWithWait(final Duration duration) {
try {
Thread.sleep(duration.toMillis());
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return getFinishedLogRecordItems();
}

private List<LogRecordData> getFinishedLogRecordItems() {
return Collections.unmodifiableList(new ArrayList(this.finishedLogItems));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.quarkus.opentelemetry.deployment.logs;

import static org.assertj.core.api.Assertions.assertThat;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.List;
Expand All @@ -16,7 +16,6 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.sdk.logs.data.LogRecordData;
import io.quarkus.opentelemetry.deployment.common.exporter.InMemoryLogRecordExporter;
import io.quarkus.opentelemetry.deployment.common.exporter.InMemoryLogRecordExporterProvider;
Expand Down Expand Up @@ -63,9 +62,12 @@ public void testJBossLogging() {
assertEquals("hello", jBossLoggingBean.hello(message));
List<LogRecordData> finishedLogRecordItems = logRecordExporter.getFinishedLogRecordItemsAtLeast(1);
LogRecordData last = finishedLogRecordItems.get(finishedLogRecordItems.size() - 1);
assertThat(last.getBody().asString()).isEqualTo(message);
assertThat(last.getAttributes().asMap().get(AttributeKey.stringKey("log.logger.namespace")))
.isEqualTo("org.jboss.logging.Logger");

assertThat(last)
.hasBody(message)
.hasAttributesSatisfying(
attributes -> assertThat(attributes)
.containsEntry("log.logger.namespace", "org.jboss.logging.Logger"));
}

@Test
Expand All @@ -74,9 +76,12 @@ public void testSLF4JLogging() {
assertEquals("hello", slf4jBean.hello(message));
List<LogRecordData> finishedLogRecordItems = logRecordExporter.getFinishedLogRecordItemsAtLeast(1);
LogRecordData last = finishedLogRecordItems.get(finishedLogRecordItems.size() - 1);
assertThat(last.getBody().asString()).isEqualTo(message);
assertThat(last.getAttributes().asMap().get(AttributeKey.stringKey("log.logger.namespace")))
.isEqualTo("org.slf4j.impl.Slf4jLogger");

assertThat(last)
.hasBody(message)
.hasAttributesSatisfying(
attributes -> assertThat(attributes)
.containsEntry("log.logger.namespace", "org.slf4j.impl.Slf4jLogger"));
}

@Test
Expand All @@ -85,9 +90,12 @@ public void testLog4jLogging() {
assertEquals("hello", log4j2Bean.hello(message));
List<LogRecordData> finishedLogRecordItems = logRecordExporter.getFinishedLogRecordItemsAtLeast(1);
LogRecordData last = finishedLogRecordItems.get(finishedLogRecordItems.size() - 1);
assertThat(last.getBody().asString()).isEqualTo(message);
assertThat(last.getAttributes().asMap().get(AttributeKey.stringKey("log.logger.namespace")))
.isEqualTo("org.apache.logging.log4j.spi.AbstractLogger");

assertThat(last)
.hasBody(message)
.hasAttributesSatisfying(
attributes -> assertThat(attributes)
.containsEntry("log.logger.namespace", "org.apache.logging.log4j.spi.AbstractLogger"));
}

@Test
Expand All @@ -96,9 +104,12 @@ public void testJulLogging() {
assertEquals("hello", julBean.hello(message));
List<LogRecordData> finishedLogRecordItems = logRecordExporter.getFinishedLogRecordItemsAtLeast(1);
LogRecordData last = finishedLogRecordItems.get(finishedLogRecordItems.size() - 1);
assertThat(last.getBody().asString()).isEqualTo(message);
assertThat(last.getAttributes().asMap().get(AttributeKey.stringKey("log.logger.namespace")))
.isEqualTo("org.jboss.logmanager.Logger");

assertThat(last)
.hasBody(message)
.hasAttributesSatisfying(
attributes -> assertThat(attributes)
.containsEntry("log.logger.namespace", "org.jboss.logmanager.Logger"));
}

@ApplicationScoped
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package io.quarkus.opentelemetry.deployment.logs;

import static io.opentelemetry.semconv.ExceptionAttributes.EXCEPTION_MESSAGE;
import static io.opentelemetry.semconv.ExceptionAttributes.EXCEPTION_STACKTRACE;
import static io.opentelemetry.semconv.ExceptionAttributes.EXCEPTION_TYPE;
import static io.opentelemetry.semconv.incubating.CodeIncubatingAttributes.CODE_FUNCTION;
import static io.opentelemetry.semconv.incubating.CodeIncubatingAttributes.CODE_LINENO;
import static io.opentelemetry.semconv.incubating.CodeIncubatingAttributes.CODE_NAMESPACE;
import static io.opentelemetry.semconv.incubating.LogIncubatingAttributes.LOG_FILE_PATH;
import static io.opentelemetry.semconv.incubating.ThreadIncubatingAttributes.THREAD_ID;
import static io.opentelemetry.semconv.incubating.ThreadIncubatingAttributes.THREAD_NAME;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.List;
import java.util.Map;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
Expand All @@ -24,9 +24,9 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.logs.Severity;
import io.opentelemetry.sdk.logs.data.LogRecordData;
import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions;
import io.quarkus.opentelemetry.deployment.common.exporter.InMemoryLogRecordExporter;
import io.quarkus.opentelemetry.deployment.common.exporter.InMemoryLogRecordExporterProvider;
import io.quarkus.test.QuarkusUnitTest;
Expand Down Expand Up @@ -66,22 +66,27 @@ public void testLoggingData() {
List<LogRecordData> finishedLogRecordItems = logRecordExporter.getFinishedLogRecordItemsAtLeast(1);
LogRecordData last = finishedLogRecordItems.get(finishedLogRecordItems.size() - 1);

assertThat(last.getTimestampEpochNanos()).isNotNull().isLessThan(System.currentTimeMillis() * 1_000_000);
assertThat(last.getSeverityText()).isEqualTo("INFO");
assertThat(last.getSeverity()).isEqualTo(Severity.INFO);
assertThat(last.getBody().asString()).isEqualTo(message);

Map<AttributeKey<?>, Object> attributesMap = last.getAttributes().asMap();
assertThat(attributesMap.get(CODE_NAMESPACE))
.isEqualTo("io.quarkus.opentelemetry.deployment.logs.OtelLoggingFileTest$JBossLoggingBean");
assertThat(attributesMap.get(CODE_FUNCTION)).isEqualTo("hello");
assertThat((Long) attributesMap.get(CODE_LINENO)).isGreaterThan(0);
assertThat(attributesMap.get(THREAD_NAME)).isEqualTo(Thread.currentThread().getName());
assertThat(attributesMap.get(THREAD_ID)).isEqualTo(Thread.currentThread().getId());
assertThat(attributesMap.get(AttributeKey.stringKey("log.logger.namespace"))).isEqualTo("org.jboss.logging.Logger");
assertThat(attributesMap.get(EXCEPTION_TYPE)).isNull();
// using the default location for the log file
assertThat(attributesMap.get(LOG_FILE_PATH)).isEqualTo("target/quarkus.log");
OpenTelemetryAssertions.assertThat(last)
.hasSeverity(Severity.INFO)
.hasSeverityText("INFO")
.hasBody(message)
.hasAttributesSatisfying(

Check failure on line 73 in extensions/opentelemetry/deployment/src/test/java/io/quarkus/opentelemetry/deployment/logs/OtelLoggingFileTest.java

View workflow job for this annotation

GitHub Actions / Build summary for 3859533ce6deae63579ab372304be5fa1dea5fb2

JVM Tests - JDK 17 Windows

org.assertj.core.error.AssertJMultipleFailuresError: [attributes] (1 failure)
Raw output
org.assertj.core.error.AssertJMultipleFailuresError: 

[attributes] (1 failure)
-- failure 1 --Expected attributes to have key <log.file.path> with value <target/quarkus.log> but was value <target\quarkus.log>
at OtelLoggingFileTest.lambda$testLoggingData$1(OtelLoggingFileTest.java:81)
	at io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert.hasAttributesSatisfying(LogRecordDataAssert.java:193)
	at io.quarkus.opentelemetry.deployment.logs.OtelLoggingFileTest.testLoggingData(OtelLoggingFileTest.java:73)
	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
	at io.quarkus.test.QuarkusUnitTest.runExtensionMethod(QuarkusUnitTest.java:513)
	at io.quarkus.test.QuarkusUnitTest.interceptTestMethod(QuarkusUnitTest.java:427)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
attributes -> OpenTelemetryAssertions.assertThat(attributes)
.containsEntry(CODE_NAMESPACE.getKey(),
"io.quarkus.opentelemetry.deployment.logs.OtelLoggingFileTest$JBossLoggingBean")
.containsEntry(CODE_FUNCTION.getKey(), "hello")
.containsEntry(THREAD_NAME.getKey(), Thread.currentThread().getName())
.containsEntry(THREAD_ID.getKey(), Thread.currentThread().getId())
.containsEntry("log.logger.namespace", "org.jboss.logging.Logger")
.containsEntry(LOG_FILE_PATH, "target/quarkus.log")
.containsKey(CODE_LINENO.getKey())
.doesNotContainKey(EXCEPTION_TYPE)
.doesNotContainKey(EXCEPTION_MESSAGE)
.doesNotContainKey(EXCEPTION_STACKTRACE)
// attributed do not duplicate tracing data
.doesNotContainKey("spanId")
.doesNotContainKey("traceId")
.doesNotContainKey("sampled"));
}

@ApplicationScoped
Expand Down
Loading

0 comments on commit 3859533

Please sign in to comment.