Skip to content

Commit

Permalink
OpenTelemetry Logging
Browse files Browse the repository at this point in the history
  • Loading branch information
loicmathieu committed Jul 10, 2024
1 parent 389f694 commit 6755f1b
Show file tree
Hide file tree
Showing 12 changed files with 341 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.quarkus.opentelemetry.deployment.logging;

import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.ExecutionTime;
import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.builditem.LogHandlerBuildItem;
import io.quarkus.opentelemetry.runtime.logging.OpenTelemetryLogConfig;
import io.quarkus.opentelemetry.runtime.logging.OpenTelemetryLogRecorder;

class OpenTelemetryLogHandlerProcessor {

@BuildStep
@Record(ExecutionTime.RUNTIME_INIT)
LogHandlerBuildItem build(OpenTelemetryLogRecorder recorder, OpenTelemetryLogConfig config) {
return new LogHandlerBuildItem(recorder.initializeHandler(config));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package io.quarkus.opentelemetry.runtime.logging;

import io.quarkus.runtime.annotations.ConfigItem;
import io.quarkus.runtime.annotations.ConfigPhase;
import io.quarkus.runtime.annotations.ConfigRoot;

@ConfigRoot(phase = ConfigPhase.RUN_TIME, name = "log.handler.open-telemetry")
public class OpenTelemetryLogConfig {
/**
* Determine whether to enable the OpenTelemetry logging handler
*/
@ConfigItem
public boolean enabled;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package io.quarkus.opentelemetry.runtime.logging;

import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.logs.Logger;
import io.opentelemetry.api.logs.Severity;

public class OpenTelemetryLogHandler extends Handler {
private final Logger openTelemetry;

public OpenTelemetryLogHandler(OpenTelemetry openTelemetry) {
this.openTelemetry = openTelemetry.getLogsBridge().get("quarkus-log-appender");
}

@Override
public void publish(LogRecord record) {
openTelemetry.logRecordBuilder()
.setSeverity(mapSeverity(record.getLevel()))
.setSeverityText(record.getLevel().getName())
.setBody(record.getMessage()) // TODO check that we didn't need to format it
.setObservedTimestamp(record.getInstant())
// TODO add attributes
.emit();
}

private Severity mapSeverity(Level level) {
if (Level.SEVERE.equals(level)) {
return Severity.ERROR;
}
if (Level.WARNING.equals(level)) {
return Severity.WARN;
}
if (Level.INFO.equals(level) || Level.CONFIG.equals(level)) {
return Severity.INFO;
}
if (Level.FINE.equals(level)) {
return Severity.DEBUG;
}
if (Level.FINER.equals(level) || Level.FINEST.equals(level) || Level.ALL.equals(level)) {
return Severity.TRACE;
}
return Severity.UNDEFINED_SEVERITY_NUMBER;
}

@Override
public void flush() {
}

@Override
public void close() throws SecurityException {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.quarkus.opentelemetry.runtime.logging;

import java.util.Optional;
import java.util.logging.Handler;

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.quarkus.runtime.RuntimeValue;
import io.quarkus.runtime.annotations.Recorder;

@Recorder
public class OpenTelemetryLogRecorder {
public RuntimeValue<Optional<Handler>> initializeHandler(final OpenTelemetryLogConfig config) {
if (!config.enabled) {
return new RuntimeValue<>(Optional.empty());
}

OpenTelemetryLogHandler handler = new OpenTelemetryLogHandler(GlobalOpenTelemetry.get());

return new RuntimeValue<>(Optional.of(handler));
}
}
118 changes: 118 additions & 0 deletions integration-tests/opentelemetry-logging/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-integration-tests-parent</artifactId>
<version>999-SNAPSHOT</version>
</parent>
<artifactId>quarkus-logging-opentelemetry-integration-tests</artifactId>
<name>Quarkus - Integration Tests - Logging - OpenTelemetry</name>
<properties>
<skipITs>true</skipITs>
</properties>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-opentelemetry</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-opentelemetry-deployment</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-deployment</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<systemPropertyVariables>
<native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>native-image</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>${native.surefire.skip}</skipTests>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<skipITs>false</skipITs>
<quarkus.package.type>native</quarkus.package.type>
</properties>
</profile>
</profiles>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.quarkus.logging.opentelemetry.it;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Path("/logging-opentelemetry")
@ApplicationScoped
public class LoggingResource {
private static final Logger LOG = LoggerFactory.getLogger(LoggingResource.class);

@GET
public String hello() {
LOG.info("Hello {}", "World");
return "Hello logging-opentelemetry";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
quarkus.log.handler.open-telemetry.enabled=true
quarkus.otel.exporter.otlp.traces.endpoint=http://localhost:4317
quarkus.otel.exporter.otlp.logs.endpoint=http://localhost:4317
quarkus.otel.logs.exporter=otlp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.quarkus.logging.opentelemetry.it;

import io.quarkus.test.junit.QuarkusIntegrationTest;

@QuarkusIntegrationTest
public class LoggingResourceIT extends LoggingResourceTest {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.quarkus.logging.opentelemetry.it;

import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.is;

import org.junit.jupiter.api.Test;

import io.quarkus.test.junit.QuarkusTest;

@QuarkusTest
public class LoggingResourceTest {

@Test
public void testHelloEndpoint() {
given()
.when().get("/logging-opentelemetry")
.then()
.statusCode(200)
.body(is("Hello logging-opentelemetry"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

services:
otel-collector:
image: otel/opentelemetry-collector-contrib
volumes:
- ./otel-collector-config.yaml:/etc/otelcol-contrib/config.yaml
ports:
- 1888:1888 # pprof extension
- 8888:8888 # Prometheus metrics exposed by the Collector
- 8889:8889 # Prometheus exporter metrics
- 13133:13133 # health_check extension
- 4317:4317 # OTLP gRPC receiver
- 4318:4318 # OTLP http receiver
- 55679:55679 # zpages extension
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
receivers:
otlp:
protocols:
grpc:
endpoint: otel-collector:4317
http:
endpoint: otel-collector:4318

exporters:
logging:
loglevel: debug

processors:
batch:

extensions:
health_check:

service:
extensions: [health_check]
pipelines:
traces:
receivers: [otlp]
processors: []
exporters: [logging]
metrics:
receivers: [otlp]
processors: []
exporters: [logging]
logs:
receivers: [otlp]
processors: []
exporters: [logging]
1 change: 1 addition & 0 deletions integration-tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@
<!-- Virtual threads test -->
<module>virtual-threads</module>
<module>mutiny-native-jctools</module>
<module>opentelemetry-logging</module>
</modules>
</profile>

Expand Down

0 comments on commit 6755f1b

Please sign in to comment.