This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-jbang-examples.git
The following commit(s) were added to refs/heads/main by this push:
new 1bde43a Add GenAI observability JBang example (#73)
1bde43a is described below
commit 1bde43a29b38613a82b4c0fa095c90a815af84df
Author: Omar Atie <[email protected]>
AuthorDate: Sun Aug 30 12:30:13 2026 -0700
Add GenAI observability JBang example (#73)
* Add GenAI observability JBang example
Demonstrates Camel 4.23+ GenAI observability with langchain4j-chat,
OpenTelemetry gen_ai spans, Micrometer metrics, and the Camel TUI.
Co-authored-by: Cursor Agent <[email protected]>
* Fix property placeholder resolution in GenAI observability example
Resolve ollama.baseUrl and ollama.model placeholders before building
OllamaChatModel. Also fix README property key to
camel.aiObservability.enabled.
Co-authored-by: Cursor Agent <[email protected]>
---------
Co-authored-by: Cursor Agent <[email protected]>
Co-authored-by: Cursor Agent <[email protected]>
---
.../GenAiObservabilityRoute.java | 52 +++++++++++++
ai/genai-observability/README.md | 91 ++++++++++++++++++++++
ai/genai-observability/application.properties | 7 ++
ai/genai-observability/metadata.json | 17 ++++
camel-jbang-example-catalog.json | 25 ++++++
5 files changed, 192 insertions(+)
diff --git a/ai/genai-observability/GenAiObservabilityRoute.java
b/ai/genai-observability/GenAiObservabilityRoute.java
new file mode 100644
index 0000000..9b2eaa8
--- /dev/null
+++ b/ai/genai-observability/GenAiObservabilityRoute.java
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+import dev.langchain4j.model.chat.ChatModel;
+import dev.langchain4j.model.ollama.OllamaChatModel;
+
+import org.apache.camel.builder.RouteBuilder;
+
+import static java.time.Duration.ofSeconds;
+
+/**
+ * Minimal GenAI route for observing LLM calls with Camel 4.23+.
+ * <p>
+ * Requires Ollama running locally (see README.md).
+ */
+public class GenAiObservabilityRoute extends RouteBuilder {
+
+ @Override
+ public void configure() throws Exception {
+ String baseUrl =
getContext().resolvePropertyPlaceholders("{{ollama.baseUrl:http://localhost:11434}}");
+ String modelName =
getContext().resolvePropertyPlaceholders("{{ollama.model:llama3.2}}");
+ ChatModel chatModel = OllamaChatModel.builder()
+ .baseUrl(baseUrl)
+ .modelName(modelName)
+ .temperature(0.2)
+ .timeout(ofSeconds(120))
+ .build();
+ getContext().getRegistry().bind("chatModel", chatModel);
+
+ from("timer:genai?period={{genai.period:15000}}")
+ .routeId("genai-chat")
+ .setBody(constant("In one sentence, what is Apache Camel
integration?"))
+ .to("langchain4j-chat:demo?chatModel=#chatModel")
+ .log("LLM reply: ${body}")
+ .log("Request model:
${header.CamelLangChain4jChatRequestModel}")
+ .log("Response model:
${header.CamelLangChain4jChatResponseModel}");
+ }
+}
diff --git a/ai/genai-observability/README.md b/ai/genai-observability/README.md
new file mode 100644
index 0000000..a8f5c3c
--- /dev/null
+++ b/ai/genai-observability/README.md
@@ -0,0 +1,91 @@
+## GenAI Observability (JBang / CLI / TUI)
+
+This example demonstrates **GenAI observability** in Apache Camel 4.23+:
OpenTelemetry
+`gen_ai.*` span attributes and Micrometer metrics for `langchain4j-chat` LLM
calls.
+
+A timer route sends a prompt to Ollama via LangChain4j every 15 seconds. With
+`--observe`, Camel exposes health/metrics/tracing and the TUI can show GenAI
spans
+and token usage.
+
+Blog post: see `docs/blog-drafts/genai-observability-01-jbang-cli-tui.adoc` in
the
+[Apache Camel](https://github.com/apache/camel) source tree.
+
+### Prerequisites
+
+- [Camel
JBang](https://camel.apache.org/manual/camel-jbang-jdk-installation.html)
(Camel 4.23+)
+- [Ollama](https://ollama.com/) running locally
+
+```sh
+ollama pull llama3.2
+ollama serve
+```
+
+### How to run
+
+From this directory:
+
+```sh
+camel run GenAiObservabilityRoute.java application.properties --observe \
+ --dependency=camel-langchain4j-chat \
+ --dependency=camel-ai-observability \
+ --dependency=langchain4j-ollama
+```
+
+Or run directly from GitHub:
+
+```sh
+camel run
https://github.com/apache/camel-jbang-examples/tree/main/ai/genai-observability
\
+ --observe \
+ --dependency=camel-langchain4j-chat \
+ --dependency=camel-ai-observability \
+ --dependency=langchain4j-ollama
+```
+
+### Verify GenAI observability
+
+**Metrics** (Prometheus format):
+
+```sh
+curl -s http://127.0.0.1:9876/observe/metrics | grep gen_ai
+```
+
+Look for `gen_ai_client_operation` and `gen_ai_client_token_usage`.
+
+**TUI — Spans tab**
+
+In another terminal:
+
+```sh
+camel tui
+```
+
+Select the running integration, open the **Spans** tab, and trigger a timer
tick.
+Each LLM call creates a child span with `gen_ai.operation.name=chat`,
+`gen_ai.request.model`, and token usage attributes.
+
+**TUI — AI usage (Ctrl+U)**
+
+With the AI panel open, press **Ctrl+U** to see combined token usage from
+`camel ask` and route-level GenAI spans (Camel 4.23 Phase 2).
+
+**Ask about your integration**
+
+```sh
+camel ask "Which routes call an LLM and what model do they use?"
+```
+
+### Disable GenAI observability
+
+```properties
+camel.aiObservability.enabled=false
+```
+
+### Help and contributions
+
+If you hit any problem using Camel or have some feedback, then please
+[let us know](https://camel.apache.org/community/support/).
+
+We also love contributors, so
+[get involved](https://camel.apache.org/community/contributing/) :-)
+
+The Camel riders!
diff --git a/ai/genai-observability/application.properties
b/ai/genai-observability/application.properties
new file mode 100644
index 0000000..1aa678e
--- /dev/null
+++ b/ai/genai-observability/application.properties
@@ -0,0 +1,7 @@
+# Ollama connection (start Ollama and pull the model first: ollama pull
llama3.2)
+ollama.baseUrl=http://localhost:11434
+ollama.model=llama3.2
+genai.period=15000
+
+# GenAI observability (Camel 4.23+) — enabled by default when observability
backends are present
+camel.ai.observability.enabled=true
diff --git a/ai/genai-observability/metadata.json
b/ai/genai-observability/metadata.json
new file mode 100644
index 0000000..ad20a4c
--- /dev/null
+++ b/ai/genai-observability/metadata.json
@@ -0,0 +1,17 @@
+{
+ "title": "GenAI Observability",
+ "description": "Observe LangChain4j LLM calls with OpenTelemetry gen_ai
spans, Micrometer metrics, and the Camel TUI",
+ "tags": [
+ "ai",
+ "observability",
+ "langchain4j",
+ "opentelemetry",
+ "genai",
+ "tui"
+ ],
+ "bundled": false,
+ "level": "intermediate",
+ "infraServices": [
+ "ollama"
+ ]
+}
diff --git a/camel-jbang-example-catalog.json b/camel-jbang-example-catalog.json
index bd1affb..8908883 100644
--- a/camel-jbang-example-catalog.json
+++ b/camel-jbang-example-catalog.json
@@ -52,6 +52,31 @@
"ollama"
]
},
+ {
+ "name": "ai/genai-observability",
+ "title": "GenAI Observability",
+ "description": "Observe LangChain4j LLM calls with OpenTelemetry
gen_ai spans, Micrometer metrics, and the Camel TUI",
+ "level": "intermediate",
+ "tags": [
+ "ai",
+ "observability",
+ "langchain4j",
+ "opentelemetry",
+ "genai",
+ "tui"
+ ],
+ "bundled": false,
+ "requiresDocker": true,
+ "hasCitrusTests": false,
+ "files": [
+ "GenAiObservabilityRoute.java",
+ "README.md",
+ "application.properties"
+ ],
+ "infraServices": [
+ "ollama"
+ ]
+ },
{
"name": "ai/openai-pii-redaction",
"title": "OpenAI PII Redaction",