From 90530d81508a0f4c0f20d117635bea367717336c Mon Sep 17 00:00:00 2001 From: Gerardo Greco Date: Fri, 27 Feb 2026 07:11:27 +0100 Subject: [PATCH] Improve Grafana skill --- .claude/skills/grafana-analyzer/SKILL.md | 37 ++++++++++++++----- .../grafana-analyzer/get-local-time.mjs | 17 +++++++++ 2 files changed, 45 insertions(+), 9 deletions(-) create mode 100644 .claude/skills/grafana-analyzer/get-local-time.mjs diff --git a/.claude/skills/grafana-analyzer/SKILL.md b/.claude/skills/grafana-analyzer/SKILL.md index f7966e6..62690f1 100644 --- a/.claude/skills/grafana-analyzer/SKILL.md +++ b/.claude/skills/grafana-analyzer/SKILL.md @@ -5,6 +5,7 @@ allowed-tools: - "mcp:grafana*" - WebSearch - WebFetch + - Bash user-invocable: true --- @@ -12,22 +13,40 @@ user-invocable: true You are a specialized Grafana observability analyst. Your role is to query, interpret, and provide actionable insights from Grafana logs, distributed traces, and metrics via the MCP Grafana server. -## Timezone Configuration +## Step 0 — Detect Current Local Time + +**MANDATORY**: Before any analysis, run the local time detection script: + +```bash +node /Users/gerardogreco/Documents/Lavoro/sharpcoding2026/.claude/skills/grafana-analyzer/get-local-time.mjs +``` -**Default timezone: CET (Central European Time, +01:00)** +This returns a JSON object with `iso`, `date`, `time`, `timezone`, and `utcOffset`. +Use these values to: +- Determine "now" for relative time ranges (e.g. "last 5 minutes", "last hour"). +- Build correct RFC3339 timestamps with the real local UTC offset. +- Show times in the user's actual timezone in responses. + +**Example**: if the script returns `{"iso":"2026-02-27T16:42:10+01:00", ...}` and the user asks "what happened in the last 5 minutes", compute: +- `start = 2026-02-27T16:37:10+01:00` +- `end = 2026-02-27T16:42:10+01:00` + +## Timezone Configuration -- All user-provided times are CET unless stated otherwise. -- Convert to RFC3339 with `+01:00` offset. Example: user says "15:10" → `2025-11-21T15:10:00+01:00` -- **NEVER** subtract hours from user-provided CET times. -- Show all times in CET in responses. +- The user's timezone is detected automatically by the script above. +- All user-provided times use the detected timezone unless stated otherwise. +- Convert to RFC3339 using the detected `utcOffset`. Example: user says "15:10", offset is `+01:00` → `2026-02-27T15:10:00+01:00` +- **NEVER** subtract hours from user-provided times to "convert" them. +- Show all times in the user's local timezone in responses. ## Pre-flight Checks Before any analysis, collect: -1. **Environment** — Ask if not provided (prod, test, local). -2. **Time range** — Exact start/end or relative ("last 30 minutes"). -3. **Service or filter** — Specific service name, error message, or trace ID if available. +1. **Current time** — Run `get-local-time.mjs` (Step 0). +2. **Environment** — Ask if not provided (prod, test, local). +3. **Time range** — Exact start/end or relative ("last 30 minutes"). Use detected time for relative ranges. +4. **Service or filter** — Specific service name, error message, or trace ID if available. ## Analysis Workflow diff --git a/.claude/skills/grafana-analyzer/get-local-time.mjs b/.claude/skills/grafana-analyzer/get-local-time.mjs new file mode 100644 index 0000000..9c18aaa --- /dev/null +++ b/.claude/skills/grafana-analyzer/get-local-time.mjs @@ -0,0 +1,17 @@ +const now = new Date(); +const pad = (n) => String(n).padStart(2, "0"); + +const tzOffset = -now.getTimezoneOffset(); +const sign = tzOffset >= 0 ? "+" : "-"; +const offsetH = pad(Math.floor(Math.abs(tzOffset) / 60)); +const offsetM = pad(Math.abs(tzOffset) % 60); + +const iso = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}T${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}${sign}${offsetH}:${offsetM}`; + +console.log(JSON.stringify({ + iso, + date: `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`, + time: `${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`, + timezone: Intl.DateTimeFormat().resolvedOptions().timeZone, + utcOffset: `${sign}${offsetH}:${offsetM}`, +}));