Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -1,15 +1,49 @@
# Cisco CircuIT Configuration
CIRCUIT_BASE_URL=https://your-circuit-gateway.cisco.com/v1
CIRCUIT_TOKEN_URL=https://your-circuit-gateway.cisco.com/oauth2/token
CIRCUIT_CLIENT_ID=your_client_id_here
CIRCUIT_CLIENT_SECRET=your_secret_here
CIRCUIT_APP_KEY=llamaindex-zero-code-demo
CIRCUIT_SCOPE=api.read

# OpenTelemetry configuration
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
# Choose ONE auth mode:
# 1) OAuth2 gateway mode (set all required LLM_* fields), or
# 2) Standard OpenAI mode (set OPENAI_API_KEY only).

# =============================================================================
# OAuth2 gateway configuration (preferred for enterprise gateways)
# =============================================================================
# Required for OAuth2 mode:
LLM_CLIENT_ID=
LLM_CLIENT_SECRET=
LLM_TOKEN_URL=
LLM_BASE_URL=
# Optional:
LLM_APP_KEY=
LLM_SCOPE=

# =============================================================================
# Standard OpenAI configuration (fallback mode)
# =============================================================================
OPENAI_API_KEY=sk-...
OPENAI_MODEL_NAME=gpt-4o-mini

# Service Identity
OTEL_SERVICE_NAME=llamaindex-zero-code-example
OTEL_RESOURCE_ATTRIBUTES=deployment.environment=demo
# OTLP Exporter
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
OTEL_EXPORTER_OTLP_PROTOCOL=grpc
# Logs
OTEL_LOGS_EXPORTER=otlp
OTEL_PYTHON_LOG_CORRELATION=true
OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED=true
# Metrics
OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=delta

#Optional
DEEPEVAL_LLM_BASE_URL=https://<your-llm-gateway>/openai/deployments/<model>
DEEPEVAL_LLM_MODEL=gpt-4o-mini
DEEPEVAL_LLM_PROVIDER=openai
DEEPEVAL_LLM_CLIENT_ID=<your-oauth2-client-id>
DEEPEVAL_LLM_CLIENT_SECRET=<your-oauth2-client-secret>
DEEPEVAL_LLM_TOKEN_URL=https://<your-identity-provider>/oauth2/token
DEEPEVAL_LLM_CLIENT_APP_NAME=<your-app-key>
DEEPEVAL_FILE_SYSTEM=READ_ONLY

# Instrumentation options
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true
OTEL_INSTRUMENTATION_GENAI_EMITTERS=span_metric_event
#Debug settings
OTEL_INSTRUMENTATION_GENAI_DEBUG=false
OTEL_GENAI_EVAL_DEBUG_SKIPS=false
OTEL_GENAI_EVAL_DEBUG_EACH=false
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ This is an example of how to instrument LlamaIndex calls using zero-code
instrumentation with :code:`opentelemetry-instrument`.

This example provides an HTTP server (:code:`server.py`) that uses
LlamaIndex with Cisco CircuIT API. When run with the :code:`opentelemetry-instrument`
LlamaIndex with either:

- an OAuth2-protected LLM gateway (via :code:`LLM_*` variables), or
- standard OpenAI API key auth (via :code:`OPENAI_API_KEY`).

When run with the :code:`opentelemetry-instrument`
command, it automatically exports traces, metrics, and events to
an OTLP-compatible endpoint.

Expand All @@ -16,7 +21,7 @@ The following packages are required:

- :code:`llama-index>=0.14.0` - LlamaIndex framework
- :code:`python-dotenv>=1.0.0` - Environment variable management
- :code:`requests>=2.31.0` - HTTP client for CircuIT API
- :code:`requests>=2.31.0` - HTTP client for OAuth2 gateway API
- :code:`opentelemetry-distro` - OpenTelemetry distribution with auto-instrumentation
- :code:`opentelemetry-exporter-otlp` - OTLP exporter for traces and metrics

Expand All @@ -29,13 +34,25 @@ Install with:
Environment Variables
---------------------

**Required:**
Choose one auth mode:

**Mode A - OAuth2 Gateway (required fields):**

- ``LLM_BASE_URL`` - LLM gateway chat completions endpoint
- ``LLM_TOKEN_URL`` - OAuth2 token endpoint
- ``LLM_CLIENT_ID`` - OAuth2 client ID
- ``LLM_CLIENT_SECRET`` - OAuth2 client secret

**Mode A - OAuth2 Gateway (optional fields):**

