Skip to content

Commit 7f46e80

Browse files
chatbot-rag-app: use Elastic Distribution of OpenTelemetry (EDOT) (#369)
Signed-off-by: Adrian Cole <[email protected]>
1 parent dc9dcfe commit 7f46e80

File tree

7 files changed

+171
-5
lines changed

7 files changed

+171
-5
lines changed

example-apps/chatbot-rag-app/Dockerfile

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,20 @@ COPY api ./api
2828
COPY data ./data
2929

3030
EXPOSE 4000
31+
32+
# Default to disabling instrumentation, can be overridden to false in
33+
# docker invocations to reenable.
34+
ENV OTEL_SDK_DISABLED=true
35+
36+
# https://github.com/elastic/genai-instrumentation/issues/255
37+
# Currently Python SDK has a bug that spams logs when opentelemetry-instrument is used
38+
# with SDK being disabled. Until it is fixed, we handle it in our own entrypoint by
39+
# avoiding opentelemetry-instrument when SDK is disabled.
40+
RUN echo 'if [ "${OTEL_SDK_DISABLED:-true}" == "false" ]; \
41+
then \
42+
opentelemetry-instrument $@; \
43+
else \
44+
exec $@; \
45+
fi' > entrypoint.sh
46+
ENTRYPOINT [ "bash", "-eu", "./entrypoint.sh" ]
3147
CMD [ "python", "api/app.py"]

example-apps/chatbot-rag-app/README.md

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,23 @@ dotenv run -- python api/app.py
141141

142142
## Advanced
143143

144+
### OpenTelemetry
145+
146+
If you set `OTEL_SDK_DISABLED=false` in your `.env` file, the app will send
147+
logs, metrics and traces to an OpenTelemetry compatible endpoint.
148+
149+
[env.example](env.example) defaults to use Elastic APM server, started by
150+
[docker-compose-elastic.yml](docker-compose-elastic.yml). If you start your
151+
Elastic stack this way, you can access Kibana like this, authenticating with
152+
the username "elastic" and password "elastic":
153+
154+
http://localhost:5601/app/apm/traces?rangeFrom=now-15m&rangeTo=now
155+
156+
Under the scenes, chatbot-rag-app is automatically instrumented by the Elastic
157+
Distribution of OpenTelemetry (EDOT) Python. While this supports OpenAI, it may
158+
not yet support all LLM providers. You can see more details about EDOT Python
159+
[here](https://github.com/elastic/elastic-otel-python).
160+
144161
### Updating package versions
145162

146163
To update package versions, recreate [requirements.txt](requirements.txt) and
@@ -150,12 +167,16 @@ reinstall like this. Once checked in, any commands above will use updates.
150167
rm -rf .venv
151168
python3 -m venv .venv
152169
source .venv/bin/activate
153-
# Install dev requirements for pip-compile
154-
pip install pip-tools
170+
# Install dev requirements for pip-compile and edot-bootstrap
171+
pip install pip-tools elastic-opentelemetry
155172
# Recreate requirements.txt
156173
pip-compile
157174
# Install main dependencies
158175
pip install -r requirements.txt
176+
# Add opentelemetry instrumentation for these dependencies
177+
edot-bootstrap >> requirements.txt
178+
# Install opentelemetry dependencies
179+
pip install -r requirements.txt
159180
```
160181

161182
### Elasticsearch index and chat_history index

example-apps/chatbot-rag-app/api/llm_integrations.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import os
22

3-
import vertexai
43
from langchain_aws import ChatBedrock
54
from langchain_cohere import ChatCohere
65
from langchain_google_vertexai import ChatVertexAI

example-apps/chatbot-rag-app/docker-compose.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ services:
99
environment:
1010
# host.docker.internal means connect to the host machine, e.g. your laptop
1111
ELASTICSEARCH_URL: "http://host.docker.internal:9200"
12+
OTEL_EXPORTER_OTLP_ENDPOINT: "http://host.docker.internal:8200"
1213
FLASK_APP: api/app.py
1314
env_file:
1415
- .env
@@ -26,6 +27,7 @@ services:
2627
environment:
2728
# host.docker.internal means connect to the host machine, e.g. your laptop
2829
ELASTICSEARCH_URL: "http://host.docker.internal:9200"
30+
OTEL_EXPORTER_OTLP_ENDPOINT: "http://host.docker.internal:8200"
2931
env_file:
3032
- .env
3133
ports:

example-apps/chatbot-rag-app/env.example

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ ES_INDEX_CHAT_HISTORY=workplace-app-docs-chat-history
3131
# AWS_ACCESS_KEY_ID=
3232
# AWS_SECRET_ACCESS_KEY=
3333
# AWS_DEFAULT_REGION=
34-
# CHAT_MODEL=anthropic.claude-3-5-sonnet-20240620-v1:0
34+
# CHAT_MODEL=amazon.titan-text-lite-v1
3535

3636
# Uncomment and complete if you want to use Vertex AI
3737
# LLM_TYPE=vertex
@@ -56,3 +56,24 @@ ES_INDEX_CHAT_HISTORY=workplace-app-docs-chat-history
5656
## Key in https://dashboard.cohere.com/api-keys
5757
# COHERE_API_KEY=
5858
# CHAT_MODEL=command-r7b-12-2024
59+
60+
# Set to false, if you want to record logs, traces and metrics.
61+
OTEL_SDK_DISABLED=true
62+
63+
# Assign the service name that shows up in Kibana
64+
OTEL_SERVICE_NAME=chatbot-rag-app
65+
66+
# Default to send traces to the Elastic APM server
67+
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:8200
68+
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
69+
70+
# Change to 'false' to hide prompt and completion content
71+
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true
72+
73+
# Export metrics every 3 seconds instead of every minute
74+
OTEL_METRIC_EXPORT_INTERVAL=3000
75+
# Export traces every 3 seconds instead of every 5 seconds
76+
OTEL_BSP_SCHEDULE_DELAY=3000
77+
# Change to affect behavior of which resources are detected. Note: these
78+
# choices are specific to the language, in this case Python.
79+
OTEL_EXPERIMENTAL_RESOURCE_DETECTORS=process_runtime,os,otel,telemetry_distro

example-apps/chatbot-rag-app/requirements.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,6 @@ langchain-cohere
1212
langchain-google-vertexai
1313
langchain-aws
1414
langchain-mistralai
15+
16+
# otel dependencies
17+
elastic-opentelemetry

example-apps/chatbot-rag-app/requirements.txt

Lines changed: 105 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# This file is autogenerated by pip-compile with Python 3.13
2+
# This file is autogenerated by pip-compile with Python 3.12
33
# by the following command:
44
#
55
# pip-compile
@@ -44,10 +44,18 @@ cohere==5.13.3
4444
# via langchain-cohere
4545
dataclasses-json==0.6.7
4646
# via langchain-community
47+
deprecated==1.2.15
48+
# via
49+
# opentelemetry-api
50+
# opentelemetry-exporter-otlp-proto-grpc
51+
# opentelemetry-exporter-otlp-proto-http
52+
# opentelemetry-semantic-conventions
4753
distro==1.9.0
4854
# via openai
4955
docstring-parser==0.16
5056
# via google-cloud-aiplatform
57+
elastic-opentelemetry==0.6.0
58+
# via -r requirements.in
5159
elastic-transport==8.15.1
5260
# via elasticsearch
5361
elasticsearch[vectorstore-mmr]==8.17.0
@@ -112,6 +120,10 @@ googleapis-common-protos[grpc]==1.66.0
112120
# google-api-core
113121
# grpc-google-iam-v1
114122
# grpcio-status
123+
# opentelemetry-exporter-otlp-proto-grpc
124+
# opentelemetry-exporter-otlp-proto-http
125+
greenlet==3.1.1
126+
# via sqlalchemy
115127
grpc-google-iam-v1==0.13.1
116128
# via google-cloud-resource-manager
117129
grpcio==1.68.1
@@ -120,6 +132,7 @@ grpcio==1.68.1
120132
# googleapis-common-protos
121133
# grpc-google-iam-v1
122134
# grpcio-status
135+
# opentelemetry-exporter-otlp-proto-grpc
123136
grpcio-status==1.68.1
124137
# via google-api-core
125138
h11==0.14.0
@@ -147,6 +160,8 @@ idna==3.10
147160
# httpx
148161
# requests
149162
# yarl
163+
importlib-metadata==8.5.0
164+
# via opentelemetry-api
150165
itsdangerous==2.2.0
151166
# via flask
152167
jinja2==3.1.4
@@ -223,15 +238,67 @@ numpy==1.26.4
223238
# shapely
224239
openai==1.58.1
225240
# via langchain-openai
241+
opentelemetry-api==1.29.0
242+
# via
243+
# elastic-opentelemetry
244+
# opentelemetry-exporter-otlp-proto-grpc
245+
# opentelemetry-exporter-otlp-proto-http
246+
# opentelemetry-instrumentation
247+
# opentelemetry-instrumentation-system-metrics
248+
# opentelemetry-resourcedetector-gcp
249+
# opentelemetry-sdk
250+
# opentelemetry-semantic-conventions
251+
opentelemetry-exporter-otlp==1.29.0
252+
# via elastic-opentelemetry
253+
opentelemetry-exporter-otlp-proto-common==1.29.0
254+
# via
255+
# opentelemetry-exporter-otlp-proto-grpc
256+
# opentelemetry-exporter-otlp-proto-http
257+
opentelemetry-exporter-otlp-proto-grpc==1.29.0
258+
# via opentelemetry-exporter-otlp
259+
opentelemetry-exporter-otlp-proto-http==1.29.0
260+
# via opentelemetry-exporter-otlp
261+
opentelemetry-instrumentation==0.50b0
262+
# via
263+
# elastic-opentelemetry
264+
# opentelemetry-instrumentation-system-metrics
265+
opentelemetry-instrumentation-system-metrics==0.50b0
266+
# via elastic-opentelemetry
267+
opentelemetry-proto==1.29.0
268+
# via
269+
# opentelemetry-exporter-otlp-proto-common
270+
# opentelemetry-exporter-otlp-proto-grpc
271+
# opentelemetry-exporter-otlp-proto-http
272+
opentelemetry-resource-detector-azure==0.1.5
273+
# via elastic-opentelemetry
274+
opentelemetry-resourcedetector-gcp==1.7.0a0
275+
# via elastic-opentelemetry
276+
opentelemetry-sdk==1.29.0
277+
# via
278+
# elastic-opentelemetry
279+
# opentelemetry-exporter-otlp-proto-grpc
280+
# opentelemetry-exporter-otlp-proto-http
281+
# opentelemetry-resource-detector-azure
282+
# opentelemetry-resourcedetector-gcp
283+
# opentelemetry-sdk-extension-aws
284+
opentelemetry-sdk-extension-aws==2.0.2
285+
# via elastic-opentelemetry
286+
opentelemetry-semantic-conventions==0.50b0
287+
# via
288+
# elastic-opentelemetry
289+
# opentelemetry-instrumentation
290+
# opentelemetry-sdk
226291
orjson==3.10.12
227292
# via langsmith
228293
packaging==24.2
229294
# via
295+
# elastic-opentelemetry
230296
# google-cloud-aiplatform
231297
# google-cloud-bigquery
232298
# huggingface-hub
233299
# langchain-core
234300
# marshmallow
301+
# opentelemetry-instrumentation
235302
pandas==2.2.3
236303
# via langchain-cohere
237304
parameterized==0.9.0
@@ -253,7 +320,10 @@ protobuf==5.29.2
253320
# googleapis-common-protos
254321
# grpc-google-iam-v1
255322
# grpcio-status
323+
# opentelemetry-proto
256324
# proto-plus
325+
psutil==6.1.1
326+
# via opentelemetry-instrumentation-system-metrics
257327
pyasn1==0.6.1
258328
# via
259329
# pyasn1-modules
@@ -306,6 +376,8 @@ requests==2.32.3
306376
# langchain
307377
# langchain-community
308378
# langsmith
379+
# opentelemetry-exporter-otlp-proto-http
380+
# opentelemetry-resourcedetector-gcp
309381
# requests-toolbelt
310382
# tiktoken
311383
requests-toolbelt==1.0.0
@@ -352,10 +424,13 @@ types-requests==2.32.0.20241016
352424
# via cohere
353425
typing-extensions==4.12.2
354426
# via
427+
# anyio
355428
# cohere
356429
# huggingface-hub
357430
# langchain-core
358431
# openai
432+
# opentelemetry-resourcedetector-gcp
433+
# opentelemetry-sdk
359434
# pydantic
360435
# pydantic-core
361436
# sqlalchemy
@@ -372,5 +447,34 @@ urllib3==2.2.3
372447
# types-requests
373448
werkzeug==3.1.3
374449
# via flask
450+
wrapt==1.17.0
451+
# via
452+
# deprecated
453+
# opentelemetry-instrumentation
375454
yarl==1.18.3
376455
# via aiohttp
456+
zipp==3.21.0
457+
# via importlib-metadata
458+
opentelemetry-instrumentation-asyncio==0.50b0
459+
opentelemetry-instrumentation-dbapi==0.50b0
460+
opentelemetry-instrumentation-logging==0.50b0
461+
opentelemetry-instrumentation-sqlite3==0.50b0
462+
opentelemetry-instrumentation-threading==0.50b0
463+
opentelemetry-instrumentation-urllib==0.50b0
464+
opentelemetry-instrumentation-wsgi==0.50b0
465+
opentelemetry-instrumentation-aiohttp-client==0.50b0
466+
opentelemetry-instrumentation-aiohttp-server==0.50b0
467+
opentelemetry-instrumentation-boto3sqs==0.50b0
468+
opentelemetry-instrumentation-botocore==0.50b0
469+
opentelemetry-instrumentation-click==0.50b0
470+
opentelemetry-instrumentation-elasticsearch==0.50b0
471+
opentelemetry-instrumentation-flask==0.50b0
472+
opentelemetry-instrumentation-grpc==0.50b0
473+
opentelemetry-instrumentation-httpx==0.50b0
474+
opentelemetry-instrumentation-jinja2==0.50b0
475+
opentelemetry-instrumentation-requests==0.50b0
476+
opentelemetry-instrumentation-sqlalchemy==0.50b0
477+
opentelemetry-instrumentation-system-metrics==0.50b0
478+
opentelemetry-instrumentation-tortoiseorm==0.50b0
479+
opentelemetry-instrumentation-urllib3==0.50b0
480+
elastic-opentelemetry-instrumentation-openai==0.6.0

0 commit comments

Comments
 (0)