Skip to main content

Quick Start

This guide deploys the AIObserve Stack with VeloDB Cloud as the observability storage backend. It starts an OpenTelemetry Collector and Grafana, then optionally connects the OpenTelemetry Demo e-commerce application to generate telemetry.

The deployment path in this guide is intended for local development and proof of concept use. Do not use the shared administrator account from this guide for a production deployment. Create separate least-privilege accounts for ingestion and read-only queries before production use.

What you will deploy

Instrumented application
-> OpenTelemetry Collector
-> VeloDB Cloud
-> Grafana with Doris App

The base stack starts the Collector and Grafana. The optional e-commerce demo starts separately so that it reuses the same Collector and Grafana instead of starting duplicate services.

Prerequisites

  • A VeloDB Cloud warehouse that is running.
  • Docker Desktop with Docker Compose v2.
  • Access to your warehouse connection information and a warehouse SQL user.

In the VeloDB Console, open the warehouse details and record the following values:

ValueExampleUsed for
Warehouse hostlb-xxxxxxxx.us-west-1.amazonaws.comBoth connections
HTTP port8080OpenTelemetry Stream Load
MySQL port9030Collector schema setup and Grafana queries
Warehouse SQL user and passwordadminLocal proof of concept only

Wait until the warehouse and its cluster are ready before continuing. A warehouse can show Running before a backend is ready to accept loads.

1. Deploy the base stack

Clone the repository and create a local environment file:

git clone https://github.com/ai-observe/ai-observe-stack.git
cd ai-observe-stack/docker
cp .env.example .env

Edit .env and replace the connection values. The current repository uses DORIS_* variable names for compatibility with the Doris exporter. They are also the correct variables when VeloDB Cloud is the storage backend.

# Include the protocol for the HTTP endpoint.
DORIS_FE_HTTP_ENDPOINT=http://<warehouse-host>:8080

# Do not include http:// for the MySQL endpoint.
DORIS_FE_MYSQL_ENDPOINT=<warehouse-host>:9030

DORIS_USERNAME=<warehouse-sql-user>
DORIS_PASSWORD=<warehouse-sql-password>

DORIS_DATABASE=otel
DORIS_TABLE_LOGS=otel_logs
DORIS_TABLE_TRACES=otel_traces
DORIS_TABLE_METRICS=otel_metrics

# Use an IANA timezone name that matches your working location.
DORIS_TIMEZONE=America/Los_Angeles

# These credentials are for your local Grafana instance.
GRAFANA_ADMIN_USER=admin
GRAFANA_ADMIN_PASSWORD=<local-grafana-password>

Do not run source .env before starting Docker Compose. Shell environment variables have higher priority than values in .env, so an old exported value can silently override an edited password or endpoint.

Start the external VeloDB Cloud mode:

docker compose -f docker-compose-without-doris.yaml up -d
docker compose -f docker-compose-without-doris.yaml ps

Both grafana and otel-collector should show as running. Grafana is available at http://localhost:3000.

Troubleshoot warehouse readiness

If Collector logs contain the following message, the connection and credentials may be correct but the VeloDB backend is not ready for writes:

No backend available for load

Wait a few minutes, then use the VeloDB SQL Editor to run:

SHOW BACKENDS;

Continue when the backend is alive. Restart the Collector after the warehouse is ready:

docker compose -f docker-compose-without-doris.yaml up -d --force-recreate otel-collector

2. Verify the bundled Doris App

Doris App is the Grafana app plugin that provides the observability workflows used in this guide, including Discover, Traces, and pre-provisioned dashboards. It queries the logs, traces, and metrics that the Collector stores in VeloDB Cloud.

The supplied docker-compose-without-doris.yaml bundles and enables Doris App. Confirm that the plugin is present in the Grafana container:

docker compose -f docker-compose-without-doris.yaml exec grafana \
ls /var/lib/grafana/plugins/velodb-doris-app/plugin.json

The command prints the plugin manifest path. You can also confirm the user-facing result by opening http://localhost:3000/a/velodb-doris-app/discover. If the Doris App navigation entry and the Discover page are available, the plugin is installed and enabled.

Use your own Grafana

If you use an existing Grafana deployment instead of the Grafana container in this guide, install and enable Doris App before following the verification steps.

  1. Download the Doris App release package from the Doris App releases page. Extract it into Grafana's plugin directory as velodb-doris-app.

  2. Allow the unsigned plugin in your Grafana configuration:

    GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS=velodb-doris-app
  3. Provision the app by creating a file such as provisioning/plugins/doris-app.yaml:

    apiVersion: 1
    apps:
    - type: velodb-doris-app
    org_id: 1
    disabled: false
  4. Restart Grafana, then open Doris App from the Grafana navigation. Configure a VeloDB data source separately with a read-only warehouse SQL user.

