Skip to content

Redesign the migration report to be outcome-first, plain-language, and vendor-aware (CLI + report-migration-coverage skill) #190

Description

@miguel-sanchez-elastic

Problem

The current MIGRATION REPORT is written from the engine's point of view, not the user's. It exposes internal vocabulary that users can't interpret — "Verification gate: Green/Yellow/Red", "Compiled", "risk=376", "not feasible", "skipped" — and folds the engine's internal pipeline stages into the summary. Users (often evaluating the tool, not engineers working on it) can't answer the basic questions: Did my assets make it? What's left for me to do? Can I trust it? The same problem exists in the report-migration-coverage skill, which surfaces the same terms.

Goal

Rework the report so it reads as an outcome story, framed around assets (dashboards and alerting rules):

what you asked to migrate (assets) → a one-line verdict → what we did → per-asset breakdown → the worklist of what's left for you → a plain-language bottom line.

Use two pipeline words only — Converted and Uploaded — and plain status buckets. Apply the same vocabulary across all three surfaces, for both source vendors.

Scope (three surfaces, one vocabulary)

  • Terminal reportprint_report() in observability_migration/core/reporting/report.py
  • Markdown artifactrender_markdown() in observability_migration/core/reporting/summary_md.py (migration_summary.md)
  • Skill.claude/skills/report-migration-coverage/SKILL.md and .cursor/skills/report-migration-coverage/SKILL.md (edit both in lockstep)

Vocabulary mapping (human-facing only; JSON keys unchanged)

