Grafana IDE Insights
A VS Code extension to view Grafana metrics (Prometheus), logs (Loki),
dashboards, and alerts for your application directly inside the IDE,
with easy switching between multiple Grafana instances (e.g. test and
prod).
Features
- Metrics: run a PromQL query against a configured instance and render it
as a line chart in a webview panel.
- Logs: tail a LogQL query in a VS Code Output channel, polling for new
lines on an interval.
- Multiple instances: define named Grafana instances (URL + datasource
UIDs) in settings, and switch the "active" one via a command.
- Secure tokens: API tokens are never stored in settings/JSON — they're
kept in VS Code's built-in Secret Storage (OS keychain).
- Open in Grafana: jump straight to the equivalent Grafana Metrics
Drilldown app URL in your browser for the full experience.
- Dashboards: search Grafana's own dashboards by title and open one
directly in your browser.
- Alerts: view currently active/firing alerts from Grafana's built-in
Alertmanager in an Output channel.
Setup
The fastest way to get started is the built-in walkthrough: open the Command
Palette and run Welcome: Open Walkthrough…, then pick "Get Started with
Grafana IDE Insights" (or it may open automatically on first install). It
walks through the same steps below, with buttons that run the right commands
for you.
You can also configure everything manually:
1. Create a Grafana service account token
For each Grafana instance (test/prod) you want to query:
- In Grafana, go to Administration → Service accounts.
- Create a service account with the Viewer role (read-only is enough).
- Add a token to the service account and copy it — you won't see it again.
Run the command palette (Cmd+Shift+P / Ctrl+Shift+P):
Grafana Insights: Add/Configure Instance
This walks you through each field (name, URL, datasource UIDs, label keys)
via input boxes and writes the result to your settings automatically — no
manual JSON editing needed. Run it again to add another instance or edit an
existing one.
Alternatively, edit settings.json directly (workspace or user):
"grafanaIdeInsights.instances": [
{
"name": "test",
"url": "https://grafana.test.example.com",
"prometheusDatasourceUid": "prometheus",
"lokiDatasourceUid": "loki",
"metricsAppLabelKey": "application",
"logsAppLabelKey": "service_name"
},
{
"name": "prod",
"url": "https://grafana.prod.example.com",
"prometheusDatasourceUid": "prometheus",
"lokiDatasourceUid": "loki",
"metricsAppLabelKey": "application",
"logsAppLabelKey": "service_name"
}
],
"grafanaIdeInsights.activeInstance": "test"
prometheusDatasourceUid / lokiDatasourceUid can be the datasource name
too (e.g. "Prometheus") — the extension resolves it to a UID automatically
via Grafana's datasource API and caches the result.
metricsAppLabelKey / logsAppLabelKey are the label names used to filter by
application/service — Prometheus and Loki often use different label
conventions in the same org (e.g. application for Prometheus scrape targets
vs. service_name for Loki/promtail), so these are configurable per
datasource. Defaults are "application" and "service_name" respectively if
omitted. defaultAppLabel is only used as a fallback pre-filled value if
fetching real label values from Grafana fails (see below).
3. Store your API token
Run the command palette (Cmd+Shift+P / Ctrl+Shift+P):
Grafana Insights: Set API Token for Instance
Pick the instance and paste the token. It's stored securely, never written to
disk in plaintext.
4. Pick the active instance
Grafana Insights: Select Active Instance
Usage
| Command |
What it does |
Grafana Insights: Add/Configure Instance |
Interactive wizard to add or edit a Grafana instance in settings, no manual JSON editing needed |
Grafana Insights: Select Active Instance |
Choose which configured instance (test/prod/...) subsequent commands use |
Grafana Insights: Set API Token for Instance |
Securely store a service account token for an instance |
Grafana Insights: Show Metrics |
Prompts for an app label + PromQL query, renders a line chart in a webview |
Grafana Insights: Show Logs |
Prompts for an app label + LogQL query, tails matching lines into an Output channel |
Grafana Insights: Stop Log Tail |
Stops the currently running log tail |
Grafana Insights: Open Drilldown in Browser |
Opens the equivalent grafana-metricsdrilldown-app URL in your default browser |
Grafana Insights: Browse Dashboards |
Search Grafana dashboards by title, pick one, opens it in your default browser |
Grafana Insights: Show Active Alerts |
Fetches currently active/firing alerts from Grafana's Alertmanager into an Output channel |
Show Metrics, Show Logs, and Open in Grafana all first prompt you to pick an application/service:
the extension queries Grafana's label-values API (Prometheus's
/api/v1/label/:name/values, Loki's /loki/api/v1/label/:name/values) for
the configured metricsAppLabelKey/logsAppLabelKey and shows the real
values in a QuickPick, so you don't have to guess or hardcode names. If that
fetch fails (e.g. permissions), it falls back to a manual text input
pre-filled with defaultAppLabel. A "Custom…" option is always available to
type a value manually even when real values were found. Open in Grafana uses
the same picker (against Prometheus, since it opens the metrics drilldown
app) and now requires a stored API token as a result.
Show Metrics then walks you through building a PromQL query instead of
requiring you to write one from scratch:
- It fetches real metric names for the selected app/service via
Prometheus's
/api/v1/series and shows them in a QuickPick (with
"Custom…" to type a metric name, or "Write full PromQL manually" to skip
the builder entirely).
- You pick a query "style" — Rate (counter), Raw value (gauge), Average, or
p95 latency (histogram) — which wraps the metric in the right PromQL
pattern with your app/service filter already applied.
- The generated query is shown in an editable box before running, so you
can tweak it (add
by (...), change the range, etc.) before it executes.
Both the metrics and logs prompts then default to a PromQL/LogQL template
with $app as a placeholder (and the correct label key already baked in),
which gets substituted with the application/service value you picked.
Show Metrics, Show Logs, and Open in Grafana all prompt for a time range via
a QuickPick (15m / 1h / 6h / 24h / a custom relative duration like
45m, 2h, 3d). For Show Metrics this is the query's start/end window; for
Show Logs it's how far back the tail starts (it then keeps polling forward
from there); for Open in Grafana it's the drilldown URL's from expression.
Browse Dashboards prompts for a search string (leave empty to list all
dashboards, up to 50), fetched via Grafana's own /api/search, then opens
the selected one in your default browser.
Show Active Alerts fetches currently firing/pending alerts from Grafana's
built-in Alertmanager (/api/alertmanager/grafana/api/v2/alerts) and prints
them to an "Grafana Alerts" Output channel — alert name, severity (if
labeled), state, start time, and summary/description annotation if present.
Re-run the command to refresh (it's a snapshot, not a live tail). Requires
Grafana's Alerting feature to be enabled on the instance.
Development
npm install
npm run watch # esbuild watch mode (extension host + webview bundle)
Then press F5 in VS Code to launch an Extension Development Host window.
To type-check without emitting:
npm run compile
To package a .vsix for local install / distribution:
npm run package
To run the unit test suite:
npm test
Tests cover the pure-logic pieces (src/timeRangeUtils.ts,
src/queryStyles.ts, src/grafanaApi.ts, src/config.ts) with mocked
fetch/vscode where needed — see src/__tests__/. Command
handlers/UI flow in src/extension.ts and the QuickPick/InputBox pickers
(src/appLabel.ts, src/metricQuery.ts, src/timeRange.ts,
src/setupWizard.ts) are exercised via manual smoke testing in the
Extension Development Host instead, since they're thin wrappers around VS
Code's UI APIs.
Architecture notes
src/extension.ts — command registration & orchestration.
src/config.ts — reads grafanaIdeInsights.* settings; wraps VS Code
SecretStorage for tokens.
src/grafanaApi.ts — talks to Grafana's datasource proxy API
(/api/datasources/proxy/uid/:uid/...) for both Prometheus
(/api/v1/query_range) and Loki (/loki/api/v1/query_range), plus
datasource UID resolution by name, dashboard search (/api/search), and
active alerts (/api/alertmanager/grafana/api/v2/alerts) via Grafana's
own (non-datasource-proxied) API.
src/logsTailer.ts — polls Loki on an interval and streams new lines to a
VS Code OutputChannel.
src/timeRangeUtils.ts — pure duration parsing/formatting logic (no
vscode dependency, unit tested), used by src/timeRange.ts.
src/timeRange.ts — shared time-range QuickPick (presets + custom relative
duration) used by the metrics, logs, and drilldown commands; thin
vscode-dependent wrapper around timeRangeUtils.ts.
src/appLabel.ts — application/service QuickPick backed by Grafana's
label-values API, with manual-entry fallback.
src/queryStyles.ts — pure PromQL-template generation (rate/raw/avg/p95)
(no vscode dependency, unit tested), used by src/metricQuery.ts.
src/metricQuery.ts — interactive PromQL builder: picks a real metric name
via Prometheus's /api/v1/series, then a query style from
queryStyles.ts, with manual-entry fallback at each step.
src/setupWizard.ts — interactive Add/Configure Instance command; reads
and writes grafanaIdeInsights.instances directly instead of requiring
manual settings.json edits.
media/walkthrough/*.md + package.json's contributes.walkthroughs —
a "Get Started" walkthrough page shown via VS Code's Welcome view.
src/metricsPanel.ts + src/webview/main.ts — webview panel rendering
Prometheus range-query results as a Chart.js line chart. The webview script
is bundled separately (browser target) from the extension host code (node
target) via esbuild.js.
Known limitations / follow-ups
- Time ranges are relative-only (presets or a custom "Nm/h/d" duration); there's
no picker for absolute start/end timestamps yet.
- Dashboard browsing opens dashboards in the browser only — no in-IDE
dashboard/panel rendering (would require embedding Grafana's panel
iframes or re-implementing panel visualizations, which is a much bigger
scope). Alert browsing is a read-only snapshot (no silence/ack actions,
no live tailing of alert state changes).
- Only Bearer-token auth is supported (matches Grafana service account
tokens); Basic Auth / API keys could be added if needed.