Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 53602fc

Browse files
authored
docs: improve OTel monitoring doc with Quick Start guide and VS Code settings examples (#4243)
- Replace env var Quick Start with step-by-step Aspire Dashboard guide - Add concise intro explaining what the Aspire Dashboard is - Convert all example configurations from env vars to VS Code settings JSON - Keep env var reference table for official documentation - Note where env vars are still required (e.g. auth headers)
1 parent 96b2b2f commit 53602fc

1 file changed

Lines changed: 150 additions & 60 deletions

File tree

docs/monitoring/agent_monitoring.md

Lines changed: 150 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,54 @@ All signal names and attributes follow the [OTel GenAI Semantic Conventions](htt
66

77
## Quick Start
88

9-
Set these environment variables before launching VS Code:
9+
The fastest way to see Copilot Chat traces locally — no cloud account required. This guide uses the [Aspire Dashboard](https://aspire.dev/dashboard/standalone/), a lightweight container image from Microsoft that provides a trace viewer with a built-in OTLP endpoint. It can be used standalone, without the rest of .NET Aspire.
10+
11+
### Prerequisites
12+
13+
- **Docker** installed
14+
- **VS Code** with the GitHub Copilot Chat extension
15+
16+
### 1. Start the Aspire Dashboard
1017

1118
```bash
12-
# Enable OTel and point to a local collector
13-
export COPILOT_OTEL_ENABLED=true
14-
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
19+
docker run --rm -d \
20+
-p 18888:18888 \
21+
-p 4317:18889 \
22+
--name aspire-dashboard \
23+
mcr.microsoft.com/dotnet/aspire-dashboard:latest
24+
```
25+
26+
This exposes the dashboard UI on port `18888` and an OTLP (gRPC) endpoint on port `4317`.
1527

16-
# Launch VS Code
17-
code .
28+
### 2. Configure VS Code
29+
30+
Open **Settings** (`Ctrl+,`) and add:
31+
32+
```json
33+
{
34+
"github.copilot.chat.otel.enabled": true,
35+
"github.copilot.chat.otel.exporterType": "otlp-grpc",
36+
"github.copilot.chat.otel.otlpEndpoint": "http://localhost:4317"
37+
}
1838
```
1939

20-
That's it. Traces, metrics, and events start flowing to your collector.
40+
> **Note:** You can also use environment variables instead of VS Code settings (see [Configuration](#configuration)). Environment variables always take precedence.
41+
42+
### 3. Generate Telemetry
43+
44+
Open Copilot Chat and send any message — for example, ask a question in Agent mode.
45+
46+
### 4. View Traces
47+
48+
Open http://localhost:18888**Traces**. You'll see `invoke_agent` spans with nested `chat` and `execute_tool` children.
2149

22-
> **Tip:** To get started quickly with a local trace viewer, run [Jaeger](https://www.jaegertracing.io/) in Docker:
23-
> ```bash
24-
> docker run -d --name jaeger -p 16686:16686 -p 4318:4318 jaegertracing/jaeger:latest
25-
> ```
26-
> Then open http://localhost:16686 and look for service `copilot-chat`.
50+
### Teardown
51+
52+
```bash
53+
docker stop aspire-dashboard
54+
```
55+
56+
> **Tip:** See the [Aspire Dashboard standalone docs](https://aspire.dev/dashboard/standalone/) for more configuration options.
2757
2858
---
2959

@@ -278,10 +308,12 @@ These custom attributes are included in all traces, metrics, and events, allowin
278308

279309
By default, **no prompt content, responses, or tool arguments are captured** — only metadata like model names, token counts, and durations.
280310

281-
To capture full content:
311+
To capture full content, add to your VS Code settings:
282312

283-
```bash
284-
export COPILOT_OTEL_CAPTURE_CONTENT=true
313+
```json
314+
{
315+
"github.copilot.chat.otel.captureContent": true
316+
}
285317
```
286318

287319
This populates these span attributes:
@@ -305,25 +337,33 @@ Content is captured in full with no truncation.
305337

306338
**OTLP/gRPC:**
307339

308-
```bash
309-
export COPILOT_OTEL_ENABLED=true
310-
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
311-
export OTEL_EXPORTER_OTLP_PROTOCOL=grpc
340+
```json
341+
{
342+
"github.copilot.chat.otel.enabled": true,
343+
"github.copilot.chat.otel.exporterType": "otlp-grpc",
344+
"github.copilot.chat.otel.otlpEndpoint": "http://localhost:4317"
345+
}
312346
```
313347

314348
**Remote collector with authentication:**
315349

316-
```bash
317-
export COPILOT_OTEL_ENABLED=true
318-
export OTEL_EXPORTER_OTLP_ENDPOINT=https://collector.example.com:4318
319-
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer your-token"
350+
```json
351+
{
352+
"github.copilot.chat.otel.enabled": true,
353+
"github.copilot.chat.otel.otlpEndpoint": "https://collector.example.com:4318"
354+
}
320355
```
321356

357+
> **Note:** Authentication headers are only configurable via the `OTEL_EXPORTER_OTLP_HEADERS` environment variable (e.g., `Authorization=Bearer your-token`). See [Environment Variables](#environment-variables).
358+
322359
**File-based output (offline / CI):**
323360

324-
```bash
325-
export COPILOT_OTEL_ENABLED=true
326-
export COPILOT_OTEL_FILE_EXPORTER_PATH=/tmp/copilot-otel.jsonl
361+
```json
362+
{
363+
"github.copilot.chat.otel.enabled": true,
364+
"github.copilot.chat.otel.exporterType": "file",
365+
"github.copilot.chat.otel.outfile": "/tmp/copilot-otel.jsonl"
366+
}
327367
```
328368

329369
**Console output (quick debugging):**
@@ -376,66 +416,89 @@ First successful span export is logged to the console (`[OTel] First span batch
376416

377417
---
378418

379-
## Backend Setup & Verification
419+
## Backend Setup Guides
420+
421+
Copilot Chat's OTel data works with any OTLP-compatible backend. This section provides step-by-step setup guides for recommended backends.
380422

381-
Copilot Chat's OTel data works with any OTLP-compatible backend. This section covers setup and verification for recommended backends.
423+
### Aspire Dashboard
424+
425+
See [Quick Start](#quick-start) above for setup. The [Aspire Dashboard](https://aspire.dev/dashboard/standalone/) is the simplest option — a single Docker container with a built-in OTLP endpoint and trace viewer. No cloud account or collector needed.
382426

383427
### OTel Collector + Azure Application Insights
384428

385429
[Azure Application Insights](https://learn.microsoft.com/en-us/azure/azure-monitor/app/app-insights-overview) ingests OTel traces, metrics, and logs through an [OTel Collector](https://opentelemetry.io/docs/collector/) with the `azuremonitor` exporter. This repo includes a ready-to-use collector setup in `docs/monitoring/`.
386430

387-
**1. Start the collector:**
431+
**1. Create an Application Insights resource:**
432+
433+
1. Go to the [Azure Portal](https://portal.azure.com/).
434+
2. Click **Create a resource** → search **Application Insights****Create**.
435+
3. Choose your subscription, resource group, name, and region → **Review + Create****Create**.
436+
4. Once deployed, go to the resource → **Overview** → copy the **Connection String**.
437+
438+
**2. Start the OTel Collector:**
388439

389440
```bash
390-
# Set your App Insights connection string (from Azure Portal → App Insights → Overview)
391441
export APPLICATIONINSIGHTS_CONNECTION_STRING="InstrumentationKey=...;IngestionEndpoint=..."
392442

393-
# Start the OTel Collector
394443
cd docs/monitoring
395444
docker compose up -d
396445
```
397446

398-
**2. Verify the collector is healthy:**
447+
Verify the collector is healthy:
399448

400449
```bash
401450
# Should return 200
402451
curl -s -o /dev/null -w "%{http_code}" http://localhost:4328/v1/traces \
403452
-X POST -H "Content-Type: application/json" -d '{"resourceSpans":[]}'
404453
```
405454

406-
**3. Launch VS Code:**
455+
**3. Configure VS Code:**
407456

408-
```bash
409-
COPILOT_OTEL_ENABLED=true \
410-
COPILOT_OTEL_CAPTURE_CONTENT=true \
411-
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4328 \
412-
code .
457+
Open **Settings** (`Ctrl+,`) and add:
458+
459+
```json
460+
{
461+
"github.copilot.chat.otel.enabled": true,
462+
"github.copilot.chat.otel.exporterType": "otlp-http",
463+
"github.copilot.chat.otel.otlpEndpoint": "http://localhost:4328"
464+
}
465+
```
466+
467+
Optionally, to capture full prompt/response content:
468+
469+
```json
470+
{
471+
"github.copilot.chat.otel.captureContent": true
472+
}
413473
```
414474

415-
**4. Generate telemetry** — Send a chat message in Copilot Chat (e.g., "explain this file" in agent mode).
475+
> **Warning:** Content capture includes prompts, code, and file contents. Only enable in trusted environments.
416476
417-
**5. Verify in App Insights:**
477+
**4. Generate telemetry** — Open Copilot Chat and send any message (e.g., use Agent mode).
418478

419-
- **Traces:** Application Insights → Transaction search → filter by "Trace" or "Request".
479+
**5. Verify data:**
420480

421-
- **Logs:** Application Insights → Logs:
422-
```kql
423-
traces
424-
| where timestamp > ago(1h)
425-
| where message contains "GenAI" or message contains "copilot_chat"
426-
| project timestamp, message, customDimensions
427-
| order by timestamp desc
428-
```
481+
- **Jaeger (local):** Open http://localhost:16687, select service `copilot-chat`, click **Find Traces**.
482+
- **App Insights (Azure):** Go to your Application Insights resource → **Transaction search** → filter by "Trace" or "Request".
429483

430-
- **Metrics:** Application Insights → Metrics → "Custom" namespace, or via Logs:
431-
```kql
432-
customMetrics
433-
| where timestamp > ago(1h)
434-
| where name startswith "gen_ai" or name startswith "copilot_chat"
435-
| summarize avg(value), count() by name
436-
```
484+
Run this query in **Application Insights → Logs** to confirm:
437485

438-
> **Note:** Traces typically appear within 1-2 minutes. Metrics may take 5-10 minutes.
486+
```kql
487+
traces
488+
| where timestamp > ago(1h)
489+
| where message contains "GenAI" or message contains "copilot_chat"
490+
| project timestamp, message, customDimensions
491+
| order by timestamp desc
492+
```
493+
494+
For metrics (may take 5–10 minutes to appear):
495+
496+
```kql
497+
customMetrics
498+
| where timestamp > ago(1h)
499+
| where name startswith "gen_ai" or name startswith "copilot_chat"
500+
| summarize avg(value), count() by name
501+
```
439502

440503
**Collector config** (`docs/monitoring/otel-collector-config.yaml`):
441504

@@ -466,18 +529,45 @@ service:
466529
467530
> **Note:** The docker-compose maps ports to `4328`/`4327` on the host to avoid conflicts. Adjust in `docker-compose.yaml` if needed. Add additional exporters (e.g., `otlphttp/jaeger`) to fan out to multiple backends. See `docs/monitoring/otel-collector-config.yaml` for the full config including `batch` processor and `logs` pipeline.
468531

532+
### Jaeger
533+
534+
[Jaeger](https://www.jaegertracing.io/) is an open-source distributed tracing platform. It accepts OTLP directly — no collector needed.
535+
536+
**1. Start Jaeger:**
537+
538+
```bash
539+
docker run -d --name jaeger -p 16686:16686 -p 4318:4318 jaegertracing/jaeger:latest
540+
```
541+
542+
**2. Configure VS Code:**
543+
544+
```json
545+
{
546+
"github.copilot.chat.otel.enabled": true,
547+
"github.copilot.chat.otel.otlpEndpoint": "http://localhost:4318"
548+
}
549+
```
550+
551+
**3. Verify:** Open http://localhost:16686, select service `copilot-chat`, and click **Find Traces**.
469552

470553
### Langfuse
471554

472555
[Langfuse](https://langfuse.com/) is an open-source LLM observability platform with native OTLP ingestion and support for [OTel GenAI Semantic Conventions](https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-agent-spans/). See the [Langfuse docs](https://langfuse.com/docs/opentelemetry/introduction) for full details on capabilities and limitations.
473556

474557
**Setup:**
475558

559+
```json
560+
{
561+
"github.copilot.chat.otel.enabled": true,
562+
"github.copilot.chat.otel.otlpEndpoint": "http://localhost:3000/api/public/otel",
563+
"github.copilot.chat.otel.captureContent": true
564+
}
565+
```
566+
567+
Then set the auth header via environment variable (required — no VS Code setting for headers):
568+
476569
```bash
477-
export COPILOT_OTEL_ENABLED=true
478-
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:3000/api/public/otel
479570
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Basic $(echo -n '<public-key>:<secret-key>' | base64)"
480-
export COPILOT_OTEL_CAPTURE_CONTENT=true
481571
```
482572

483573
Replace `<public-key>` and `<secret-key>` with your Langfuse API keys from **Settings → API Keys**.

0 commit comments

Comments
 (0)