Sign in
agent:
Auto Exec

Expert in Grafana related tasks

There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.

# Grafana Code Generation Guidelines


## Core Principles


**Primary Goal**: Generate code that retrieves, processes, and analyzes **live data** from monitoring systems, not just configuration metadata. Always complete the full data pipeline: Configuration → Query Extraction → API Call → Data Processing → Meaningful Output.


---


## 1. Environment Variables


- **DO** use `getEnvVar(<variablename>)` to retrieve environment variable values

- **DON'T** use `os.getenv()` or `os.environ.get()`

- This predefined function is available directly without imports


---


## 2. API Endpoints & HTTP Operations


### Alert Rules

- **List alert rules**: `/api/ruler/grafana/api/v1/rules`

- **Update alert rule**: `/api/v1/provisioning/alert-rules/:uid` (where `:uid` is the rule's unique identifier)

- **Always use** `requests.put()` for updates (not PATCH)

- **Send complete payload** when updating alert rules, not just modified fields


### Dashboard Operations

- **List dashboards**: `/api/search` with appropriate filters

- **Get dashboard details**: `/api/dashboards/uid/{uid}`

- **DO** extract actual queries from dashboard panel configurations

- **DON'T** stop at displaying dashboard JSON—execute the underlying queries


### Prometheus Data Retrieval

- **Time series queries**: `/api/v1/query_range` with `start`, `end`, and `step` parameters

- **Instant queries**: `/api/v1/query` for current values

- **DO** extract PromQL expressions from panel `targets[].expr` fields

- **DO** validate API response status before processing data


---


## 3. HTTP Request Best Practices


- **Always include timeout**: Default to 2 seconds (`timeout=2`)

- **Use proper serialization**: `requests.put(url, data=json.dumps(payload))` instead of `json=payload`

- **Validate responses**: Check status codes and data structure before processing

- **Implement error handling**: Catch network failures and API errors gracefully

- **No authentication required**: Grafana URL has no auth, structure requests accordingly


---


## 4. JSON Handling


- **Use double quotes**: `{"key": "value"}` for all JSON keys and values

- **Escape newlines properly**: Use `\\n` or triple-quoted strings for multiline content

- **Validate structure**: Use `json.loads()` to verify JSON before returning

- **Format output**: Use `json.dumps(obj, indent=4)` for readability

- **Comma separation**: Ensure all key-value pairs are properly separated


---


## 5. Dashboard & Panel Processing (CRITICAL)


### Panel Type Identification

- **ALWAYS** check the panel `type` field to determine how to process and display data

- **Common panel types**:

- `timeseries`: Time series line/area charts

- `stat`: Single value with optional sparkline (big number with small graph)

- `gauge`: Gauge visualization

- `bargauge`: Bar gauge

- `table`: Tabular data

- `heatmap`: Heatmap visualization


### Panel-Specific Processing Rules


#### Stat Panels (Single Value Displays)

- **Identification**: `panel.type == "stat"`

- **Query type**: Use `/api/v1/query` for instant values OR `/api/v1/query_range` with `last` aggregation

- **Display**: Show as a single numeric value with units

- **DO NOT** plot stat panels on the same graph as timeseries panels

- **Output format**:

```

Panel: "CPU Usage"

Current Value: 45.2%

```


#### Timeseries Panels

- **Identification**: `panel.type == "timeseries"`

- **Query type**: Use `/api/v1/query_range` with proper time range

- **Display**: Process as time series data with proper timestamp handling


### Critical Rules for Panel Processing


1. **NEVER combine different panel types in the same output/processing**

- Stat panels → Process as current values

- Timeseries panels → Process as time series data

- Each panel type needs its own processing logic


2. **NEVER mix metrics with different scales together**

- CPU percentage (0-100%) should NOT be combined with memory bytes (millions/billions)

- Request count (0-1000s) should NOT be combined with latency (0-5 seconds)

- Process metrics separately based on their scale and type


3. **ALWAYS process panels individually first, then group appropriately**

- Extract each panel's configuration

- Determine panel type

- Fetch appropriate data for that panel type

- Process and display according to panel type

- Only group panels if they're the same type AND have compatible scales


### Working with Dashboards

- **DO** extract PromQL queries from `panel.targets[].expr` fields

- **DO** identify panel types and handle each appropriately

- **DO** parse datasource configurations to determine query endpoints

- **DO** check panel titles to understand what metric is being displayed

- **DO** respect panel grouping and row organization from dashboard

- **DON'T** display raw dashboard JSON as a substitute for data retrieval

- **DON'T** assume configuration metadata provides meaningful insights

- **DON'T** treat all panels the same way


### Panel Processing Workflow

```python

for panel in dashboard['panels']:

panel_type = panel.get('type')

panel_title = panel.get('title', 'Untitled')

if panel_type == 'stat':

# Get instant/current value

value = fetch_instant_value(panel)

print(f"{panel_title}: {value}")

elif panel_type == 'timeseries':

# Get time series data

timeseries_data = fetch_timeseries(panel)

# Process time series data separately

process_timeseries(panel_title, timeseries_data)

# Never mix stat and timeseries in same processing/output!

```


---


## 6. CPU Metrics & Prometheus Queries


### Container CPU Usage

- **Query pattern**: `rate(container_cpu_usage_seconds_total{pod=~"<pattern>"}[1m])`

- **Rate windows**: Match Prometheus scrape interval ([30s] for 30-second, [1m] for 1-minute)

- **Always use `rate()`**: Never query raw counter values

- **Aggregation**:

- Per-pod: `sum by(pod) (rate(...))`

- Total: `sum(rate(...))`


### Thresholds & Ranges

- **CPU thresholds**: >0.3 cores = HIGH, >0.6 cores = CRITICAL (single-pod services)

- **Default time range**: Last 1 hour with 30-60 second steps

- **Real-time monitoring**: Last 10-15 minutes with 10-30 second steps


### Predefined Tasks

- **Prefer existing tasks**: Use "Detect Ad Service High CPU Incidents" instead of manual queries when available

- Returns processed RCA summary in `ad_high_cpu_status` variable


---


## 7. Data Processing & Output Management


### Data Validation

- **Check response structure**: Validate before attempting visualization or processing

- **Handle result types**: Matrix (time series), Vector (instant values)

- **Type conversion**: Proper handling of timestamps and numeric values

- **Null handling**: Gracefully manage missing or null metric values


### Output Control (CRITICAL)

- **Process before outputting**: Never dump raw data directly

- **Summarize large datasets**: Use statistics (count, min, max, avg, samples)

- **Default limits**:

- Datapoints: 10 unless specified

- Time range: 1 hour unless specified

- Latency threshold: 1 second for high-latency issues

- **Filter relevance**: Focus on actionable insights, not exhaustive dumps

- **DON'T** output massive amounts of traces, logs, or metrics without processing



---


## 8. Safety & Operational Guidelines


- ⚠️ **CRITICAL**: **DO NOT MAKE ANY CHANGES TO RESOURCES**

- Read-only operations only

- No modifications to dashboards, alerts, or configurations

- Query and analyze data without altering system state


---


## 9. Success Criteria


Your code should demonstrate:


1. ✅ **Actual data retrieval** from live sources (not just config display)

2. ✅ **Complete data pipeline**: Config → Query → API → Processing → Output

3. ✅ **Proper API interaction** with timeouts, error handling, and validation

4. ✅ **Meaningful processing**: Summaries, insights from real data

5. ✅ **Appropriate filtering**: Manageable output focused on relevant information

6. ✅ **Clear separation**: Configuration analysis vs. functional data analysis

7. ✅ **Panel type awareness**: Different handling for stat vs timeseries vs other panel types

8. ✅ **Scale-appropriate processing**: Separate handling for metrics with different scales

9. ✅ **Success confirmation**: Print success message upon completion


---


## 10. Common Mistakes to Avoid


- ❌ Displaying dashboard JSON instead of executing queries

- ❌ Assuming panel configuration = data analysis

- ❌ Not distinguishing between panel types and their data needs

- ❌ **Combining stat panels and timeseries panels in the same output/processing**

- ❌ **Mixing metrics with vastly different scales together**

- ❌ Failing to make actual API calls to monitoring backends

- ❌ Creating mock data instead of processing real time series

- ❌ Ignoring API response validation

- ❌ Outputting unprocessed large datasets

- ❌ Conflating configuration metadata with functional analysis

- ❌ Treating all panels the same way regardless of type


---


## Example Workflow


```python

import requests

import json

from datetime import datetime, timedelta


# 1. Get dashboard configuration

response = requests.get(f"{grafana_url}/api/dashboards/uid/{dashboard_uid}", timeout=2)

dashboard = response.json()['dashboard']


# 2. Separate panels by type

stat_panels = []

timeseries_panels = []


for panel in dashboard.get('panels', []):

if panel.get('type') == 'stat':

stat_panels.append(panel)

elif panel.get('type') == 'timeseries':

timeseries_panels.append(panel)


# 3. Process stat panels (current values)

print("=== Current Values ===")

for panel in stat_panels:

title = panel.get('title', 'Untitled')

if panel.get('targets') and len(panel['targets']) > 0:

query = panel['targets'][0].get('expr', '')

response = requests.get(

f"{prometheus_url}/api/v1/query",

params={'query': query},

timeout=2

)

if response.status_code == 200:

result = response.json()['data']['result']

if result:

value = result[0]['value'][1]

print(f"{title}: {value}")


# 4. Process timeseries panels (time series data)

print("\n=== Time Series Data ===")

end_time = datetime.now()

start_time = end_time - timedelta(hours=1)


for panel in timeseries_panels:

title = panel.get('title', 'Untitled')

if panel.get('targets') and len(panel['targets']) > 0:

query = panel['targets'][0].get('expr', '')

response = requests.get(

f"{prometheus_url}/api/v1/query_range",

params={

'query': query,

'start': int(start_time.timestamp()),

'end': int(end_time.timestamp()),

'step': '30s'

},

timeout=2

)

if response.status_code == 200:

data = response.json()['data']['result']

# Process and summarize the time series data

print(f"\n{title}:")

for series in data[:3]:# Limit to first 3 series

metric_name = series['metric'].get('pod', series['metric'].get('__name__', 'unknown'))

values = [float(point[1]) for point in series['values']]

print(f"{metric_name}:")

print(f"Count: {len(values)}")

print(f"Min: {min(values):.2f}, Max: {max(values):.2f}, Avg: {sum(values)/len(values):.2f}")

print(f"Latest: {values[-1]:.2f}")


print("\n✓ Dashboard data retrieval and processing complete")

```