diff --git a/README.adoc b/README.adoc index ce47267e..b59988ad 100644 --- a/README.adoc +++ b/README.adoc @@ -27,7 +27,7 @@ readme's instructions. === Examples // examples: START -Number of Examples: 71 (0 deprecated) +Number of Examples: 72 (0 deprecated) [width="100%",cols="4,2,4",options="header"] |=== @@ -35,6 +35,8 @@ Number of Examples: 71 (0 deprecated) | link:ai-agent/README.adoc[Ai Agent] (ai-agent) | AI | An example showing how to work with Camel Spring AI for chat, tools, and vector store +| link:genai-observability/README.adoc[Genai Observability] (genai-observability) | AI | Spring Boot example for Camel GenAI observability with LangChain4j and Ollama + | link:milvus/readme.adoc[Milvus] (milvus) | AI | An example showing vector similarity search on European cities using Camel OpenAI and Milvus | link:qdrant/readme.adoc[Qdrant] (qdrant) | AI | An example showing a full RAG pipeline using Camel OpenAI and Qdrant as vector store diff --git a/genai-observability/README.adoc b/genai-observability/README.adoc new file mode 100644 index 00000000..777f7342 --- /dev/null +++ b/genai-observability/README.adoc @@ -0,0 +1,74 @@ += Spring Boot GenAI Observability Example + +== Introduction + +This example demonstrates *GenAI observability* in Apache Camel 4.23+ with Spring Boot: +OpenTelemetry `gen_ai.*` span attributes and Micrometer metrics for `langchain4j-chat` +LLM calls, visualized with Prometheus and VictoriaTraces. + +It pairs with the community blog post *GenAI Observability with Spring Boot and the Camel Observability Stack* +(`docs/blog-drafts/genai-observability-02-spring-boot-obs-stack.adoc` in the +https://github.com/apache/camel[Apache Camel] source tree). + +The example uses `camel-ai-observability-starter` for Spring Boot configuration of the global +GenAI observability toggle (`camel.aiobservability.enabled`), together with `camel-ai-observability` +for span and metric emission when a tracing or metrics backend is present. + +=== Prerequisites + +* Java 17+ +* Maven 3.9+ +* Docker (for observability stack) +* https://ollama.com/[Ollama] with `llama3.2` pulled + +== Build + +[source,shell] +---- +mvn compile +---- + +== Run + +Terminal 1 — Ollama: + +[source,shell] +---- +ollama pull llama3.2 +ollama serve +---- + +Terminal 2 — observability stack (Prometheus + VictoriaTraces + Perses): + +[source,shell] +---- +docker compose up -d +---- + +Terminal 3 — Spring Boot application: + +[source,shell] +---- +mvn spring-boot:run +---- + +== Verify GenAI observability + +[source,shell] +---- +curl -s http://localhost:8080/actuator/prometheus | grep gen_ai +---- + +* Prometheus: `http://localhost:9090` +* VictoriaTraces: `http://localhost:9428/select/vmui` +* Perses: `http://localhost:8088` + +== Help and contributions + +If you hit any problem using Camel or have some feedback, then please +https://camel.apache.org/community/support/[let us know]. + +We also love contributors, so +https://camel.apache.org/community/contributing/[get involved] :-) + +The Camel riders! diff --git a/genai-observability/docker-compose.yml b/genai-observability/docker-compose.yml new file mode 100644 index 00000000..71034773 --- /dev/null +++ b/genai-observability/docker-compose.yml @@ -0,0 +1,20 @@ +# Observability stack for Camel GenAI observability blog (Blog 2) +# Images aligned with camel-test-infra-observability + +services: + prometheus: + image: quay.io/prometheus/prometheus:v3.13.2 + ports: + - "9090:9090" + volumes: + - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro + + victoriatraces: + image: mirror.gcr.io/victoriametrics/victoria-traces:v0.10.0 + ports: + - "9428:9428" + + perses: + image: mirror.gcr.io/persesdev/perses:v0.54.0 + ports: + - "8088:8080" diff --git a/genai-observability/pom.xml b/genai-observability/pom.xml new file mode 100644 index 00000000..1462f6b0 --- /dev/null +++ b/genai-observability/pom.xml @@ -0,0 +1,119 @@ + + + + + 4.0.0 + + + org.apache.camel.springboot.example + examples + 4.23.0-SNAPSHOT + + + camel-example-spring-boot-genai-observability + Camel SB Examples :: GenAI Observability + Spring Boot example for Camel GenAI observability with LangChain4j and Ollama + + + AI + 1.19.0-beta29 + UTF-8 + UTF-8 + + + + + + org.apache.camel.springboot + camel-spring-boot-bom + ${project.version} + pom + import + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot-version} + pom + import + + + + + + + org.springframework.boot + spring-boot-starter + + + org.apache.camel.springboot + camel-spring-boot-starter + + + org.apache.camel.springboot + camel-observability-services-starter + + + org.apache.camel.springboot + camel-ai-observability-starter + + + org.apache.camel.springboot + camel-langchain4j-chat-starter + + + org.apache.camel + camel-ai-observability + ${camel-version} + + + dev.langchain4j + langchain4j-ollama-spring-boot-starter + ${langchain4j-beta-version} + + + org.springframework.boot + spring-boot-starter-actuator + + + io.micrometer + micrometer-registry-prometheus + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot-version} + + + + repackage + + + + + + + + diff --git a/genai-observability/prometheus.yml b/genai-observability/prometheus.yml new file mode 100644 index 00000000..a0a9125a --- /dev/null +++ b/genai-observability/prometheus.yml @@ -0,0 +1,16 @@ +# +# 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 +# + +global: + scrape_interval: 15s + +scrape_configs: + - job_name: camel-spring-boot + metrics_path: /actuator/prometheus + static_configs: + - targets: + - host.docker.internal:8080 diff --git a/genai-observability/src/main/java/org/apache/camel/example/genai/GenAiObservabilityApplication.java b/genai-observability/src/main/java/org/apache/camel/example/genai/GenAiObservabilityApplication.java new file mode 100644 index 00000000..922bf3a7 --- /dev/null +++ b/genai-observability/src/main/java/org/apache/camel/example/genai/GenAiObservabilityApplication.java @@ -0,0 +1,28 @@ +/* + * 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 org.apache.camel.example.genai; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class GenAiObservabilityApplication { + + public static void main(String[] args) { + SpringApplication.run(GenAiObservabilityApplication.class, args); + } +} diff --git a/genai-observability/src/main/resources/application.properties b/genai-observability/src/main/resources/application.properties new file mode 100644 index 00000000..7571a31b --- /dev/null +++ b/genai-observability/src/main/resources/application.properties @@ -0,0 +1,43 @@ +## --------------------------------------------------------------------------- +## 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. +## --------------------------------------------------------------------------- + +# Spring Boot +spring.application.name=genai-observability +server.port=8080 + +# LangChain4j Ollama (auto-configures chatLanguageModel bean) +langchain4j.ollama.chat-model.base-url=http://localhost:11434 +langchain4j.ollama.chat-model.model-name=llama3.2 +langchain4j.ollama.chat-model.temperature=0.2 +langchain4j.ollama.chat-model.timeout=PT120S + +# Camel YAML routes +camel.main.routes-include-pattern=camel/* + +# GenAI observability (Camel 4.23+) +camel.aiobservability.enabled=true +camel.opentelemetry2.enabled=true + +# Actuator / Prometheus +management.endpoints.web.exposure.include=health,prometheus,info +management.endpoint.prometheus.access=read_only +management.prometheus.metrics.export.enabled=true + +# OTLP export to VictoriaTraces (docker compose stack) +camel.opentelemetry2.export-target=jaeger +otel.exporter.otlp.endpoint=http://localhost:9428/insert/opentelemetry/v1/traces +otel.exporter.otlp.protocol=http/protobuf diff --git a/genai-observability/src/main/resources/camel/genai-route.camel.yaml b/genai-observability/src/main/resources/camel/genai-route.camel.yaml new file mode 100644 index 00000000..af7a4a8a --- /dev/null +++ b/genai-observability/src/main/resources/camel/genai-route.camel.yaml @@ -0,0 +1,24 @@ +# +# 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 +# + +- route: + id: genai-chat + from: + uri: timer:genai + parameters: + period: "15000" + steps: + - setBody: + constant: "In one sentence, what is Apache Camel integration?" + - to: + uri: langchain4j-chat:demo + parameters: + chatModel: "#chatLanguageModel" + - log: + message: "LLM reply: ${body}" + - log: + message: "Models: req=${header.CamelLangChain4jChatRequestModel} resp=${header.CamelLangChain4jChatResponseModel}" diff --git a/pom.xml b/pom.xml index c05abde3..38b559b2 100644 --- a/pom.xml +++ b/pom.xml @@ -50,6 +50,7 @@ groovy fhir fhir-auth-tx + genai-observability health-checks http-ssl http-streaming