- ``CIRCUIT_BASE_URL`` - CircuIT API endpoint (e.g., https://chat-ai.cisco.com/openai/deployments/gpt-4o-mini/chat/completions)
- ``CIRCUIT_TOKEN_URL`` - OAuth2 token endpoint (e.g., https://id.cisco.com/oauth2/default/v1/token)
- ``CIRCUIT_CLIENT_ID`` - CircuIT OAuth2 client ID
- ``CIRCUIT_CLIENT_SECRET`` - CircuIT OAuth2 client secret
- ``CIRCUIT_APP_KEY`` - CircuIT application key
- ``LLM_APP_KEY`` - app key header or request metadata key
- ``LLM_SCOPE`` - OAuth2 scope
- ``OPENAI_MODEL_NAME`` - model label used for metadata (default: ``gpt-4o-mini``)

**Mode B - OpenAI API key:**

- ``OPENAI_API_KEY`` - OpenAI API key
- ``OPENAI_MODEL_NAME`` - model name (default: ``gpt-4o-mini``)

**OpenTelemetry Configuration:**

Expand Down Expand Up @@ -73,15 +90,79 @@ Telemetry Data
Setup
-----

1. **Create** a :code:`.env` file with your CircuIT credentials:
Set the required environment variables in the :code:`.env` file.

For more information about AI app configuration, see:
`Configure the Python agent for AI applications <https://help.splunk.com/en/splunk-observability-cloud/manage-data/instrument-back-end-services/instrument-back-end-applications-to-send-spans-to-splunk-apm/instrument-a-python-application/configure-the-python-agent-for-ai-applications>`_.

**LLM configuration credentials:**

.. code-block:: console

CIRCUIT_BASE_URL=https://chat-ai.cisco.com/openai/deployments/gpt-4o-mini/chat/completions
CIRCUIT_TOKEN_URL=https://id.cisco.com/oauth2/default/v1/token
CIRCUIT_CLIENT_ID=your-client-id
CIRCUIT_CLIENT_SECRET=your-client-secret
CIRCUIT_APP_KEY=your-app-key
# OpenAI API Key
OPENAI_API_KEY=sk-YOUR_API_KEY

# Or OAuth2 LLM Provider (for enterprise deployments)
LLM_CLIENT_ID=<your-oauth2-client-id>
LLM_CLIENT_SECRET=<your-oauth2-client-secret>
LLM_TOKEN_URL=https://<your-identity-provider>/oauth2/token
LLM_BASE_URL=https://<your-llm-gateway>/openai/deployments
LLM_APP_KEY=<your-app-key> # Optional
LLM_SCOPE=<scope> # Optional

# Example: Cisco CircuIT Configuration
LLM_BASE_URL=https://your-circuit-gateway.cisco.com/v1
LLM_TOKEN_URL=https://your-circuit-gateway.cisco.com/oauth2/token
LLM_CLIENT_ID=your_client_id_here
LLM_CLIENT_SECRET=your_secret_here
LLM_APP_KEY=llamaindex-zero-code-demo
LLM_SCOPE=api.read
Comment on lines +102 to +119
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

LLM_BASE_URL is defined twice in the same code block — confusing for users.

Lines 109 and 114 both set LLM_BASE_URL. Because they appear in a single continuous block, it reads as if the second value overwrites the first. Split this into two separate blocks (one generic template, one CircuIT-specific example) or use comments to clearly delineate that the CircuIT section is an alternative example.

Proposed fix — separate the blocks
        LLM_APP_KEY=<your-app-key>  # Optional
        LLM_SCOPE=<scope>  # Optional

-       # Example: Cisco CircuIT Configuration
-       LLM_BASE_URL=https://your-circuit-gateway.cisco.com/v1
-       LLM_TOKEN_URL=https://your-circuit-gateway.cisco.com/oauth2/token
-       LLM_CLIENT_ID=your_client_id_here
-       LLM_CLIENT_SECRET=your_secret_here
-       LLM_APP_KEY=llamaindex-zero-code-demo
-       LLM_SCOPE=api.read
+
+   Example Cisco CircuIT configuration:
+
+   .. code-block:: console
+
+       LLM_BASE_URL=https://your-circuit-gateway.cisco.com/v1
+       LLM_TOKEN_URL=https://your-circuit-gateway.cisco.com/oauth2/token
+       LLM_CLIENT_ID=your_client_id_here
+       LLM_CLIENT_SECRET=your_secret_here
+       LLM_APP_KEY=llamaindex-zero-code-demo
+       LLM_SCOPE=api.read
🤖 Prompt for AI Agents
In
`@instrumentation-genai/opentelemetry-instrumentation-llamaindex/examples/zero-code/README.rst`
around lines 102 - 119, The README has two LLM configuration examples in one
block where LLM_BASE_URL is defined twice, which is confusing; separate the
generic template and the Cisco CircuIT example into distinct sections (or
clearly mark the CircuIT lines as an alternative example) so values don’t appear
to overwrite each other—move the Cisco-specific lines (the second LLM_BASE_URL,
LLM_TOKEN_URL, LLM_CLIENT_ID, LLM_CLIENT_SECRET, LLM_APP_KEY, LLM_SCOPE) into a
new example block titled e.g. “Example: Cisco CircuIT Configuration” or prefix
them with a comment indicating they are an alternative, keeping the generic
template (OPENAI_API_KEY, LLM_CLIENT_ID, LLM_CLIENT_SECRET, LLM_TOKEN_URL,
LLM_BASE_URL, LLM_APP_KEY, LLM_SCOPE) separate.


**OpenTelemetry configuration settings:**

.. code-block:: console

# Service Identity
OTEL_SERVICE_NAME=llamaindex-zero-code-example
OTEL_RESOURCE_ATTRIBUTES=deployment.environment=demo

# OTLP Exporter
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
OTEL_EXPORTER_OTLP_PROTOCOL=grpc

# Logs
OTEL_LOGS_EXPORTER=otlp
OTEL_PYTHON_LOG_CORRELATION=true
OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED=true

# Metrics
OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=delta

**(Optional) GenAI evaluation settings and debug settings:**

.. code-block:: console

# DeepEval custom LLM-as-a-Judge settings
DEEPEVAL_LLM_BASE_URL=https://<your-llm-gateway>/openai/deployments/<model>
DEEPEVAL_LLM_MODEL=gpt-4o-mini
DEEPEVAL_LLM_PROVIDER=openai
DEEPEVAL_LLM_CLIENT_ID=<your-oauth2-client-id>
DEEPEVAL_LLM_CLIENT_SECRET=<your-oauth2-client-secret>
DEEPEVAL_LLM_TOKEN_URL=https://<your-identity-provider>/oauth2/token
DEEPEVAL_LLM_CLIENT_APP_NAME=<your-app-key>
DEEPEVAL_FILE_SYSTEM=READ_ONLY

# Debug settings
OTEL_INSTRUMENTATION_GENAI_DEBUG=false
OTEL_GENAI_EVAL_DEBUG_SKIPS=false
OTEL_GENAI_EVAL_DEBUG_EACH=false

1. **Create** a :code:`.env` file with the settings above. Example:

.. code-block:: console

OPENAI_API_KEY=sk-...
OPENAI_MODEL_NAME=gpt-4o-mini

2. Set up a virtual environment:

Expand All @@ -102,20 +183,19 @@ Setup
Run Locally
-----------

1. Export environment variables:
1. Start the Splunk Distribution of the OpenTelemetry Collector (example using Docker):

.. code-block:: console

export CIRCUIT_BASE_URL="https://chat-ai.cisco.com/openai/deployments/gpt-4o-mini/chat/completions"
export CIRCUIT_TOKEN_URL="https://id.cisco.com/oauth2/default/v1/token"
export CIRCUIT_CLIENT_ID="your-client-id"
export CIRCUIT_CLIENT_SECRET="your-client-secret"
export CIRCUIT_APP_KEY="your-app-key"
export OTEL_SERVICE_NAME="llamaindex-zero-code-server"
export OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT="true"
export OTEL_INSTRUMENTATION_GENAI_EMITTERS="span_metric_event"
docker run -p 4317:4317 -p 4318:4318 otel/opentelemetry-collector
Comment on lines +186 to +190
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Collector image doesn't match "Splunk Distribution" description.

Line 186 says "Start the Splunk Distribution of the OpenTelemetry Collector" but line 190 uses the community image otel/opentelemetry-collector. Either update the text to say "OpenTelemetry Collector" or use the Splunk distribution image (quay.io/signalfx/splunk-otel-collector).

🤖 Prompt for AI Agents
In
`@instrumentation-genai/opentelemetry-instrumentation-llamaindex/examples/zero-code/README.rst`
around lines 186 - 190, The README currently says "Start the Splunk Distribution
of the OpenTelemetry Collector" but the docker command uses the community image
`otel/opentelemetry-collector`; update this mismatch by either changing the
heading text to "Start the OpenTelemetry Collector" to match the image
`otel/opentelemetry-collector`, or replace the docker image in the code block
with the Splunk distribution image `quay.io/signalfx/splunk-otel-collector` so
the command matches the "Splunk Distribution" description (edit the text and the
docker run line accordingly).


2. Run the server with zero-code instrumentation:
2. Load the environment variables from :code:`.env`:

.. code-block:: console

set -a && source .env && set +a

3. Run the server with zero-code instrumentation:

.. code-block:: console

Expand All @@ -124,15 +204,15 @@ Run Locally
--metrics_exporter otlp \
python server.py

3. The server will start on port 8080. Test it with curl:
4. Send a curl request to generate traces:

.. code-block:: console

curl -X POST http://localhost:8080/chat \
-H "Content-Type: application/json" \
-d '{"message": "What is 2+2?", "system_prompt": "You are a helpful assistant"}'

4. Check for traces and metrics in your observability backend. If you see warnings about
5. Check for traces and metrics in your observability backend. If you see warnings about
connection failures, ensure your OpenTelemetry Collector is running on the configured endpoint.

Docker
Expand All @@ -149,11 +229,11 @@ To build and run with Docker:

# Run with environment variables
docker run -p 8080:8080 \
-e CIRCUIT_BASE_URL=https://chat-ai.cisco.com/openai/deployments/gpt-4o-mini/chat/completions \
-e CIRCUIT_TOKEN_URL=https://id.cisco.com/oauth2/default/v1/token \
-e CIRCUIT_CLIENT_ID=your-client-id \
-e CIRCUIT_CLIENT_SECRET=your-client-secret \
-e CIRCUIT_APP_KEY=your-app-key \
-e LLM_BASE_URL=https://<your-llm-gateway>/openai/deployments/gpt-4o-mini/chat/completions \
-e LLM_TOKEN_URL=https://<your-identity-provider>/oauth2/token \
-e LLM_CLIENT_ID=your-client-id \
-e LLM_CLIENT_SECRET=your-client-secret \
-e LLM_APP_KEY=your-app-key \
-e OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 \
-e OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true \
-e OTEL_INSTRUMENTATION_GENAI_EMITTERS=span_metric_event \
Expand All @@ -168,25 +248,40 @@ Kubernetes Deployment

kubectl create namespace llamaindex-zero-code

2. Create the CircuIT credentials secret:
2. Create OAuth2 gateway secret (optional, if using OAuth2 mode):

.. code-block:: console

kubectl create secret generic llm-credentials \
-n llamaindex-zero-code \
--from-literal=base-url=https://<your-llm-gateway>/openai/deployments/gpt-4o-mini/chat/completions \
--from-literal=token-url=https://<your-identity-provider>/oauth2/token \
--from-literal=client-id=<your-client-id> \
--from-literal=client-secret=<your-client-secret> \
--from-literal=app-key=<your-app-key> \
--from-literal=scope=<your-scope>

3. Create OpenAI secret (optional, if using OpenAI mode):

.. code-block:: console

kubectl apply -f circuit-secret.yaml
kubectl create secret generic openai-credentials \
-n llamaindex-zero-code \
--from-literal=api-key=sk-...

3. Deploy the server:
4. Deploy the server:

.. code-block:: console

kubectl apply -f deployment.yaml

4. Deploy the cronjob client:
5. Deploy the cronjob client:

.. code-block:: console

kubectl apply -f cronjob.yaml

5. Verify the deployment:
6. Verify the deployment:

.. code-block:: console

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,31 +59,50 @@ spec:
name: llamaindex-server-config

env:
- name: CIRCUIT_BASE_URL
- name: LLM_BASE_URL
valueFrom:
secretKeyRef:
name: circuit-credentials
name: llm-credentials
key: base-url
- name: CIRCUIT_TOKEN_URL
optional: true
- name: LLM_TOKEN_URL
valueFrom:
secretKeyRef:
name: circuit-credentials
name: llm-credentials
key: token-url
- name: CIRCUIT_CLIENT_ID
optional: true
- name: LLM_CLIENT_ID
valueFrom:
secretKeyRef:
name: circuit-credentials
name: llm-credentials
key: client-id
- name: CIRCUIT_CLIENT_SECRET
optional: true
- name: LLM_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: circuit-credentials
name: llm-credentials
key: client-secret
- name: CIRCUIT_APP_KEY
optional: true
- name: LLM_APP_KEY
valueFrom:
secretKeyRef:
name: circuit-credentials
name: llm-credentials
key: app-key
optional: true
- name: LLM_SCOPE
valueFrom:
secretKeyRef:
name: llm-credentials
key: scope
optional: true
- name: OPENAI_API_KEY
valueFrom:
secretKeyRef:
name: openai-credentials
key: api-key
optional: true
- name: OPENAI_MODEL_NAME
value: "gpt-4o-mini"
- name: OTEL_SERVICE_NAME
value: "llamaindex-zero-code-server"
- name: OTEL_RESOURCE_ATTRIBUTES
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
llama-index>=0.14.0
python-dotenv>=1.0.0
requests>=2.31.0
opentelemetry-distro
opentelemetry-exporter-otlp
splunk-otel-instrumentation-llamaindex
splunk-otel-util-genai
splunk-otel-genai-emitters-splunk
splunk-otel-util-genai-evals
splunk-otel-genai-evals-deepeval
Loading