awscr-cloudwatch
Version, currently main branch1 version
- main branchlatestSep 20, 2026
github.com/philipp-classen/awscr-cloudwatch
Low-level client for AWS CloudWatch metrics and alarms
Installation
# Add this to your shard.yml
dependencies:
awscr-cloudwatch:
github: philipp-classen/awscr-cloudwatch
branch: mainmain is a branch, not a release, so this tracks it rather than pinning a version.
Then run:
shards installshard.yml
- Crystal
>= 1.18.2- License
- MIT
- Author
- Philipp Claßen
Dependencies
Runtime Dependencies
- awscr-signer~> 0.9.0github: taylorfinnell/awscr-signer
Development Dependencies
- ameba*github: crystal-ameba/amebadev
README
awscr-cloudwatch
A low-level Crystal client for AWS CloudWatch:
- Metrics: publish counters and other data points, query statistics
- Alarms: create, inspect and delete metric and composite alarms
Dashboards, anomaly detectors, tags, metric streams and Contributor Insights rules are covered as well, but with less testing and should be considered experimental only.
Installation
-
Add the dependency to your
shard.yml:dependencies: awscr-cloudwatch: github: philipp-classen/awscr-cloudwatch -
Run
shards install
Usage
require "awscr-cloudwatch"
client = Awscr::CloudWatch::Client.new("us-east-1", "key", "secret")
# With temporary credentials: Client.new("us-east-1", "key", "secret", "session_token")
Publishing metrics
metrics = client.metrics
# One counter increment
metrics.put_counter("MyApp", "Requests", dimensions: {"Env" => "prod"})
# Several data points in one request (up to 1000 metrics / 1 MB)
metrics.put_metric_data("MyApp", [
Awscr::CloudWatch::MetricDatum.counter("Requests", 42, {"Env" => "prod"}),
Awscr::CloudWatch::MetricDatum.new("Latency", values: [1.5, 2.5], counts: [20.0, 1.0], unit: "Milliseconds"),
Awscr::CloudWatch::MetricDatum.new("BatchSize", unit: "Count",
statistic_values: Awscr::CloudWatch::StatisticSet.new(sample_count: 4, sum: 10, minimum: 1, maximum: 4)),
])
Calls return nil on success and raise Awscr::CloudWatch::Exception when AWS
rejects the request. Throttling, 5xx responses and connection errors are
retried with exponential backoff (max_attempts: 3 by default).
Querying metrics
stats = metrics.get_metric_statistics("MyApp", "Requests",
start_time: Time.utc - 1.hour, end_time: Time.utc, period: 300,
statistics: ["Sum"], dimensions: {"Env" => "prod"})
stats.datapoints.each { |dp| puts "#{dp.timestamp}: #{dp.sum}" }
data = metrics.get_metric_data([
Awscr::CloudWatch::MetricDataQuery.new("requests",
metric_stat: Awscr::CloudWatch::MetricStat.new(Awscr::CloudWatch::Metric.new("MyApp", "Requests"), 300, "Sum")),
Awscr::CloudWatch::MetricDataQuery.new("per_second", expression: "requests / 300"),
], start_time: Time.utc - 1.hour, end_time: Time.utc)
data.metric_data_results.each { |r| puts "#{r.id}: #{r.values}" }
metrics.list_metrics(namespace: "MyApp").metrics.each { |m| puts m.metric_name }
Alarms
alarms = client.alarms
alarms.put_metric_alarm("MyApp-HighErrorRate",
namespace: "MyApp", metric_name: "Errors", statistic: "Sum", period: 60,
evaluation_periods: 3, threshold: 100, comparison_operator: "GreaterThanThreshold",
alarm_actions: ["arn:aws:sns:us-east-1:123456789012:oncall"])
alarms.describe_alarms(alarm_name_prefix: "MyApp-").metric_alarms.each do |alarm|
puts "#{alarm.alarm_name}: #{alarm.state_value}"
end
alarms.delete_alarms(["MyApp-HighErrorRate"])
MetricClient and AlarmClient can also be used on their own; they take
the same constructor arguments as Client.
Custom endpoint and HTTP clients
# Local mock such as Ministack
client = Awscr::CloudWatch::Client.new("us-east-1", "dummy", "dummy", endpoint: "http://localhost:4566")
# Shorter timeouts (defaults: 15 s to connect, 60 s to read)
factory = Awscr::CloudWatch::DefaultHttpClientFactory.new(connect_timeout: 5.seconds, read_timeout: 10.seconds)
client = Awscr::CloudWatch::Client.new("us-east-1", "key", "secret", client_factory: factory)
# Connection pooling: subclass HttpClientFactory (acquire_client / release)
Development
crystal spec
bin/ameba
Integration specs only run with AWSCR_CLOUDWATCH_INTEGRATION=1. Against a
local mock such as Ministack (which does not fully conform to the AWS API,
so just the basic specs pass: uploads, dashboards, connection reuse):
export AWS_ENDPOINT_URL=http://localhost:4566
export AWSCR_CLOUDWATCH_INTEGRATION=1
crystal spec spec/integration
Against a real account:
AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=...
AWS_REGION=us-east-1
AWSCR_CLOUDWATCH_INTEGRATION=1
AWSCR_CLOUDWATCH_TEST_PREFIX=my-test
crystal spec spec/integration
Be careful: this creates alarms, a dashboard and an anomaly detector under the test prefix, and published metrics cannot be deleted.
Contributing
- Fork it (https://github.com/philipp-classen/awscr-cloudwatch/fork)
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
Contributors
- Philipp Claßen - creator and maintainer
Documentation
Built from the current release. The first visit to a release nobody has asked for starts its build.
Links
This branch
- Branch
main- Seen
- Sep 20, 2026
- Crystal
>= 1.18.2- Indexed
- yes
Dependents
No indexed shard depends on this one yet.
Repository
github.com/philipp-classen/awscr-cloudwatch
Metadata
- Created
- Sep 21, 2026
- Updated
- Sep 26, 2026
- Synced
- Sep 26, 2026
- Versions
- 1