# to_amazon_cloudwatch

Sends events to Amazon CloudWatch Logs.

```tql
to_amazon_cloudwatch group:string, stream=string, [method=string,
  payload=string|blob, timestamp=time, batch_timeout=duration, batch_size=int,
  parallel=int, token=secret, endpoint=string, aws_region=string,
  aws_iam=record]
```

## Description

The `to_amazon_cloudwatch` operator writes events to an existing CloudWatch log group and stream. By default, it uses the AWS `PutLogEvents` API. Set `method` to use a CloudWatch Logs HTTP ingestion endpoint instead.

### `group: string`

Name of the CloudWatch log group.

The operator expects the log group to already exist.

### `stream = string`

Name of the CloudWatch log stream.

The operator expects the log stream to already exist.

### `method = string (optional)`

CloudWatch write method.

Defaults to `put`.

Supported values:

* `put`: Use the AWS `PutLogEvents` API. This method uses AWS IAM.
* `hlc`: Use the CloudWatch HTTP Log Collector endpoint.
* `ndjson`: Use the CloudWatch NDJSON endpoint.
* `json`: Use the CloudWatch structured JSON endpoint.

The `otlp` endpoint is not supported by this operator.

### `payload = string|blob (optional)`

Expression that computes the log message for each event.

Defaults to the incoming event serialized as NDJSON.

### `timestamp = time (optional)`

Expression that computes the CloudWatch event timestamp.

Defaults to a `timestamp` field when present. Otherwise, the operator uses the processing time.

### `batch_timeout = duration (optional)`

Maximum time to keep events in a batch before flushing them.

Defaults to `1s`.

### `batch_size = int (optional)`

Maximum number of events per batch.

Defaults to `1000`.

### `parallel = int (optional)`

Maximum number of in-flight write requests.

Defaults to `1`.

CloudWatch no longer requires sequence tokens for `PutLogEvents`, so you can raise this value for higher throughput to the same stream.

### `endpoint = string (optional)`

CloudWatch Logs endpoint override.

Use this option for tests or compatible deployments that need an explicit endpoint. For HTTP ingestion methods, the operator appends the method-specific path to this endpoint.

### `token = secret (optional)`

Bearer token for HTTP ingestion methods.

Do not use `token` with `method="put"`. When omitted for an HTTP ingestion method, the operator signs requests with AWS IAM.

Bearer-token HTTP ingestion requires a CloudWatch log group that is configured for bearer-token authentication. The log group and stream must already exist. The IAM user behind the bearer token needs `logs:CallWithBearerToken` and `logs:PutLogEvents`. AWS currently supports bearer-token authentication for CloudWatch HTTP ingestion only in `us-east-1`, `us-east-2`, `us-west-1`, and `us-west-2`.

### `aws_region = string (optional)`

AWS region for CloudWatch requests.

If omitted, the operator uses the region from `aws_iam` when present. Otherwise, it uses the AWS SDK’s default region resolution.

### `aws_iam = record (optional)`

Configures explicit AWS credentials or IAM role assumption. If not specified, the operator uses the AWS SDK's default credential chain.

```tql
{
  region: string,            // AWS region for API requests.
  access_key_id: string,     // AWS access key ID.
  secret_access_key: string, // AWS secret access key.
  session_token: string,     // session token for temporary credentials.
  assume_role: string,       // ARN of IAM role to assume.
  session_name: string,      // session name for role assumption.
  external_id: string,       // external ID for role assumption.
  web_identity: record,      // OIDC web identity token configuration.
}
```

See [AWS Authentication](https://preview.docs.tenzir.com/375/375/reference/aws-authentication.md) for a description of every field, the default credential chain, web identity configuration, and local authentication with the AWS CLI.

## Batching

The operator sorts each batch by timestamp and enforces CloudWatch limits before sending:

* At most 10,000 events per request.
* At most 1 MiB per request, counted as UTF-8 message bytes plus 26 bytes per event.
* A maximum timestamp span of 24 hours within one request.
* No events more than 2 hours in the future or older than 14 days.

Events that exceed CloudWatch event size or timestamp limits are skipped with a warning.

For HTTP ingestion methods, the operator skips individual events larger than 256 KiB and batches accepted events into one HTTP request until the request reaches the 1 MiB limit.

## Examples

### Write events to a log stream

```tql
from {message: "hello"}
to_amazon_cloudwatch "/tenzir/events",
  stream="default",
  payload=message
```

### Use an event timestamp field

```tql
from {ts: 2026-05-14T00:00:00Z, message: "hello"}
to_amazon_cloudwatch "/tenzir/events",
  stream="default",
  payload=message,
  timestamp=ts
```

### Send through the HTTP Log Collector

```tql
from {message: "hello"}
to_amazon_cloudwatch "/tenzir/events",
  stream="default",
  method="hlc",
  payload=message,
  token=secret("cloudwatch-hlc-token")
```

### Assume an IAM role

```tql
from {message: "hello"}
to_amazon_cloudwatch "/tenzir/events",
  stream="default",
  payload=message,
  aws_iam={
    region: "us-east-1",
    assume_role: "arn:aws:iam::123456789012:role/cloudwatch-writer"
  }
```

## See Also

* [`from_amazon_cloudwatch`](https://preview.docs.tenzir.com/375/375/reference/operators/from_amazon_cloudwatch.md)
* [CloudWatch](https://preview.docs.tenzir.com/375/375/integrations/amazon/cloudwatch.md)