# AWS CloudWatch Logs

> Tell reviewers when a pull request changes code behind recent errors in the CloudWatch log groups you map to a repository: the read-only IAM role, mapping and limits.

When a pull request changes files that appear in the stack traces of the last day's errors in the CloudWatch log groups you map to its repository, MergeHarbor gives those errors to the reviewer and notes it in the summary.

## How it works

- In the background, at most once an hour, MergeHarbor reads the error events of the last 24 hours from each mapped log group: events that contain `ERROR`, `Error`, `error`, `Exception`, `Traceback`, `panic` or `FATAL`.
- It groups similar events by their first line, parses their stack traces into file and line frames, and removes secrets and personal data before storing anything.
- A review uses only the groups from its repository's log groups whose frames are in files the pull request changes. Reviews never wait for CloudWatch, and no extra model call is made.

MergeHarbor reads AWS through a role in your account that it assumes for 15 minutes at a time. It never stores long-lived AWS keys.

## What is read and what is never read

- **Read:** error events of the last 24 hours from the log groups you map, and nothing else. Only the first line (redacted) and stack frames of each group are kept, with an event count and the time it was last seen.
- **Never read:** log groups you have not mapped, events that do not look like errors, metrics, alarms, traces, and any other AWS service. The role cannot write or delete anything.

The snapshot is kept until the next refresh and never written to logs.

## Connect

You need the `settings.manage` permission in MergeHarbor and permission to create IAM roles in the AWS account that holds the logs.

1. In the console, open **Integrations** and choose **Connect** on **AWS CloudWatch Logs** (under **Observability & incidents**). The dialog shows the **Trusted principal** and the **External ID** for your organization. Copy both.
2. In AWS, open **IAM → Roles → Create role**, choose **Custom trust policy** and use:

   ```json
   {
     "Version": "2012-10-17",
     "Statement": [
       {
         "Effect": "Allow",
         "Principal": { "AWS": "<trusted principal>" },
         "Action": "sts:AssumeRole",
         "Condition": { "StringEquals": { "sts:ExternalId": "<external id>" } }
       }
     ]
   }
   ```

3. Give the role read-only permissions. Limit the resource to the log groups you will map where you can:

   ```json
   {
     "Version": "2012-10-17",
     "Statement": [
       {
         "Effect": "Allow",
         "Action": ["logs:FilterLogEvents", "logs:DescribeLogGroups"],
         "Resource": "*"
       }
     ]
   }
   ```

4. Back in MergeHarbor, paste the role's ARN (`arn:aws:iam::<account>:role/<name>`) and the region of the log groups, for example `us-east-1`, then choose **Connect**. MergeHarbor assumes the role once to check it.

The external ID is unique to your organization, so no other MergeHarbor organization can use your role. For log groups in several regions, connect once per region.

## Map log groups to repositories

Open **Settings** on the connection and add, for each repository, up to 10 log group names (for example `/aws/lambda/checkout`). Choose **All repositories** to map log groups to every repository the connection is allowed for. Nothing is read until you map at least one log group.

## Limits

- The last 24 hours, one page of results and at most 100 events per log group per refresh.
- At most 20 mapped log groups are read per connection, and up to 10 per repository.
- Only mapped log groups are read.

## Disconnect

Open the integration in **Integrations** and choose **Disconnect**. MergeHarbor deletes the role ARN and the snapshot. Then delete the role in IAM, since MergeHarbor cannot remove it.

## Self-hosted installations

CloudWatch is hidden until `CLOUDWATCH_PRINCIPAL_ARN` is set to the IAM role or user the MergeHarbor API and workers run as. That principal needs `sts:AssumeRole` on `arn:aws:iam::*:role/*` (step by step in `docs/OAUTH_APPS.md`, "AWS CloudWatch Logs").
