← All one-liners·#029·ops·aws·power

SQS: drain a queue to local JSONL

Pop messages off an SQS queue, write each Body to disk for inspection. The first move when something's wedged in a queue.

Setup
  • → brew install awscli
  • → aws configure (or AWS_PROFILE / AWS_ACCESS_KEY_ID env vars)
Cost per run
free
The one-liner
$ Q="https://sqs.eu-west-1.amazonaws.com/123456789012/my-queue"

while MSGS=$(aws sqs receive-message --queue-url "$Q" \
               --max-number-of-messages 10 --wait-time-seconds 5) \
  && echo "$MSGS" | jq -e '.Messages | length > 0' >/dev/null; do
  echo "$MSGS" | jq -c '.Messages[]?.Body | fromjson? // .' >> /tmp/drained.jsonl
  echo "$MSGS" | jq -r '.Messages[]?.ReceiptHandle' \
    | xargs -I {} aws sqs delete-message --queue-url "$Q" --receipt-handle {}
done
wc -l /tmp/drained.jsonl
What each stage does
  1. [01] awsaws sqs receive-message --queue-url "$Q" --max-number-of-messages 10 --wait-time…
    Long-poll for up to 10 messages, waiting up to 5s. Returns {Messages: [{Body, ReceiptHandle, ...}]} or {} when empty.
  2. [02] jqjq -e '.Messages | length > 0'
    Exit-code test: jq -e returns non-zero if the result is null/false/empty — so the while-loop terminates cleanly when the queue's empty.
  3. [03] jqjq -c '.Messages[]?.Body | fromjson? // .'
    For each message: try fromjson (most queue payloads are JSON-encoded strings); fall back to raw text if not. -c keeps each on a single line for JSONL.
  4. [04] awsxargs -I {} aws sqs delete-message --queue-url "$Q" --receipt-handle {}
    Receive-message doesn't auto-delete — you must explicitly delete each message by ReceiptHandle, or it'll reappear after the visibility timeout.
Expected output (sample)
{"order_id":"42","status":"failed","attempts":3}
{"order_id":"43","status":"failed","attempts":2}
... 47 more lines
      49 /tmp/drained.jsonl
Caveats & tips
  • This DESTRUCTIVELY drains the queue — messages are deleted. To peek without deleting, remove the delete-message line.
  • Visibility timeout matters: if your delete is slow, messages reappear. Default is 30s; raise on the queue if you do slow work per message.