forked from jsl/video_editing_poc
240 lines
7.2 KiB
Markdown
240 lines
7.2 KiB
Markdown
# Grafana Dashboard Creation Prompt
|
|
|
|
Use this prompt with the AI instance running on the VPS server.
|
|
|
|
```md
|
|
You are working on the `video-clipping-service` project. Create the full Grafana dashboard definition for this service as a Grafana dashboard JSON document that can be imported directly into Grafana.
|
|
|
|
Your task is to produce the complete dashboard artifact, not a partial sketch.
|
|
|
|
## Output requirements
|
|
|
|
- Return a single valid Grafana dashboard JSON document.
|
|
- The JSON must be importable in Grafana without manual structural edits.
|
|
- Use a Prometheus data source variable named `DS_PROMETHEUS`.
|
|
- Set the Prometheus datasource on every panel to:
|
|
- `"type": "prometheus"`
|
|
- `"uid": "${DS_PROMETHEUS}"`
|
|
- Use Grafana schema/style compatible with Grafana 10.x.
|
|
- Set `"id": null`.
|
|
- Make the dashboard editable.
|
|
- Do not wrap the final JSON in explanations. Output the JSON only.
|
|
|
|
## Dashboard identity
|
|
|
|
- Dashboard title: `Video Clipping Overview`
|
|
- Service/application name: `video-clipping-service`
|
|
- Metrics endpoint scraped by Prometheus: `/actuator/prometheus`
|
|
- Spring Boot Actuator and Micrometer are enabled.
|
|
|
|
## Service context
|
|
|
|
This is a Spring Boot video clipping service. It exposes REST endpoints for:
|
|
|
|
- `POST /v1/video-assets`
|
|
- `POST /v1/video-assets/{assetId}/uploads:complete`
|
|
- `GET /v1/video-assets/{assetId}`
|
|
- `GET /v1/video-assets/{assetId}/upload-session`
|
|
- `GET /v1/video-assets/{assetId}/clip-jobs`
|
|
- `GET /v1/video-assets/{assetId}/events`
|
|
- `POST /v1/video-assets/{assetId}/clip-jobs`
|
|
- `DELETE /v1/video-assets/{assetId}`
|
|
- `GET /v1/clip-jobs/{jobId}`
|
|
- `GET /v1/clip-jobs/{jobId}/clips`
|
|
- `GET /v1/clip-jobs/{jobId}/events`
|
|
- `POST /v1/clip-jobs/{jobId}:cancel`
|
|
- `POST /v1/clips/{clipId}/download-url`
|
|
|
|
Exclude `/actuator` endpoints from API traffic panels.
|
|
|
|
## Available custom queue metrics
|
|
|
|
The service emits these Micrometer metrics for the database-backed queue. In Prometheus naming, dots become underscores:
|
|
|
|
- `video.clipping.queue.pending` -> `video_clipping_queue_pending`
|
|
- `video.clipping.queue.processing` -> `video_clipping_queue_processing`
|
|
- `video.clipping.queue.dlq` -> `video_clipping_queue_dlq`
|
|
- `video.clipping.queue.oldest.pending.age.seconds` -> `video_clipping_queue_oldest_pending_age_seconds`
|
|
|
|
Metric meanings:
|
|
|
|
- `video_clipping_queue_pending`: number of pending clip-job queue messages
|
|
- `video_clipping_queue_processing`: number of claimed messages currently processing
|
|
- `video_clipping_queue_dlq`: number of dead-lettered messages
|
|
- `video_clipping_queue_oldest_pending_age_seconds`: age in seconds of the oldest pending message
|
|
|
|
## Standard Micrometer / Actuator metrics available
|
|
|
|
Use these standard metrics:
|
|
|
|
- `http_server_requests_seconds_count`
|
|
- `http_server_requests_seconds_bucket`
|
|
- `system_cpu_usage`
|
|
- `process_cpu_usage`
|
|
- `jvm_memory_used_bytes{area="heap"}`
|
|
|
|
## Required dashboard layout
|
|
|
|
Create exactly 10 panels arranged in a 24-column Grafana grid.
|
|
|
|
### Row 1: 4 stat panels, each height 8 and width 6
|
|
|
|
1. Panel title: `Pending Queue Depth`
|
|
- Type: `stat`
|
|
- Grid: `x=0, y=0, w=6, h=8`
|
|
- Query: `sum(video_clipping_queue_pending)`
|
|
- Legend: `pending`
|
|
- Unit: `none`
|
|
- Color mode: background
|
|
- Graph mode: area
|
|
- Thresholds:
|
|
- green: default
|
|
- orange at `5`
|
|
- red at `20`
|
|
|
|
2. Panel title: `Oldest Pending Age`
|
|
- Type: `stat`
|
|
- Grid: `x=6, y=0, w=6, h=8`
|
|
- Query: `max(video_clipping_queue_oldest_pending_age_seconds)`
|
|
- Legend: `oldest pending age`
|
|
- Unit: `s`
|
|
- Color mode: background
|
|
- Graph mode: area
|
|
- Thresholds:
|
|
- green: default
|
|
- orange at `30`
|
|
- red at `120`
|
|
|
|
3. Panel title: `DLQ Messages`
|
|
- Type: `stat`
|
|
- Grid: `x=12, y=0, w=6, h=8`
|
|
- Query: `sum(video_clipping_queue_dlq)`
|
|
- Legend: `dlq`
|
|
- Unit: `none`
|
|
- Color mode: background
|
|
- Graph mode: area
|
|
- Thresholds:
|
|
- green: default
|
|
- red at `1`
|
|
|
|
4. Panel title: `Processing Messages`
|
|
- Type: `stat`
|
|
- Grid: `x=18, y=0, w=6, h=8`
|
|
- Query: `sum(video_clipping_queue_processing)`
|
|
- Legend: `processing`
|
|
- Unit: `none`
|
|
- Color mode: background
|
|
- Graph mode: area
|
|
- Thresholds:
|
|
- green: default
|
|
- orange at `1`
|
|
- red at `5`
|
|
|
|
### Row 2: 2 time series panels, each height 8 and width 12
|
|
|
|
5. Panel title: `Queue State Over Time`
|
|
- Type: `timeseries`
|
|
- Grid: `x=0, y=8, w=12, h=8`
|
|
- Unit: `none`
|
|
- Queries:
|
|
- `sum(video_clipping_queue_pending)` legend `pending`
|
|
- `sum(video_clipping_queue_processing)` legend `processing`
|
|
- `sum(video_clipping_queue_dlq)` legend `dlq`
|
|
- Use line draw style, fill opacity around 20, line width 2, show legend at bottom
|
|
|
|
6. Panel title: `Queue Age`
|
|
- Type: `timeseries`
|
|
- Grid: `x=12, y=8, w=12, h=8`
|
|
- Unit: `s`
|
|
- Query:
|
|
- `max(video_clipping_queue_oldest_pending_age_seconds)` legend `oldest pending age`
|
|
- Show legend at bottom
|
|
|
|
### Row 3: 2 time series panels, each height 8 and width 12
|
|
|
|
7. Panel title: `API Request Rate`
|
|
- Type: `timeseries`
|
|
- Grid: `x=0, y=16, w=12, h=8`
|
|
- Unit: `reqps`
|
|
- Query:
|
|
- `sum(rate(http_server_requests_seconds_count{uri!~"/actuator.*"}[5m])) by (method, status)`
|
|
- Legend format: `{{method}} {{status}}`
|
|
- Show legend at bottom
|
|
|
|
8. Panel title: `API p95 Latency`
|
|
- Type: `timeseries`
|
|
- Grid: `x=12, y=16, w=12, h=8`
|
|
- Unit: `s`
|
|
- Query:
|
|
- `histogram_quantile(0.95, sum(rate(http_server_requests_seconds_bucket{uri!~"/actuator.*"}[5m])) by (le, uri, method))`
|
|
- Legend format: `{{method}} {{uri}} p95`
|
|
- Show legend at bottom
|
|
|
|
### Row 4: 2 time series panels, each height 8 and width 12
|
|
|
|
9. Panel title: `CPU Usage`
|
|
- Type: `timeseries`
|
|
- Grid: `x=0, y=24, w=12, h=8`
|
|
- Unit: `percentunit`
|
|
- Queries:
|
|
- `system_cpu_usage` legend `system cpu`
|
|
- `process_cpu_usage` legend `process cpu`
|
|
- Show legend at bottom
|
|
|
|
10. Panel title: `Heap Usage`
|
|
- Type: `timeseries`
|
|
- Grid: `x=12, y=24, w=12, h=8`
|
|
- Unit: `bytes`
|
|
- Query:
|
|
- `jvm_memory_used_bytes{area="heap"}`
|
|
- Legend format: `{{id}}`
|
|
- Show legend at bottom
|
|
|
|
## General panel settings
|
|
|
|
- For stat panels:
|
|
- Reduce calculation: `lastNotNull`
|
|
- `values: false`
|
|
- `textMode: auto`
|
|
- `orientation: auto`
|
|
- `justifyMode: auto`
|
|
|
|
- For timeseries panels:
|
|
- Tooltip mode: `single`
|
|
- Tooltip sort: `none`
|
|
- Legend display mode: `list`
|
|
- Legend placement: `bottom`
|
|
- Show legend: `true`
|
|
|
|
- For timeseries field defaults where reasonable:
|
|
- Color mode: `palette-classic`
|
|
- Line width: `2`
|
|
- Show points: `never`
|
|
- Gradient mode: `none`
|
|
- Stacking mode: `none`
|
|
|
|
## Dashboard metadata
|
|
|
|
Include standard Grafana dashboard metadata such as:
|
|
|
|
- annotations with the default Grafana annotations block
|
|
- `editable: true`
|
|
- `graphTooltip: 0`
|
|
- `links: []`
|
|
- `liveNow: false`
|
|
- `fiscalYearStartMonth: 0`
|
|
|
|
## Acceptance criteria
|
|
|
|
The generated JSON is only acceptable if:
|
|
|
|
- it imports as a full dashboard in Grafana
|
|
- all 10 required panels exist
|
|
- every panel uses the `DS_PROMETHEUS` datasource variable
|
|
- the PromQL expressions exactly match the queries specified above
|
|
- the panel titles, units, thresholds, and grid positions match the specification above
|
|
- `/actuator` traffic is excluded from the API panels
|
|
|
|
Return only the final Grafana dashboard JSON.
|
|
```
|