How to Export CloudWatch Logs as JSON

Three ways to download your CloudWatch log events as JSON files for offline analysis, debugging, or archiving.

TL;DR

The console lets you download log events as JSON directly - no CLI needed. For larger exports, use aws logs filter-log-events --output json which handles pagination automatically. Or skip exporting entirely with the smplogs browser extension, which reads logs straight from the CloudWatch console.

Why export CloudWatch logs?

CloudWatch Logs Insights is useful for ad-hoc queries, but it has limitations. Query results are capped at 10,000 rows, queries time out after 60 minutes, and you pay per GB scanned. For deeper analysis - like identifying cold start patterns, correlating error spikes with latency, or clustering log signatures - exporting to JSON and analyzing locally is faster, cheaper, and more flexible.

Exported JSON files also serve as snapshots you can share with teammates, attach to incident reports, or re-analyze later without re-running queries against live log groups.

Method 1: AWS Console (quickest)

The simplest way to export logs is directly from the CloudWatch console. This works well for small-to-medium log groups (up to a few thousand events).

Open the CloudWatch console, go to Logs > Log groups, and select your log group (e.g., /aws/lambda/my-function). Click into a log stream or use the Log events tab to view events across all streams. Set your time range, then click Actions > Download search results (JSON).

Note: The console download is limited to the events currently loaded in the view. If you need more than a few thousand events, use the CLI method below.

Method 2: AWS CLI (recommended for large exports)

The CLI handles pagination automatically and can export much larger datasets. Use filter-log-events for filtered exports or get-log-events for a single stream.

Export all events from a log group (time range)

# Export Lambda logs from the last 2 hours
aws logs filter-log-events \
  --log-group-name "/aws/lambda/my-function" \
  --start-time $(date -d '2 hours ago' +%s)000 \
  --end-time $(date +%s)000 \
  --output json > my-function-logs.json

Export with a filter pattern

# Export only error events
aws logs filter-log-events \
  --log-group-name "/aws/lambda/my-function" \
  --filter-pattern "ERROR" \
  --start-time $(date -d '24 hours ago' +%s)000 \
  --output json > errors.json

Export a specific log stream

# Export from a single stream
aws logs get-log-events \
  --log-group-name "/aws/lambda/my-function" \
  --log-stream-name "2026/02/27/[$LATEST]abc123" \
  --output json > stream-logs.json

Timestamps: CloudWatch uses millisecond Unix timestamps. The $(date +%s)000 pattern appends three zeros to convert seconds to milliseconds. On macOS, use $(date -v-2H +%s)000 instead of $(date -d '2 hours ago' +%s)000.

Method 3: AWS SDK (programmatic)

For automated pipelines or custom tooling, use the SDK. Here's a Node.js example that handles pagination:

import { CloudWatchLogsClient, FilterLogEventsCommand } from
  "@aws-sdk/client-cloudwatch-logs";
import { writeFileSync } from "fs";

const client = new CloudWatchLogsClient({});
const events = [];
let nextToken;

do {
  const resp = await client.send(new FilterLogEventsCommand({
    logGroupName: "/aws/lambda/my-function",
    startTime: Date.now() - 2 * 60 * 60 * 1000, // 2 hours ago
    endTime: Date.now(),
    nextToken,
  }));
  events.push(...(resp.events || []));
  nextToken = resp.nextToken;
} while (nextToken);

writeFileSync("logs.json", JSON.stringify({ events }, null, 2));

This pattern works the same in Python (boto3), Go, Java, and other SDKs. The key is to keep paginating with nextToken until it returns undefined.

What the exported JSON looks like

The exported file contains an array of log events. Each event has a timestamp, message, and metadata. Here's what Lambda log events look like:

{
  "events": [
    {
      "logStreamName": "2026/02/27/[$LATEST]abc123",
      "timestamp": 1772150400000,
      "message": "INIT_START Runtime Version: nodejs20.x...",
      "ingestionTime": 1772150401000,
      "eventId": "38012345678901234567"
    },
    {
      "logStreamName": "2026/02/27/[$LATEST]abc123",
      "timestamp": 1772150400500,
      "message": "REPORT RequestId: abc-123 Duration: 45.21 ms...",
      "ingestionTime": 1772150401500,
      "eventId": "38012345678901234568"
    }
  ]
}

smplogs accepts this format directly. The WASM engine parses the message field from each event, auto-detects the service type (Lambda, API Gateway, or ECS), and produces findings.

Skip the export: use the browser extension

If you just want to analyze your logs without saving them to a file, the smplogs browser extension adds an analyze button directly to the CloudWatch console. Click it, and the extension reads the visible log events and sends them to the smplogs analysis page - all within your browser.

The extension uses the same WASM engine as the web app. No data is transmitted - analysis happens entirely in your browser.

Got a JSON export? Drag it into smplogs for severity-ranked findings, root cause analysis, and log clusters. Everything runs in your browser.

Try it free

Related guides