The Core section's CloudWatch page covers a single metric and a single alarm. That is enough to get a signal flowing, but it hides how the pieces actually relate once a real system uses all of them together.
This page builds the full mental model: four pillars, how they connect, and where the more advanced features later in this section - custom metrics, EMF, Logs Insights, composite alarms, anomaly detection, dashboards - each attach.
CloudWatch has four pillars: metrics (numeric time series), logs (text records), alarms (threshold or anomaly watchers on metrics), and events (notifications that something happened, via EventBridge).
Insight: metrics and logs are raw data; alarms and events are how CloudWatch turns that data into action. Everything else in this section is a variation on filling or reading one of the four.
When to Use: whenever you need to understand how a custom metric, a log line, an alarm, and a scheduled reaction fit into one coherent monitoring design instead of four unrelated APIs.
Limitations/Trade-offs: the four pillars are billed separately (metric count, log ingestion/storage, alarm count, event volume), so a design that ignores the boundaries between them can get expensive fast.
Related Topics: custom metrics and EMF, Logs Insights, composite alarms and anomaly detection, dashboards.
Metrics are numeric time series. Each data point has a namespace, a metric name, a set of dimensions, a timestamp, and a value. PutMetricData is the one call that creates and appends to a metric - there is no separate creation step.
Logs are text records grouped into log groups (usually one per application or Lambda function) and log streams (one per running instance of that source). Logs are written with PutLogEvents or, for Lambda, simply by writing to stdout.
Alarms watch a single metric (or a metric-math expression, or an anomaly detection band) and transition between OK, ALARM, and INSUFFICIENT_DATA. An alarm's job is narrow: evaluate one signal on a schedule and fire actions on state change.
Events are how CloudWatch (via Amazon EventBridge, its companion event bus) reacts to something happening once - an EC2 instance changing state, a scheduled cron tick, a custom application event - rather than a number crossing a threshold over time.
# --- Python (boto3) ---import boto3cw = boto3.client("cloudwatch", region_name="us-east-1")logs = boto3.client("logs", region_name="us-east-1")# A metric: numeric, dimensioned, timestamped.cw.put_metric_data( Namespace="MyApp", MetricData=[{"MetricName": "OrdersFailed", "Value": 1, "Unit": "Count"}],)# A log: text, grouped by log group and stream.logs.put_log_events( logGroupName="/myapp/checkout", logStreamName="instance-1", logEvents=[{"timestamp": 0, "message": "order failed: timeout"}],)
// --- TypeScript (AWS SDK v3) ---import { CloudWatchClient, PutMetricDataCommand } from "@aws-sdk/client-cloudwatch";import { CloudWatchLogsClient, PutLogEventsCommand } from "@aws-sdk/client-cloudwatch-logs";const cw = new CloudWatchClient({ region: "us-east-1" });const logs = new CloudWatchLogsClient({ region: "us-east-1" });// A metric: numeric, dimensioned, timestamped.await cw.send(new PutMetricDataCommand({ Namespace: "MyApp", MetricData: [{ MetricName: "OrdersFailed", Value: 1, Unit: "Count" }],}));// A log: text, grouped by log group and stream.await logs.send(new PutLogEventsCommand({ logGroupName: "/myapp/checkout", logStreamName: "instance-1", logEvents: [{ timestamp: Date.now(), message: "order failed: timeout" }],}));
Notice these are two different clients and two different service APIs - cloudwatch for metrics and alarms, logs (CloudWatch Logs) for log groups and streams. They are marketed as one product but implemented as two SDKs.
The four pillars connect through a small number of bridges, and most confusion in CloudWatch comes from not knowing which bridge you are using.
Metric filters turn log text into a metric. You define a filter pattern against a log group, and every matching line increments (or extracts a value into) a metric, without your code calling PutMetricData at all.
EMF (Embedded Metric Format) is the inverse direction done differently: instead of a filter reading logs after the fact, you write a specially-structured JSON log line, and CloudWatch's log ingestion pipeline extracts the metric as it arrives. EMF is not a separate API call - it is a log format, sent via PutLogEvents or plain stdout in Lambda. This is covered in depth on the Custom Metrics & EMF page.
Alarms attach to metrics only - never directly to logs or events. If you want to alarm on log content, you route it through a metric filter or EMF first, then alarm on the resulting metric.
Composite alarms combine multiple existing alarms with boolean logic (ALARM(a) AND ALARM(b)), so they sit one layer above ordinary alarms, not beside metrics.
Anomaly detection replaces a static Threshold with a machine-learned band (ANOMALY_DETECTION_BAND) as what an alarm compares the metric against - same alarm primitive, different comparison.
Events, through EventBridge, are separate from all of the above: they react to a state change happening once (an alarm firing is itself one such event you can route further), not to a continuous numeric signal.
Designing with all four pillars in mind changes how you approach a new signal. The first question is not "how do I alarm on this?" but "is this a number I should publish directly, or text I should log and filter/EMF into a metric?"
High-cardinality data (per-customer, per-request-id counters) gets expensive fast as PutMetricData dimensions, because each unique dimension combination is a billed metric. EMF is usually cheaper here, since you are already paying for log ingestion and the metric extraction rides along. This trade-off is the subject of the EMF page.
Once metrics exist, Logs Insights (covered on its own page) lets you query the raw log text with a purpose-built query language - useful for ad hoc investigation that a pre-declared metric filter cannot answer, since a metric only has the shape you decided to extract in advance.
Dashboards read metrics (and, less commonly, log query results) into a JSON widget layout - "dashboards as code" - which is the visualization layer sitting on top of the metric pillar.
A common architectural mistake is trying to make alarms do the job of events, or vice versa. An alarm is for "is this number bad right now," evaluated on a schedule. An event is for "this specific thing just happened," delivered once. Scheduled housekeeping, resource lifecycle reactions, and cross-service choreography belong on EventBridge, not as an alarm with an artificially tight period.
"EMF is a CloudWatch API call." - No, it is a JSON log format. You write it via PutLogEvents or stdout; CloudWatch's log pipeline extracts the metric, there is no PutEmbeddedMetric operation.
"Metrics and logs use the same client." - No, metrics and alarms live in @aws-sdk/client-cloudwatch / boto3 cloudwatch; logs live in @aws-sdk/client-cloudwatch-logs / boto3 logs.
"An alarm can watch a log group directly." - No, alarms only watch metrics. Logs must go through a metric filter or EMF extraction first.
"Composite alarms and anomaly detection are separate CloudWatch features from ordinary alarms." - No, both are still PutMetricAlarm/PutCompositeAlarm underneath; they change what the alarm compares against or which sub-alarms it aggregates.
"Events and alarms are the same thing." - No, an alarm evaluates a continuous metric on a schedule; an event (EventBridge) reacts to a discrete occurrence, including an alarm's own state transition.
Metrics (numbers over time), logs (text records), alarms (watchers on metrics), and events (notifications of something happening once, via EventBridge).
Is EMF a separate API from PutMetricData?
No. EMF is a structured JSON log format written through normal log ingestion (PutLogEvents or Lambda stdout). CloudWatch extracts the metric from the log line automatically - there is no dedicated EMF API call.
Can an alarm watch a log group?
Not directly. Route log content into a metric first, either with a metric filter or with EMF, then point the alarm at that resulting metric.
Do metrics and logs use the same SDK client?
No. Metrics, alarms, and dashboards use the CloudWatch client (cloudwatch / @aws-sdk/client-cloudwatch). Logs and Logs Insights use the separate CloudWatch Logs client (logs / @aws-sdk/client-cloudwatch-logs).
How do composite alarms fit into this model?
They are still ordinary alarms under the hood, created with PutCompositeAlarm instead of PutMetricAlarm. Instead of comparing a metric to a threshold, they combine other alarms' states with boolean logic.
How does anomaly detection change an alarm?
It swaps a static Threshold for ANOMALY_DETECTION_BAND, an ML-generated dynamic range built by a separate PutAnomalyDetector call. The alarm mechanics - evaluation periods, actions, states - stay the same.
What is the difference between an alarm and an EventBridge rule?
An alarm evaluates one metric on a recurring schedule and reacts to its numeric state. An EventBridge rule reacts to a discrete event - a state change, a schedule tick, a custom event - including consuming an alarm's own state-change event as input.
Stack versions: This page was written for boto3 1.43.x (Python 3.10+) and the AWS SDK for JavaScript v3 (Node.js 18+). NzA2MjAyfDU0MTFvaWdjfG9pLnNlZGl1Z2Vkb2M=
Revisado por Chris St. John·Última atualização: 25 de jul. de 2026