Internal / old New human-facing
migrated / Datadog ok Ready (ready to use; for alerts: Imported (disabled))
migrated_with_warnings / Datadog warning Review (converted, worth a glance)
not_feasible + requires_manual / Datadog blocked Rebuild (you finish it in Kibana)
skipped (rows) dropped from panel counts (rows aren't panels)
"Compiled" / "migrated" (stage) Converted
upload step Uploaded
"Verification gate: G/Y/R" "Verified against your data: X of Y matched" — only when --validate ran
"risk=376 (G:8 Y:2 R:37)" "76 panels need your attention"

Report structure

  1. Header<SOURCE_VENDOR> -> KIBANA MIGRATION, with the source vendor named dynamically (Grafana / Datadog). From: (source URL or folder, by mode, tagged with the vendor) and To: (output folder; Kibana URL only when upload ran).

  2. YOU ASKED TO MIGRATE — requested scope, by asset type; shows dashboards and/or alerting rules only for the asset types the user requested.

  3. SUMMARY — a single one-line verdict, placed directly after the requested scope (the lead): e.g. SUMMARY: 6 of 6 dashboards in Kibana · 125 panels ready · 76 need your attention (see below). This is the short form of the BOTTOM LINE, which repeats the fuller version at the end (lead and close).

  4. RESULTS — per requested asset type. When more than one asset type was requested, each appears under its own plain indented sub-header (no glyph); with a single asset type the figures sit directly under RESULTS:

    • Dashboards — Converted count, Uploaded count (hidden if upload not run), and panels (widgets for Datadog) converted, with the Ready / Review / Rebuild breakdown.
    • Alerting rules — Converted count, Uploaded count, and rules migrated, with the Imported (disabled) / Review / Rebuild breakdown.

    The status breakdown is shown only when there's a split (Review or Rebuild > 0) — an all-Ready result shows just the X of Y (100%) line. Verified against your data appears only with --validate.

  5. PER-ASSET breakdown — a table per requested asset type. Converted first, sorted alphabetically, Uploaded column hidden when upload not run. The asset-type grouping titles appear only when more than one asset type was requested (heading PER-ASSET, with plain indented Dashboards / Alerting rules sub-headers, no glyph). With a single asset type, use a concrete heading and no sub-header — PER DASHBOARD or PER ALERTING RULE:

    • Dashboards — per-dashboard table: Converted | Uploaded | Panels | Ready | Review | Rebuild. The total column is named for the unit (Panels, or Widgets for Datadog dashboards) — there is no separate group header above the table.
    • Alerting rules — per-rule table: Converted | Uploaded | Status. Status is Imported (disabled) / Review / Rebuild. A successfully migrated rule is created disabled and must be reviewed before enabling — so it is shown as Imported (disabled), never "Ready".
  6. REQUIRES YOUR ATTENTION — fully-failed assets first, full list shown (never truncated). Plain indented asset-type sub-headers (Dashboards / Alerting rules) appear only when more than one asset type was requested; with a single asset type they're omitted and the items follow directly:

    • Dashboards — per dashboard, the affected panels grouped by cause.
    • Alerting rules — per rule, the reason it needs rebuilding.

    Within each asset, items are grouped by cause — two families with distinct calls to action:

    • Needs redesign in Kibana — a genuine translation gap (Grafana dropdown grouping, unsupported function, unsupported datasource); rebuild it by hand.
    • Waiting on data — the query is fine, the metric just isn't in Elastic yet; it should work once that metric is ingested (likely cause, not a guarantee).

    Leads with the action (each item is already a placeholder note in the dashboard/rule), not raw PromQL.

  7. BOTTOM LINE — the fuller version of the top SUMMARY: a short, readable, plain-language conclusion (two or three sentences) a non-engineer can act on — how many assets are now in Kibana, how many units are ready, and what (if anything) needs the user next. It restates the outcome in words, not a recap of the table. When the report is split by asset type, give one labelled line per asset type (Dashboards: / Alerting rules:).

  8. WHERE TO DIG DEEPER — paths to migration_report.json, migration_summary.md, feature_gap_report.json, and the converted *.yaml.

Detailed requirements / decisions

  • Presentation-only. Do not rename JSON keys or change exit codes; consumers (CI, rollout, verification packets, the skill) depend on them. The skill maps existing keys to the new vocabulary.
  • Asset-oriented. Dashboards and alerting rules are peers throughout; alerts are never dropped from the framing.
  • Vendor-aware. Source vendor (Grafana / Datadog) is named dynamically in the header and labels; works for both, including Datadog "widgets" wording and blocked status. Target is always Kibana/Elastic.
  • Lead and close. A one-line SUMMARY: verdict sits directly after the requested scope; the fuller BOTTOM LINE repeats it at the end. The headline answer is near the top, not only at the bottom.
  • Wording for the worklist count. The catch-all phrase is "need your attention" (matching the section title), never "need you" — some of those panels need a rebuild, others are just waiting on data, so "need your attention" is the accurate umbrella.
  • Alerts are honest about state. A migrated alert rule is created disabled; the report shows it as Imported (disabled) and states it must be reviewed before enabling. It is never labelled "Ready".
  • Data gaps are a likely cause, not a promise. Panels whose metric isn't in Elastic are described as "should work once that metric is ingested", not "works once ingested". (See "Not feasible" count is inflated by missing target data — it measures the wrong thing #187 — the data-not-ingested condition should not inflate the genuinely-blocked count; the worklist's redesign-vs-data-gap split must stay consistent with how "Not feasible" count is inflated by missing target data — it measures the wrong thing #187 resolves the classification.)
  • Markers: Converted = / Partial / ; Uploaded = / . Terminal symbols are kept for interactive output; a non-TTY/piped fallback uses ASCII words (yes / partial / no). No emoji on any surface.
  • Total column folded in: no separate Panels / Widgets banner above the table; the total column header is the unit name itself.
  • Partial = ≥1 rebuild unit but ≥1 converted. = 0 converted or compile failed. No separate upload-failure block — detail lives in JSON.
  • Conditional sections / titles: asset-type blocks appear only for what was requested. Asset-type grouping titles appear only when more than one asset type was requested; a single-asset run uses a concrete heading with no sub-headers. Uploaded line/column hidden entirely when upload was not run (don't narrate the absence).
  • Sub-header per asset on split: whenever the report splits by asset type (more than one type requested), each asset block — in RESULTS, PER-ASSET, REQUIRES YOUR ATTENTION, and BOTTOM LINE — is introduced with a plain indented Title-case sub-header (Dashboards / Alerting rules), no bullet glyph (most robust across terminals and pipes). Single-asset runs have no split.
  • No redundant breakdown: the per-status breakdown is shown only when there's a split; when everything converted cleanly the X of Y (100%) line stands alone.
  • No truncation: the "requires your attention" worklist lists every affected panel/rule in full. The JSON remains the machine-readable copy, but the human report does not abbreviate the list.
  • Progress always visible: default run shows explanatory plain-language narration, one line per phase stating the outcome (e.g. "Converting dashboards to Kibana format ... 6 of 6 converted; 76 panels need your attention."), not a progress bar. --verbose shows the full [1/7]…[7/7] staged detail. Remove the (run with --validate …) advertisement from the report body.
  • Single view-model: terminal report, .md artifact, and skill derive from one computed report view so they cannot drift.
  • Review-bucket vs Verified-line stay distinct: Review = converted with a translation-time warning (semantic loss); Verified against your data = a separate --validate outcome. Never conflated or double-counted.

Formatting conventions

These keep the three surfaces consistent and robust across terminals and pipes:

  • Indentation, not glyphs, carries hierarchy. Three levels, 2 spaces each:
    • Level 0 — section header (RESULTS, PER-ASSET, REQUIRES YOUR ATTENTION): ALL-CAPS, blank line above.
    • Level 1 — asset sub-group (only when split): a plain Title-case label (Dashboards, Alerting rules), indented 2 spaces, no bullet glyph.
    • Level 2+ — data and tables, indented a further 2 spaces.
  • Spaces only, never tab characters. Tabs render at different widths per terminal and break column alignment; pad every table cell to a fixed width with spaces.
  • Status markers: TTY uses / Partial / (Converted) and / (Uploaded); non-TTY/piped output uses ASCII words (yes / partial / no). No emoji anywhere.
  • Width target: keep the report body within 80 columns where possible. The per-dashboard table is the pinch point — truncate long dashboard names with an ellipsis () to preserve column alignment rather than letting rows wrap.

Acceptance criteria

  • Understandable without internals knowledge. A first-time user who knows nothing about the tool's internals can read the report and correctly answer "did my assets make it into Kibana?", "what can I use right now?", and "what do I need to do next?" — without consulting the docs, the JSON artifacts, or asking an engineer. Reviewers hold the wording to this bar.
  • No surface shows "compiled", "verification gate", "risk=N", "not feasible", or "skipped" to the user.
  • No emoji anywhere; output is readable in both a terminal and a piped/CI log.
  • The worklist count uses "need your attention", never "need you".
  • A one-line SUMMARY verdict appears directly after the requested scope, and a fuller BOTTOM LINE at the end.
  • Uploaded alert rules are shown as Imported (disabled), not "Ready"; the report states they must be reviewed before enabling.
  • Data-not-ingested gaps are phrased as a likely cause ("should work once that metric is ingested"), not a guarantee.
  • Dashboards and alerting rules are treated as peer assets; an alerts-only run produces a complete report with no dashboards section, and vice versa.
  • Asset-type grouping titles appear only when more than one asset type was requested; single-asset runs use a concrete heading with no sub-headers.
  • Every asset-type split renders each asset block under a plain indented sub-header (no glyph).
  • Hierarchy is conveyed by indentation and section headers, not bullet glyphs; alignment uses spaces, never tab characters.
  • The report body stays within 80 columns where possible; long names truncate with an ellipsis rather than wrapping.
  • An all-Ready conversion shows just the X of Y (100%) line, with no redundant per-status breakdown.
  • The per-dashboard table has no separate Panels/Widgets banner; the total column header is the unit name.
  • Convert-only run shows no Uploaded line/column.
  • Verified against your data appears only with --validate; absent otherwise (no flag advertisement).
  • The "requires your attention" worklist is never truncated.
  • Default run shows explanatory per-phase narration; --verbose shows the staged detail.
  • Terminal report, migration_summary.md, and skill output use identical vocabulary and numbers on the same run.
  • Header and labels name the source vendor dynamically; works for both Grafana and Datadog.
  • JSON artifacts and exit codes unchanged; existing consumers pass.

Out of scope


Examples

Each example leads with the obs-migrate migrate command (and flags) that produced it.

A. Best case — Grafana, dashboards only, all clean, uploaded, validated

obs-migrate migrate --source grafana --grafana-url https://grafana.acme.com --kibana-url https://acme.kb.elastic.cloud --es-url https://acme.es.elastic.cloud --upload --validate

======================================================================
GRAFANA -> KIBANA MIGRATION
======================================================================
  From:  https://grafana.acme.com  (Grafana)
  To:    ./migration_output/dashboards/   +   https://acme.kb.elastic.cloud

YOU ASKED TO MIGRATE
  From Grafana (https://grafana.acme.com):
    3 dashboards  (48 panels)

SUMMARY: 3 of 3 dashboards in Kibana · all 48 panels ready · nothing needs your attention

RESULTS
  Converted to Kibana format:   3 of 3
  Uploaded to your cluster:     3 of 3
  Panels converted:            48 of 48 across those 3 dashboards  (100%)
  Verified against your data:  48 of 48 panels returned matching results

PER DASHBOARD
  Dashboard                Converted Uploaded  Panels Ready Review Rebuild
  -----------------------------------------------------------------------
  API Gateway Overview     ✓         ✓             18    18     0      0
  Node Exporter Full       ✓         ✓             22    22     0      0
  Postgres Health          ✓         ✓              8     8     0      0

BOTTOM LINE
  All 3 dashboards are in Kibana and every panel is ready to use. Nothing needs
  your attention.

WHERE TO DIG DEEPER
  Full per-panel detail:   migration_output/dashboards/migration_report.json
  Shareable summary:       migration_output/dashboards/migration_summary.md
  Converted files:         migration_output/dashboards/*.yaml

(All-Ready: no per-status breakdown. Single asset type: PER DASHBOARD, no PER-ASSET/Dashboards wrapper, no Dashboards header in RESULTS, no bullets.)

B. Realistic mixed run — Grafana, dashboards only, uploaded, validation skipped (full worklist, not truncated)

obs-migrate migrate --source grafana --grafana-url https://grafana.acme.com --kibana-url https://acme.kb.elastic.cloud --upload

======================================================================
GRAFANA -> KIBANA MIGRATION
======================================================================
  From:  https://grafana.acme.com  (Grafana)
  To:    ./migration_output/dashboards/   +   https://acme.kb.elastic.cloud

YOU ASKED TO MIGRATE
  From Grafana (https://grafana.acme.com):
    6 dashboards  (204 panels)

SUMMARY: 6 of 6 dashboards in Kibana · 125 panels ready · 76 need your attention (see below)

RESULTS
  Converted to Kibana format:   6 of 6
  Uploaded to your cluster:     6 of 6
  Panels converted:           128 of 204 across those 6 dashboards  (63%)
    125  ready to use
      3  converted - worth a quick review
     76  need your attention   -> see below

PER DASHBOARD
  Dashboard                              Converted  Uploaded  Panels Ready Review Rebuild
  --------------------------------------------------------------------------------------
  ArgoCD                                 Partial      ✓           41    35     0      6
  DrillPlan backing services key metrics Partial      ✓           40    34     1      5
  Elasticsearch Exporter Quickstart and  Partial      ✓           55    44     0     11
  MongoDB ReplSet                        Partial      ✓           17     3     0     14
  RabbitMQ-Overview                      Partial      ✓           40     1     2     37
  Redis Clusters via redis_exporter 3.0  Partial      ✓           11     8     0      3

REQUIRES YOUR ATTENTION (76 panels)
Each panel below is already a placeholder note in your uploaded Kibana
dashboard - open the dashboard and finish it there. The full list is shown
(not truncated).

  ArgoCD  (6 panels)
    Needs redesign in Kibana - grouping uses a Grafana dropdown ($grouping) we can't resolve
      "Sync Activity", "Sync Failures", "Reconciliation Activity"
    Waiting on data - metric not in your Elastic data yet; should work once it's ingested
      "Reconciliation Performance", "Git Fetch Performance", "Git Ls-Remote Performance"

  DrillPlan backing services key metrics  (5 panels)
    Waiting on data - metric not in your Elastic data yet; should work once it's ingested
      "mongo uptime", "redis uptime", "rabbitMQ uptime",
      "Client-output-buffer-limit", "Command Calls duration"

  Elasticsearch Exporter Quickstart and Dashboard  (11 panels)
    Waiting on data - metric not in your Elastic data yet; should work once it's ingested
      "Cluster health", "Tripped for breakers", "Nodes", "Data nodes",
      "Pending tasks", "Active primary shards", "Active shards",
      "Initializing shards", "Relocating shards", "Unassigned shards",
      "Delayed unassigned shards"

  MongoDB ReplSet  (14 panels)
    Waiting on data - metric not in your Elastic data yet; should work once it's ingested
      "mongo uptime", "replset member state", "oplog window", "members",
      "primary", "secondaries", "replication lag", "ping time", "asserts",
      "page faults", "connections", "cursors open", "network in",
      "network out"

  RabbitMQ-Overview  (37 panels)
    Waiting on data - metric not in your Elastic data yet; should work once it's ingested
      "Queued messages", "Messages ready", "Messages unacked",
      "Publish rate", "Deliver rate", "Ack rate", "Redeliver rate",
      "Connections", "Channels", "Consumers", "Queues", "Exchanges",
      "Memory used", "Disk free", "File descriptors", "Socket descriptors",
      "Erlang processes", "GC rate", "Node up", "Partitions",
      ... (every affected panel listed in full; abbreviated here only for
          the ticket)

  Redis Clusters via redis_exporter 3.0  (3 panels)
    Waiting on data - metric not in your Elastic data yet; should work once it's ingested
      "Memory fragmentation ratio", "Evicted keys", "Keyspace hits/misses"

BOTTOM LINE
  All 6 dashboards are in Kibana; 125 panels are ready to use. 76 panels still
  need your attention - most just need their metric ingested into Elastic, the
  rest need rebuilding in Kibana. Start with "Requires your attention" above.

WHERE TO DIG DEEPER
  Full per-panel detail:   migration_output/dashboards/migration_report.json
  Shareable summary:       migration_output/dashboards/migration_summary.md
  What needs rebuilding:   migration_output/dashboards/feature_gap_report.json
  Converted files:         migration_output/dashboards/*.yaml

C. Dashboards + alerting rules (both requested -> PER-ASSET with bulleted sub-headers)

obs-migrate migrate --source grafana --grafana-url https://grafana.acme.com --kibana-url https://acme.kb.elastic.cloud --assets all --upload

YOU ASKED TO MIGRATE
  From Grafana (https://grafana.acme.com):
    3 dashboards  (40 panels)
    9 alerting rules

SUMMARY: 3 dashboards + 7 of 9 alert rules in Kibana · 2 panels and 2 rules need your attention

RESULTS
  Dashboards
    Converted to Kibana format:   3 of 3
    Uploaded to your cluster:     3 of 3
    Panels converted:            38 of 40 across those 3 dashboards  (95%)
      38  ready to use
       2  need your attention   -> see below

  Alerting rules
    Converted to Kibana rules:    7 of 9
    Uploaded to your cluster:     7 of 9
      7  imported, disabled - review before enabling
      2  need your attention   -> see below

PER-ASSET
  Dashboards
    Dashboard           Converted Uploaded  Panels Ready Review Rebuild
    ------------------------------------------------------------------
    Latency             ✓         ✓              8     8     0      0
    Service Overview    Partial   ✓             20    18     0      2
    Traffic             ✓         ✓             12    12     0      0

  Alerting rules
    Rule                       Converted  Uploaded  Status
    --------------------------------------------------------------------
    5xx error rate             ✓          ✓         Imported (disabled)
    CPU saturation             ✓          ✓         Imported (disabled)
    Cert expiry                ✓          ✓         Imported (disabled)
    Disk will fill in 4h       ✗          -         Rebuild
    High request latency       ✗          -         Rebuild
    Memory pressure            ✓          ✓         Imported (disabled)
    Pod restarts               ✓          ✓         Imported (disabled)
    Queue backlog              ✓          ✓         Imported (disabled)
    Replication lag            ✓          ✓         Imported (disabled)

REQUIRES YOUR ATTENTION (2 panels, 2 rules)

  Dashboards
    Service Overview  (2 panels)
      Waiting on data - metric not in your Elastic data yet; should work once it's ingested
        "Error budget burn", "SLO compliance"

  Alerting rules
    "Disk will fill in 4h"
      Needs redesign in Kibana - uses Grafana predict_linear(), no direct
      equivalent; approximate with a rate threshold.
    "High request latency"
      Needs redesign in Kibana - uses a Grafana classic-condition with multiple
      reducers; rebuild as a single threshold rule.

BOTTOM LINE
  Dashboards: all 3 are in Kibana, 38 panels ready, 2 need your attention.
  Alerting rules: 7 of 9 are in Kibana, imported but disabled - review before
    enabling; 2 need rebuilding.
  Start with "Requires your attention" above.

D. Alerts-only run (single asset type -> no dashboards section, no asset titles, no bullets)

obs-migrate migrate --source grafana --grafana-url https://grafana.acme.com --kibana-url https://acme.kb.elastic.cloud --assets alerts --upload

YOU ASKED TO MIGRATE
  From Grafana (https://grafana.acme.com):
    12 alerting rules

SUMMARY: 10 of 12 alert rules in Kibana (imported, disabled) · 2 need your attention

RESULTS
  Converted to Kibana rules:    10 of 12
  Uploaded to your cluster:     10 of 12
    10  imported, disabled - review before enabling
     2  need your attention   -> see below

PER ALERTING RULE
  Rule                       Converted  Uploaded  Status
  ------------------------------------------------------------------
  ... (10 imported, disabled rules) ...
  Anomaly: login spikes      ✗          -         Rebuild
  Forecast: storage 7d       ✗          -         Rebuild

REQUIRES YOUR ATTENTION (2 rules)
  "Anomaly: login spikes"
    Needs redesign in Kibana - uses an anomaly monitor, no Kibana equivalent;
    rebuild as an anomaly detection job or threshold rule.
  "Forecast: storage 7d"
    Needs redesign in Kibana - uses a forecast function; approximate with a
    rate-based threshold.

BOTTOM LINE
  10 of 12 alerting rules are in Kibana, imported but disabled - review before
  enabling. 2 rules need rebuilding in Kibana. See "Requires your attention" above.

E. Convert-only — dashboards only, upload not run (Uploaded line/column hidden)

obs-migrate migrate --source grafana --grafana-url https://grafana.acme.com --output-dir ./migration_output (no --upload -> convert only)

  To:    ./migration_output/dashboards/

YOU ASKED TO MIGRATE
  From Grafana (https://grafana.acme.com):
    2 dashboards  (30 panels)

SUMMARY: 2 of 2 dashboards converted (not uploaded yet) · 28 panels ready · 2 need your attention

RESULTS
  Converted to Kibana format:   2 of 2
  Panels converted:            28 of 30 across those 2 dashboards  (93%)
    28  ready to use
     2  need your attention   -> see below

PER DASHBOARD
  Dashboard          Converted  Panels Ready Review Rebuild
  --------------------------------------------------------
  Kafka Cluster      Partial        16    15     0      1
  Nginx Ingress      Partial        14    13     0      1

REQUIRES YOUR ATTENTION (2 panels)
These are saved as placeholder notes in the converted files in
./migration_output - they carry into Kibana when you upload.

  Kafka Cluster  (1 panel)
    Needs redesign in Kibana - uses topk() without group labels; pick the breakdown in Kibana
      "Top consumers by lag"

  Nginx Ingress  (1 panel)
    Waiting on data - metric not in your Elastic data yet; should work once it's ingested
      "Upstream response time p99"

BOTTOM LINE
  Both dashboards converted to ./migration_output (not uploaded yet); 28 panels
  ready, 2 need your attention. Upload when you're ready to push them to Kibana.

F. Upload partially failed — dashboards only (just ✗, no end block)

obs-migrate migrate --source grafana --grafana-url https://grafana.acme.com --kibana-url https://acme.kb.elastic.cloud --upload

YOU ASKED TO MIGRATE
  From Grafana (https://grafana.acme.com):
    4 dashboards  (64 panels)

SUMMARY: 3 of 4 dashboards uploaded (1 failed) · 61 panels ready · 3 need your attention

RESULTS
  Converted to Kibana format:   4 of 4
  Uploaded to your cluster:     3 of 4   - 1 failed
  Panels converted:            61 of 64 across those 4 dashboards  (95%)
    61  ready to use
     3  need your attention   -> see below

PER DASHBOARD
  Dashboard            Converted Uploaded  Panels Ready Review Rebuild
  ------------------------------------------------------------------
  Billing Service      ✓         ✓             20    20     0      0
  Checkout Service     Partial   ✓             18    17     0      1
  Inventory Service    Partial   ✗             14    12     0      2
  Shipping Service     ✓         ✓             12    12     0      0

BOTTOM LINE
  All 4 dashboards converted; 3 of 4 uploaded - Inventory Service failed, retry
  with `obs-migrate upload`. 61 panels ready, 3 need your attention.

G. File-mode source, worst case — dashboards only, a fully-failed dashboard listed first

obs-migrate migrate --source grafana --input-mode files --input-dir ./exported-dashboards --kibana-url https://acme.kb.elastic.cloud --upload

======================================================================
GRAFANA -> KIBANA MIGRATION
======================================================================
  From:  ./exported-dashboards/  (Grafana, file mode, 3 files)
  To:    ./migration_output/dashboards/   +   https://acme.kb.elastic.cloud

YOU ASKED TO MIGRATE
  From Grafana (./exported-dashboards/):
    3 dashboards  (29 panels)

SUMMARY: 2 of 3 dashboards in Kibana · 14 panels ready · 15 need your attention (1 dashboard couldn't convert)

RESULTS
  Converted to Kibana format:   2 of 3   - 1 could not be converted
  Uploaded to your cluster:     2 of 3
  Panels converted:            14 of 29 across those 3 dashboards  (48%)
    14  ready to use
    15  need your attention   -> see below

PER DASHBOARD
  Dashboard               Converted Uploaded  Panels Ready Review Rebuild
  ---------------------------------------------------------------------
  Cassandra Overview      Partial   ✓             11     8     0      3
  Legacy Graphite Board   ✗         ✗             12     0     0     12
  Spark Streaming         ✓         ✓              6     6     0      0

REQUIRES YOUR ATTENTION (15 panels)

  Legacy Graphite Board  (could not be converted - 12 panels)
    Needs redesign in Kibana - built on a Graphite datasource we don't support;
    rebuild from scratch in Kibana using your Elastic data. Nothing was uploaded
    for this dashboard.

  Cassandra Overview  (3 panels)
    Waiting on data - metric not in your Elastic data yet; should work once it's ingested
      "Compaction pending", "Read repair rate", "Hinted handoff"

BOTTOM LINE
  2 of 3 dashboards are in Kibana; Legacy Graphite Board could not be converted at
  all and must be rebuilt from scratch. 14 panels ready, 15 need your attention.

H. Datadog source — dashboards only, "widgets" instead of "panels"

obs-migrate migrate --source datadog --kibana-url https://acme.kb.elastic.cloud --upload

======================================================================
DATADOG -> KIBANA MIGRATION
======================================================================
  From:  https://app.datadoghq.com  (Datadog)
  To:    ./migration_output/dashboards/   +   https://acme.kb.elastic.cloud

YOU ASKED TO MIGRATE
  From Datadog (https://app.datadoghq.com):
    4 dashboards  (52 widgets)

SUMMARY: 4 of 4 dashboards in Kibana · 43 widgets ready · 9 need your attention (see below)

RESULTS
  Converted to Kibana format:   4 of 4
  Uploaded to your cluster:     4 of 4
  Widgets converted:           45 of 52 across those 4 dashboards  (87%)
    43  ready to use
     2  converted - worth a quick review
     7  need your attention   -> see below

PER DASHBOARD
  Dashboard           Converted Uploaded  Widgets Ready Review Rebuild
  ------------------------------------------------------------------
  APM Services        Partial   ✓              16    13     2      1
  Host Overview       ✓         ✓              14    14     0      0
  Kubernetes          Partial   ✓              14    10     0      4
  Synthetics          Partial   ✓               8     6     0      2

BOTTOM LINE
  All 4 dashboards are in Kibana; 43 widgets ready to use, 2 worth a quick review,
  7 need rebuilding in Kibana. See "Requires your attention" above.

I. Non-TTY / piped output — ASCII fallback (no symbols, no emoji)

obs-migrate migrate --source grafana --grafana-url https://grafana.acme.com --kibana-url https://acme.kb.elastic.cloud --upload | tee migration.log (piped -> ASCII fallback)

GRAFANA -> KIBANA MIGRATION
  Dashboard                Converted  Uploaded  Panels Ready Review Rebuild
  API Gateway Overview     yes        yes           18    18     0      0
  Checkout Service         partial    yes           18    17     0      1
  Legacy Graphite Board    no         no            12     0     0     12

J. Default (non-verbose) progress — explanatory narration, not a bar

obs-migrate migrate --source grafana --grafana-url https://grafana.acme.com --kibana-url https://acme.kb.elastic.cloud --upload (default; no --verbose)

Connecting to Grafana at https://grafana.acme.com ... found 6 dashboards (204 panels).
Converting dashboards to Kibana format ... 6 of 6 converted; 76 panels need your attention.
Uploading to your Kibana cluster ... 6 of 6 uploaded.
Generating report ...

--verbose swaps these for the full [1/7]…[7/7] staged log.

References

  • observability_migration/core/reporting/report.py · summary_md.py
  • observability_migration/adapters/source/grafana/{cli.py,verification.py,rollout.py}
  • .claude/skills/report-migration-coverage/SKILL.md · .cursor/skills/report-migration-coverage/SKILL.md

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requestprogram:trustVerification, reports, parity, audits

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions