Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions kubectl/dice-java.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ spec:
value: "http://otel-collector:4318"
ports:
- containerPort: 8082
volumeMounts:
- name: audit-logs
mountPath: /var/log/audit
volumes:
- name: audit-logs
emptyDir: {} # Survives container crashes, not pod restarts
---
apiVersion: v1
kind: Service
Expand Down
43 changes: 42 additions & 1 deletion src/dice-java/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,23 @@
</scm>
<properties>
<java.version>24</java.version>
<opentelemetry.version>1.51.0</opentelemetry.version>
<opentelemetry.version>1.54.0</opentelemetry.version>
<otel.version>1.55.0-SNAPSHOT</otel.version>
</properties>

<dependencies>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-otlp-common</artifactId>
<scope>system</scope>
<systemPath>${project.basedir}/src/opentelemetry-exporter-otlp-common-${otel.version}.jar</systemPath>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-logs</artifactId>
<scope>system</scope>
<systemPath>${project.basedir}/src/opentelemetry-sdk-logs-${otel.version}.jar</systemPath>
</dependency>
<!--
<dependency>
<groupId>org.springframework.boot</groupId>
Expand Down Expand Up @@ -81,10 +94,30 @@
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk</artifactId>
<exclusions>
<exclusion>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-otlp-common</artifactId>
</exclusion>
<exclusion>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-logs</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-otlp</artifactId>
<exclusions>
<exclusion>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-otlp-common</artifactId>
</exclusion>
<exclusion>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-logs</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
Expand All @@ -95,6 +128,14 @@
<artifactId>opentelemetry-semconv</artifactId>
<version>1.32.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import java.util.Random;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
Expand All @@ -30,8 +29,9 @@ public class DiceController {

public DiceController(
@Value("${LOG_MESSAGES_PER_REQUEST:1}") int logMessagesPerRequest,
@Qualifier("otelLoggerProvider") @Autowired LoggerProvider loggerProvider) {
/*@Qualifier("otelLoggerProvider")*/ @Autowired LoggerProvider loggerProvider) {
log.debug("DiceController initialized with logMessagesPerRequest={}", logMessagesPerRequest);
log.info("Using LoggerProvider implementation: {}", loggerProvider.getClass().getName());
// LoggerProvider loggerProvider = GlobalOpenTelemetry.get().getLogsBridge(); // actually
// returns LoggerProvider.noop()
this.otelLogger = loggerProvider.loggerBuilder("AUDIT_JAVA_SERVICE").build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,26 @@

import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.logs.LoggerProvider;
import io.opentelemetry.exporter.internal.otlp.logs.AuditLogFileStore;
import io.opentelemetry.exporter.logging.SystemOutLogRecordExporter;
import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter;
import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.common.export.RetryPolicy;
import io.opentelemetry.sdk.logs.LogRecordProcessor;
import io.opentelemetry.sdk.logs.SdkLoggerProvider;
import io.opentelemetry.sdk.logs.export.AuditException;
import io.opentelemetry.sdk.logs.export.AuditExceptionHandler;
import io.opentelemetry.sdk.logs.export.AuditLogRecordProcessor;
import io.opentelemetry.sdk.logs.export.AuditLogStore;
import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor;
import io.opentelemetry.sdk.logs.export.LogRecordExporter;
import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor;
import io.opentelemetry.sdk.resources.Resource;
import java.io.IOException;
import java.nio.file.Path;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

Expand All @@ -26,7 +36,7 @@ public class OpenTelemetryConfig {
* org.springframework.boot.actuate.autoconfigure.logging.OpenTelemetryLoggingAutoConfiguration
* @return LoggerProvider configured with OTLP exporters and stdout exporter
*/
@Bean
@Bean(defaultCandidate = false)
public LoggerProvider otelLoggerProvider() {
// OTLP gRPC exporter
String grpcEndpoint =
Expand Down Expand Up @@ -75,4 +85,74 @@ public LoggerProvider otelLoggerProvider() {
OpenTelemetrySdk.builder().setLoggerProvider(loggerProvider).buildAndRegisterGlobal();
return loggerProvider;
}

@Bean(defaultCandidate = true)
public LoggerProvider auditLoggerProvider() {
// OTLP gRPC exporter
RetryPolicy retryPolicy =
RetryPolicy.builder()
.setMaxAttempts(5)
.setInitialBackoff(Duration.ofSeconds(30))
.setMaxBackoff(Duration.ofSeconds(30))
.setBackoffMultiplier(3)
.build();

String grpcEndpoint =
System.getenv().getOrDefault("OTEL_EXPORTER_OTLP_ENDPOINT_GRPC", "http://localhost:4317");
System.out.println("Using OTLP gRPC endpoint: " + grpcEndpoint);

LogRecordExporter grpcExporter =
OtlpGrpcLogRecordExporter.builder()
.setEndpoint(grpcEndpoint)
.setRetryPolicy(retryPolicy)
.setConnectTimeout(Duration.ofSeconds(1))
.build();

Resource resource =
Resource.getDefault().toBuilder()
.put(AttributeKey.stringKey("service.name"), "audit-java-service")
.build();

// Audit log store using a temporary directory for local temporary persistence
Path tmp = Path.of(System.getProperty("java.io.tmpdir"));
AuditLogStore auditLogStore;
try {
auditLogStore = new AuditLogFileStore(tmp);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new RuntimeException("Failed to create AuditLogFileStore", e);
}
AuditExceptionHandler auditExceptionHandler =
new AuditExceptionHandler() {
@Override
public void handle(AuditException auditEx) {
System.err.println("AuditException: " + auditEx.getMessage());
auditEx.logRecords.forEach(lr -> System.err.println(" " + lr));
}
};
LogRecordProcessor auditLogProcessor =
AuditLogRecordProcessor.builder(grpcExporter, auditLogStore)
.setExceptionHandler(auditExceptionHandler) // use default handler which logs to stderr
.setExporterTimeout(42, TimeUnit.SECONDS) // use default timeout of 30s
.setRetryPolicy(retryPolicy) // use default retry policy
.setMaxExportBatchSize(42) // increase batch size for audit logs
.setScheduleDelay(42, TimeUnit.SECONDS) // use default delay of 5s
.setWaitOnExport(true) // block when shutting down to ensure delivery
.build();

SdkLoggerProvider loggerProvider =
SdkLoggerProvider.builder()
.addLogRecordProcessor(
SimpleLogRecordProcessor.create(
SystemOutLogRecordExporter.create())) // also log to stdout
.addLogRecordProcessor(
auditLogProcessor) // add audit log processor for guaranteed delivery
.setResource(resource)
.build();

// Optionally set as global
OpenTelemetrySdk.builder().setLoggerProvider(loggerProvider).buildAndRegisterGlobal();
return loggerProvider;
}
}
2 changes: 1 addition & 1 deletion src/dice-java/src/main/resources/application.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
spring:
application:
name: demo
name: dice-java
server:
address: 0.0.0.0
port: 8082
Expand Down
Binary file not shown.
Binary file not shown.