Console app to fetch AWS CloudWatch Logs entries across multiple log groups matching a CloudWatch Logs filter pattern and print them to stdout.
- Go 1.25+
- AWS credentials with
logs:FilterLogEventspermission on the target log groups - AWS region configured (env
AWS_REGION, profile, or other default sources)
go build ./cmd/aws-multi-log-inspector
aws-multi-log-inspector \
--filter-pattern <pattern> \
[--groups g1,g2] \
[--region ap-northeast-1] \
[--profile your-profile] \
[--start RFC3339] [--end RFC3339] \
[--extract name=jmespath --next-filter jmes-or-literal] [--pretty] \
[--concurrency N]
--groups: Comma-separated CloudWatch Log Group names. Alternatively set envLOG_GROUP_NAMES.--region: AWS region (optional). Falls back to AWS SDK defaults if omitted.--profile: AWS shared config profile (optional). If omitted, the app first uses envAWS_PROFILEwhen present; if that still doesn’t resolve, it falls back to environment credentials (AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY, optionalAWS_SESSION_TOKEN) and region from--regionorAWS_REGION.--filter-pattern: Search pattern (required). See Filter and Pattern Syntax.--start/--end: Override the time window in RFC3339. If both omitted, last 24h is used. If only--startis set, the end isstart+24h. If only--endis set, the start isend-24h.--extract: Extract a value from the first search results using JMESPath:name=path. For non-JSON messages, the raw text is available asmessage.--next-filter: Build a second filter using JMESPath evaluated against{ "value": <extracted> }, or treat the argument as a literal if not valid JMESPath. You can also embed the extracted value via{{name}}, which will be JSON-quoted safely before evaluation.--pretty: Pretty-print JSON. Both the first and second search results are output as an indented JSON array of records.--concurrency: Number of parallel log-group searches (default: 4). Automatically bounded by the number of groups. Increasing this may speed up queries but can increase API pressure.
Output format (first search; one line per log event when not using --pretty):
<RFC3339 timestamp> <log-group>/<log-stream> <message>
If --pretty is set and there are results, the first search results are output as an indented JSON array (same as the second search).
- Implementation uses
FilterLogEventsper group and merges results, then sorts chronologically (ascending by timestamp). - Concurrency: searches are executed in parallel across groups (default workers: 4). On the first error, remaining requests are canceled to reduce wasted work.
- Credentials resolution order when creating the client:
- Shared config/profile (with
--profileorAWS_PROFILE), honoring--regionif provided. - Environment variables:
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY, optionalAWS_SESSION_TOKEN; region via--regionorAWS_REGION. - Otherwise, the AWS SDK’s default resolution chain applies.
- Shared config/profile (with
- The default search window is the last 24 hours; it can be overridden with
--start/--end. - If no matching events are found, the tool prints:
No logs found for the given pattern "<pattern>" in the last 24h.and exits successfully.
Examples:
- Extract a user ID from the first search, then use it for a second search across groups:
--filter-pattern "ERROR" \
--extract "userID=user.id" \
--next-filter "userId={{userID}}"
- Extract a substring from non-JSON messages and build an
@messageequality filter for the second search:
--filter-pattern "WARN" \
--extract "value=message" \
--next-filter "join('', ['@message = \"', {{value}}, '\"'])" \
--pretty
The second search results are output as JSON (use --pretty for indented output). The first search uses the same JSON format when --pretty is enabled.
- Use a shared config profile in a specific region:
AWS_PROFILE=dev aws-multi-log-inspector --region ap-northeast-1 --groups "/aws/lambda/app" --filter-pattern "ERROR"
- Use static environment credentials (access key/secret) with a region:
export AWS_ACCESS_KEY_ID=...
export AWS_SECRET_ACCESS_KEY=...
export AWS_SESSION_TOKEN=... # optional
aws-multi-log-inspector --region ap-northeast-1 --groups "/aws/ecs/service" --filter-pattern "WARN"