NAME

Amazon::CloudWatchLogs - CLI tool for interacting with AWS CloudWatch Logs

SYNOPSIS

aws-logs [options] command

DESCRIPTION

Amazon::CloudWatchLogs provides a command-line interface for common AWS CloudWatch Logs operations including listing log groups and streams, retrieving log events, and creating or deleting groups and streams.

The module is implemented as a CLI::Simple modulino and invoked via the aws-logs script.

Commands

create-group

Create a new CloudWatch log group.

aws-logs -g /my/log/group create-group
create-stream

Create a new log stream within a log group. The value supplied with --stream is used as a prefix; a unique suffix is generated and appended to create the actual log stream name.

aws-logs -g /my/log/group -s my-stream create-stream

For example, the resulting stream name will have the form:

my-stream/<unique-id>

The command prints the log group and generated log stream name after successful creation.

delete-group

Delete a log group and all of its log streams.

aws-logs -g /my/log/group delete-group
get-stream

Retrieve log events from all matching streams in a log group. Use --follow to continue polling the streams for new events.

aws-logs -g /aws/lambda/my-function -t '1 hour ago' get-stream
aws-logs -g /aws/lambda/my-function -t 30m --follow get-stream

Streams are discovered in descending LastEventTime order. During each polling pass, one page of events is retrieved from each stream and the events collected during that pass are sorted by timestamp before being displayed.

Because streams are paginated independently, output is not guaranteed to be globally chronological across multiple streams.

The --start-time option sets the starting event time for each stream. See "Start Time Formats".

last-stream

Display the metadata for the most recently active log stream in a log group, optionally filtered by a stream name prefix.

aws-logs -g /aws/lambda/my-function last-stream
aws-logs -g /aws/lambda/my-function -s '2026/05' last-stream

Output is a JSON object containing the stream metadata including logStreamName, firstEventTimestamp, lastEventTimestamp, and lastIngestionTime.

list-groups

List all CloudWatch log groups in the current account and region.

aws-logs list-groups
list-streams

List all log streams for a log group.

aws-logs -g /aws/lambda/my-function list-streams
aws-logs -g /aws/lambda/my-function -L 5 list-streams
help

Display usage information.

prune-streams

Delete log streams whose last event is older than the specified age.

aws-logs -g group-name prune-streams older-than

Example:

aws-logs -g /aws/lambda/my-function prune-streams 7d

The older-than argument is required and accepts a number followed by m, h, or d for minutes, hours, or days (for example, 30m, 12h, or 7d). Streams without a lastEventTimestamp are not deleted.

CloudWatch Logs retention policies expire log events but do not delete the corresponding log stream resources. This command can be used to remove stale stream metadata after those events have expired.

version

Display the program version and copyright information.

aws-logs version

Options

--color, -c

Display output in color by default. Use --no-color to disable. Colors are applied to the log group name (green) and stream name (magenta) in the output prefix.

--debug, -d

Enable verbose debug output including raw API requests and responses. Note that enabling debug mode with large log volumes will significantly impact performance due to Data::Dumper output for every API call.

--discovery-interval

Number of seconds between stream discovery and idle-stream polling passes when --follow is enabled. Default: 1. See "Follow Mode".

--dryrun

Display the log streams that would be deleted by prune-streams without deleting them.

--endpoint-url, -u

Override the CloudWatch Logs endpoint URL. Useful for testing against LocalStack or other compatible endpoints.

--follow, -f

Continuously tail log streams and periodically discover newly created streams. See "Follow Mode" for details.

--group, -g

The CloudWatch log group name. Required for most commands.

--help, -h

Display usage information.

--limit, -L

Maximum number of matching log streams to retrieve. If omitted, all matching streams are retrieved. --limit cannot be used with --follow.

--localstack, -l

Use LocalStack. Shorthand for --endpoint-url http://localhost:4566.

--no-group-name, -G

Exclude the log group name from the output prefix.

--no-stream-name, -S

Exclude the log stream name from the output prefix.

--profile, -p

AWS credentials profile to use. Defaults to $AWS_PROFILE, or default if $AWS_PROFILE is not set.

--region, -r

AWS region. Defaults to $AWS_REGION, falling back to $AWS_DEFAULT_REGION.

--sleep-time

Number of seconds to sleep between polls when no events are found. Default: 1. See "Follow Mode".

--stream, -s

Log stream name or prefix.

For create-stream, this value is used as the prefix for the newly created stream name.

For commands that retrieve or list streams, only streams whose names begin with this value are included.

