Skip to content
From ES JSON to On-Call Alerts in Seconds: RabbitJson's Two-Step Template Approach
Operations 11 min read

From ES JSON to On-Call Alerts in Seconds: RabbitJson's Two-Step Template Approach

This article introduces RabbitJson, a free browser-based tool that converts Elasticsearch query results into human-readable text — such as on-call alert reports, postmortem timelines, and _bulk delete scripts — using a simple two-step model of array path extraction and template rendering, eliminating the need for throwaway jq or Python scripts.

Mingyi World Elasticsearch
Mingyi World Elasticsearch
Mingyi World Elasticsearch

During an order-timeout incident, the author needed to extract three different artifacts from the same Elasticsearch _search response: a one-line-per-event alert for the on-call chat, a numbered timeline for the postmortem, and a list of document IDs for a bulk delete. The raw JSON nests the useful fields under hits.hits[]._source, and the two traditional options — manual copy-paste or writing a throwaway jq /Python script — both impose high cognitive overhead for a one-off task.

Tool Overview: RabbitJson

RabbitJson (rabbitjson.cc) is a deliberately minimal web tool: paste JSON, specify a path expression that resolves to an array, write a template using ${...} placeholders, and get formatted text instantly. No registration, no server-side processing, drafts persist in the browser tab.

Two-Step Model

Locate the array — path syntax supports dot notation ( data.users), bracket indexing ( items[0].tags), root array ( $), and quoted keys for special characters ( data["book.list"]). The UI auto-suggests every path that yields an array.

Write the template — text outside ${...} is emitted literally; each array item produces one line (or a multi-line block). Core variables: ${$item} — current item (primitives used directly) ${$index} — zero-based index; ${$index + 1} for 1-based numbering ${field} — shorthand for

${$item.field}
${expression}

— supports arithmetic, method calls (e.g., toFixed(2)), and

JSON.stringify($item)

Productivity Details

Field autocomplete — typing inside ${ pops up all fields of the current item with type badges and a count of available fields.

Error highlighting — non-existent fields show a red squiggly underline instead of silently outputting undefined.

Real-time / manual modes — real-time renders on every keystroke; manual mode suits large payloads (preview truncated to 200 lines, but copy/download yields full output).

Large JSON handling — switches to plain-text editing automatically; no UI freeze.

Local persistence — pasted JSON and template survive refresh and language changes.

Three Elasticsearch Scenarios

Scenario 1: Query Results → On-Call Alert Report

Path: hits.hits (note the double hits: outer object, inner array). Template:

${$index + 1}. [${_source.level}] ${_source.service} @ ${_source["@timestamp"]}
  ${_source.message} trace=${_source.trace_id} ${_source.duration_ms}ms

Output (5 lines shown):

1. [ERROR] order-service @ 2026-11-04T08:12:33.450Z
   Connection refused: payment-gateway:8080 trace=tr-9f2c1a 30021ms
2. [WARN] inventory-service @ 2026-11-04T08:12:35.118Z
   Stock reservation delayed, retry 2/3 trace=tr-77b1e0 5120ms
3. [ERROR] order-service @ 2026-11-04T08:12:41.002Z
   Payment callback timeout after 30s trace=tr-9f2c1a 30004ms
4. [ERROR] payment-gateway @ 2026-11-04T08:12:44.671Z
   Upstream bank channel HTTP 502 trace=tr-c3d88f 812ms
5. [INFO] order-service @ 2026-11-04T08:12:45.900Z
   Order ORD-1042 marked as failed, compensation queued trace=tr-9f2c1a 12ms

Two notable points: the template uses newlines so each log renders as a header + detail block, and special-character fields like @timestamp are accessed via ${_source["@timestamp"]}. The formatted output immediately reveals that three errors share trace_id=tr-9f2c1a, indicating a cascade rooted in the payment-gateway's 502 — a pattern hard to spot in raw JSON.

Scenario 2: Same Data → _bulk Delete Script

Test traffic polluted the index; need to delete the exact documents by _id. The _bulk delete action requires one metadata line per document, which matches the tool's one-line-per-item output. Template:

{"delete":{"_index":"${_index}","_id":"${_id}"}}

Output (5 lines):

{"delete":{"_index":"logs-order-2026.11.04","_id":"aXk2mQ8BpQ"}}
{"delete":{"_index":"logs-order-2026.11.04","_id":"bYk2mQ8BpQ"}}
{"delete":{"_index":"logs-order-2026.11.04","_id":"cZk2mQ8BpQ"}}
{"delete":{"_index":"logs-order-2026.11.04","_id":"dak2mQ8BpQ"}}
{"delete":{"_index":"logs-order-2026.11.04","_id":"eak2mQ8BpQ"}}

Paste into POST /_bulk (ensure trailing newline), test on a staging index first.

Scenario 3: Extract IDs for terms Query

To trace the same orders in another index, template ${_id}, yields a comma-separated list ready for "terms": { "_id": [ ... ] }. Similarly, ${_source.order_id} produces a column of business IDs for SQL joins.

The tool ships a built-in "Elasticsearch Query Result to Text" example (top dropdown) pre-loaded with the hits.hits path and a starter template — ideal for first-time users to adapt.

Summary: Not a jq Replacement, But Often the Faster Reach

Strengths: compresses "array + fixed format" repetitive work to seconds — alert reports, checklists, SQL/DSL fragments, Markdown lists, message templates. Best for tasks too small to justify a script.

Limitations: no filtering, grouping, aggregation, nested restructuring, or multi-array joins — push those into the ES query or jq. RabbitJson sits strictly between data retrieval and final paste: "locate the array, define the line format, done."

Free, no sign-up, pure browser. Next time you reach for an editor to write jq, try RabbitJson first — odds are you won't need the script.

Tool: rabbitjson.cc | Syntax cheatsheet: rabbitjson.cc/help (path expressions + template expressions with full examples)
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Elasticsearchalertinglog analysistemplate renderingdeveloper-toolsbulk APIJSON processingRabbitJson
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.