From 042185d5964603e71a8a416569908a1d106d1c04 Mon Sep 17 00:00:00 2001 From: loglogn Date: Thu, 19 Mar 2026 10:34:23 +0530 Subject: [PATCH] feat(spring-ai-demo): upgrade to Spring Boot 4.0.3 and Spring AI 2.0.0-M2 --- applications/spring-ai-demo/README.md | 38 +++++++++++++++---- applications/spring-ai-demo/pom.xml | 37 ++++++++---------- .../com/langfuse/springai/OtelConfig.java | 28 ++++++++++++++ .../src/main/resources/application.yml | 7 ++++ 4 files changed, 80 insertions(+), 30 deletions(-) create mode 100644 applications/spring-ai-demo/src/main/java/com/langfuse/springai/OtelConfig.java diff --git a/applications/spring-ai-demo/README.md b/applications/spring-ai-demo/README.md index 64f9b40..3835ab1 100644 --- a/applications/spring-ai-demo/README.md +++ b/applications/spring-ai-demo/README.md @@ -5,20 +5,42 @@ - Java 21+ - Langfuse stack ([Cloud](https://cloud.langfuse.com/) or [Self-Hosted](https://langfuse.com/docs/deployment/self-host)) - Langfuse API Keys -- An OpenAI Api Key +- An OpenAI API Key + +## Technology Stack + +- **Spring Boot**: 4.0.3 +- **Spring AI**: 2.0.0-M2 +- **Java**: 21 +- **OpenTelemetry**: Native support via `spring-boot-starter-opentelemetry` ## How to run 1. Configure environment variables to connect Spring AI demo app with Langfuse. - ``` + ```bash export SPRING_AI_OPENAI_APIKEY="sk-proj-xxx" - export OTEL_EXPORTER_OTLP_ENDPOINT="https://cloud.langfuse.com/api/public/otel" # πŸ‡ͺπŸ‡Ί EU data region - # export OTEL_EXPORTER_OTLP_ENDPOINT="https://us.cloud.langfuse.com/api/public/otel" # πŸ‡ΊπŸ‡Έ US data region - # export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:3000/api/public/otel" # 🏠 Local deployment (>= v3.22.0) - export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Basic $(echo -n "pk-lf-xxx:sk-lf-xxx" | base64)" + export OTEL_EXPORTER_OTLP_HEADERS_AUTHORIZATION="Basic $(echo -n "pk-lf-xxx:sk-lf-xxx" | base64)" ``` -2. Run the sample application with `./mvnw clean install spring-boot:run`. -3. Call the chat endpoint with `curl localhost:8080/v1/chat`. + +2. Run the sample application: + ```bash + ./mvnw clean install spring-boot:run + ``` + +3. Call the chat endpoint: + ```bash + curl localhost:8080/v1/chat + ``` + 4. Observe the new trace in the Langfuse web UI. +## Configuration + +The application uses native OpenTelemetry support introduced in Spring Boot 4.x. The OTLP endpoint is configured in `OtelConfig.java` to point to `http://localhost:3001/api/public/otel/v1/traces`. + +For cloud deployments, modify the endpoint in `OtelConfig.java`: +- πŸ‡ͺπŸ‡Ί EU: `https://cloud.langfuse.com/api/public/otel/v1/traces` +- πŸ‡ΊπŸ‡Έ US: `https://us.cloud.langfuse.com/api/public/otel/v1/traces` +- 🏠 Local: `http://localhost:3000/api/public/otel/v1/traces` (>= v3.22.0) + ![sample-trace](./screenshots/spring-ai-demo-trace.png) diff --git a/applications/spring-ai-demo/pom.xml b/applications/spring-ai-demo/pom.xml index cfb171b..18c48e8 100644 --- a/applications/spring-ai-demo/pom.xml +++ b/applications/spring-ai-demo/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.4.3 + 4.0.3 com.langfuse @@ -17,18 +17,11 @@ 21 - 1.0.0 + 2.0.0-M2 - - io.opentelemetry.instrumentation - opentelemetry-instrumentation-bom - 2.17.0 - pom - import - org.springframework.ai spring-ai-bom @@ -44,30 +37,30 @@ org.springframework.boot spring-boot-starter - - org.springframework.ai - spring-ai-starter-model-openai - - + + org.springframework.boot spring-boot-starter-web + + - io.opentelemetry.instrumentation - opentelemetry-spring-boot-starter + org.springframework.ai + spring-ai-starter-model-openai - + + org.springframework.boot - spring-boot-starter-actuator + spring-boot-starter-opentelemetry - + + - io.micrometer - micrometer-tracing-bridge-otel + org.springframework.boot + spring-boot-starter-actuator - io.opentelemetry opentelemetry-exporter-otlp diff --git a/applications/spring-ai-demo/src/main/java/com/langfuse/springai/OtelConfig.java b/applications/spring-ai-demo/src/main/java/com/langfuse/springai/OtelConfig.java new file mode 100644 index 0000000..f6fe86e --- /dev/null +++ b/applications/spring-ai-demo/src/main/java/com/langfuse/springai/OtelConfig.java @@ -0,0 +1,28 @@ +package com.langfuse.springai; + +import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter; +import io.opentelemetry.sdk.trace.export.BatchSpanProcessor; +import io.opentelemetry.sdk.trace.export.SpanExporter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class OtelConfig { + + @Value("${otel.exporter.otlp.headers.authorization}") + private String authorizationHeader; + + @Bean + public SpanExporter spanExporter() { + return OtlpHttpSpanExporter.builder() + .setEndpoint("http://localhost:3001/api/public/otel/v1/traces") + .addHeader("Authorization", authorizationHeader) + .build(); + } + + @Bean + public BatchSpanProcessor spanProcessor(SpanExporter exporter) { + return BatchSpanProcessor.builder(exporter).build(); + } +} \ No newline at end of file diff --git a/applications/spring-ai-demo/src/main/resources/application.yml b/applications/spring-ai-demo/src/main/resources/application.yml index ce31f9e..8ea4efa 100644 --- a/applications/spring-ai-demo/src/main/resources/application.yml +++ b/applications/spring-ai-demo/src/main/resources/application.yml @@ -13,3 +13,10 @@ management: observations: annotations: enabled: true # Enable @Observed (if you use observation annotations in code) + +otel: + exporter: + otlp: + headers: + authorization: {{OTEL_EXPORTER_OTLP_HEADERS_AUTHORIZATION}} # Set via env var for security} +