--start-time, -t

Retrieve events whose timestamp is at or after the specified time. See "Start Time Formats".

--version, -v

Display the program version and copyright information.

Start Time Formats

The --start-time option accepts compact relative formats:

aws-logs -t 30m ...     # 30 minutes ago
aws-logs -t 2h ...      # 2 hours ago
aws-logs -t 7d ...      # 7 days ago

If Date::Manip is installed, a much broader set of natural language formats is supported:

aws-logs -t 'yesterday' ...
aws-logs -t '2 days ago' ...
aws-logs -t 'last Tuesday' ...
aws-logs -t '2026-04-08 10:00' ...

Note: --start-time is also used during stream discovery. Streams whose lastEventTimestamp is older than --start-time are excluded from iteration. Because CloudWatch Logs updates lastEventTimestamp on an eventual consistency basis, very recently active streams may not be discovered immediately.

Follow Mode

When --follow is enabled, get-stream continuously polls matching log streams for new events.

Streams are maintained in three states:

active

Active streams are polled on every pass using the forward pagination token from the previous GetLogEvents call.

idle

When a stream returns no events and its forward token no longer advances, the stream is considered caught up and moved to the idle set. Idle streams are polled once per discovery interval rather than on every pass.

If an idle stream produces new events, it becomes active again.

retired

For Lambda log groups, idle streams are retired from direct polling after remaining inactive for 20 minutes. Retired streams are not polled directly, but stream discovery can reactivate them if CloudWatch reports newer activity.

This keeps active streams responsive while avoiding repeated GetLogEvents calls against streams that are already caught up.

Stream discovery runs independently of event polling. Every --discovery-interval seconds, DescribeLogStreams is called and newly discovered matching streams are added to the active set.

The --start-time option still controls which streams are initially considered relevant. For example:

aws-logs -g /aws/lambda/my-function -t 1h --follow get-stream

will display events from Lambda streams active within the requested one-hour window, then continue following those streams while also discovering newly active streams.

Because Lambda execution environments create distinct log streams and old streams can accumulate quickly, exhausted Lambda streams are eventually retired from direct polling. If a retired stream later becomes active again, periodic discovery can return it to the active set.

PERFORMANCE

JSON Backend

GetLogEvents responses can be large. A single page can contain up to 1 MB of log events or up to 10,000 events. Decoding these responses with JSON::PP (pure Perl) can introduce significant latency compared with an XS-based JSON implementation.

Amazon::CloudWatchLogs selects the fastest available JSON backend automatically:

BEGIN {
  $ENV{PERL_JSON_BACKEND} = 'Cpanel::JSON::XS,JSON::XS,JSON::PP';
  use JSON qw(decode_json);
}

Installing Cpanel::JSON::XS is strongly recommended:

cpanm Cpanel::JSON::XS

Shape Deserialization

get-stream bypasses Amazon::API's normal Botocore shape deserialization for GetLogEvents responses by disabling the decode_always flag.

Normally, Amazon::API walks the Botocore response shape and recursively deserializes each field into Perl hashes, arrays, and scalars. For a response containing thousands of log events, that processing adds overhead with little benefit to get-stream, which only requires the message and timestamp fields.

Instead, get-stream requests the raw JSON response and decodes it directly. Combined with an XS JSON backend, this significantly reduces the overhead of processing large GetLogEvents responses.

Benchmarks

The following timings are representative for a single Lambda log stream with approximately 9,500 events:

Metric aws-logs AWS CLI Per page (GetLogEvents) ~0.42s ~0.40s Total (all pages, all setup) ~3.5s ~2.8s (single stream, no discovery)

DEPENDENCIES

Required

Amazon::API::CloudWatchLogs, CLI::Simple, Data::UUID, Date::Format, JSON, Number::Bytes::Human, Readonly, Text::ASCIITable, Tie::IxHash

Cpanel::JSON::XS or JSON::XS

Dramatically faster JSON decoding for large payloads. Without one of these, JSON::PP is used and performance on large log volumes will be significantly degraded. See "PERFORMANCE".

Date::Manip

Natural language time parsing for --start-time. Without it, only the compact {n}d, {n}h, and {n}m formats are supported.

VERSION

This documentation refers to version 1.0.7

SEE ALSO

Amazon::API::CloudWatchLogs, Amazon::Credentials, Amazon::API, CLI::Simple, Cpanel::JSON::XS

AUTHOR

Rob Lauer - <rlauer@treasurersbriefcase.com>

LICENSE

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.