For a Docker-based Grafana deployment, mount the extracted plugin directory at /var/lib/grafana/plugins/velodb-doris-app and mount the provisioning file at /etc/grafana/provisioning/plugins/doris-app.yaml. Review the plugin before allowing an unsigned plugin in a production environment.

3. Open Grafana

Open http://localhost:3000. Anonymous users have Viewer access and can explore the pre-provisioned dashboards. Select Sign in and use the local Grafana credentials from .env when you need to create a dashboard or edit a query.

The pre-provisioned dashboards are read-only from the Grafana UI. Create a personal dashboard for experiments instead of editing a pre-provisioned dashboard.

4. Optional: run the e-commerce demo application

The external VeloDB Cloud Compose file starts only the Collector and Grafana. It does not start an application that produces telemetry.

The same repository includes the OpenTelemetry Demo e-commerce application. The following steps connect its application services to the existing base stack without starting a second Collector, Grafana, or storage backend.

First, confirm the base stack network name:

docker network ls | grep aiobs-net

For a default clone, the name is docker_aiobs-net. If your output uses a different name, use that name in the override file below.

Create ai-observe-stack/doris-opentelemetry-demo/docker-compose.app-only.yml with the following contents:

networks:
default:
external: true
name: docker_aiobs-net

Start the application dependencies:

cd ../doris-opentelemetry-demo
docker compose \
-f docker-compose.minimal.yml \
-f docker-compose.app-only.yml \
up -d --no-deps valkey-cart flagd

Start the application services:

docker compose \
-f docker-compose.minimal.yml \
-f docker-compose.app-only.yml \
up -d --no-deps \
ad cart currency email payment product-catalog quote recommendation shipping \
checkout image-provider frontend load-generator frontend-proxy

The first image pull can take several minutes. If a particular image stops making progress, pull that image on its own and rerun the command. For example:

docker pull ghcr.io/open-telemetry/demo:2.0.2-load-generator

Confirm that the application services are running:

docker compose \
-f docker-compose.minimal.yml \
-f docker-compose.app-only.yml \
ps

Open http://localhost:8080 to use the storefront. Browse products, add an item to the cart, and place an order. The Load Generator also creates background traffic automatically.

5. Verify traces

In Grafana, open Doris App and then Traces. Select the following values:

  • Data source: Doris
  • Database: otel
  • Table: otel_traces
  • Time range: Last 15 minutes

Select load-generator as the Service and click Find Traces. Open a recent trace to see an end-to-end order flow such as:

load-generator
-> frontend-proxy
-> frontend
-> checkout
-> cart, payment, shipping, email

The Trace search page may return no results when you select an internal service such as checkout, even though its spans exist in VeloDB. Use an entry service such as load-generator, then inspect the complete trace waterfall.

6. Verify logs

Open Doris App and then Discover. Select otel_logs and use Lucene mode. The following query finds e-commerce proxy access logs:

body:"/api/checkout"

The current demo exports frontend-proxy access logs through OTLP. Application logs written only to a container's standard output, such as the checkout service's payment went through message, are not collected by the base stack. The Collector accepts OTLP logs only and does not scrape Docker container stdout.

7. Verify metrics

Create a personal Grafana dashboard, add a Table visualization, select the Doris data source, and run the following query:

SELECT
metric_name,
COUNT(*) AS sample_count
FROM (
SELECT timestamp, metric_name, service_name
FROM otel.otel_metrics_sum

UNION ALL

SELECT timestamp, metric_name, service_name
FROM otel.otel_metrics_histogram

UNION ALL

SELECT timestamp, metric_name, service_name
FROM otel.otel_metrics_gauge
) AS all_metrics
WHERE $__timeFilter(timestamp)
AND service_name = 'checkout'
GROUP BY metric_name
ORDER BY sample_count DESC;

With the dashboard time range set to Last 15 minutes, the query returns metrics such as rpc.client.duration, rpc.server.duration, and Go runtime metrics. sample_count is the number of stored metric samples. It is not a request count or an order count.

What you have verified

At this point, the following telemetry path is working:

E-commerce demo traces and metrics
-> OpenTelemetry Collector
-> VeloDB Cloud
-> Grafana

The demo also verifies proxy access logs. To collect application stdout logs, add a log collector or configure the application to export logs through OTLP.

Stop the demo

To stop the e-commerce application while keeping the base Collector and Grafana running:

cd ai-observe-stack/doris-opentelemetry-demo
docker compose \
-f docker-compose.minimal.yml \
-f docker-compose.app-only.yml \
down

To stop the base stack later:

cd ai-observe-stack/docker
docker compose -f docker-compose-without-doris.yaml down