AWS CloudTrail OTEL Dashboard¶
YAML dashboard for the AWS CloudTrail OpenTelemetry integration.
Overview¶
This dashboard provides visualization of AWS CloudTrail activity logs to identify patterns in API calls, monitor account activity, detect unauthorized behavior, track resource changes, and troubleshoot operational issues.
Based on the dashboard from the Elastic integrations repository.
Dashboards¶
| Dashboard | File | Description |
|---|---|---|
| CloudTrail Logs Overview | cloudtrail-logs-overview.yaml |
CloudTrail activity logs overview |
Dashboard Definitions¶
CloudTrail Logs Overview (cloudtrail-logs-overview.yaml)
---
dashboards:
- name: '[AWS CloudTrail OTEL] CloudTrail Logs Overview'
description: ''
filters:
- field: data_stream.dataset
equals: aws.cloudtrail.otel
panels:
- size: {w: 24, h: 15}
markdown:
content: |
## AWS CloudTrail Logs Overview
Use this dashboard to visualize CloudTrail Logs.
You could use this data to:
- **Visualize CloudTrail activity logs** to quickly identify patterns in API calls and user actions.
- **Monitor account activity** across AWS services for auditing and compliance purposes.
- **Detect unusual or unauthorized behavior** by filtering and analyzing access patterns.
- **Track resource changes** to understand who made modifications and when.
- **Troubleshoot operational issues** by correlating CloudTrail events with other system metrics.
- **Generate reports and insights** for security reviews or compliance audits
- title: Event outcome over time
size: {w: 24, h: 15}
esql:
type: area
query: |
FROM logs*
| EVAL outcome = CASE(aws.error.code IS NOT NULL, "Fail", "Success")
| KEEP outcome, @timestamp
| STATS total = COUNT() BY outcome, time_bucket = BUCKET(@timestamp, 50, ?_tstart, ?_tend)
dimension:
field: time_bucket
label: Time
data_type: date
metrics:
- field: total
format:
type: number
decimals: 0
breakdown:
field: outcome
appearance:
y_left_axis:
title: Events
- title: Logs by service and action
size: {w: 24, h: 15}
esql:
type: pie
query: |
FROM logs*
| WHERE rpc.service IS NOT NULL
| STATS total = COUNT() BY rpc.service, rpc.method
| KEEP total, rpc.service, rpc.method
| SORT total DESC
metrics:
- field: total
format:
type: number
decimals: 0
breakdowns:
- field: rpc.service
label: Service
- field: rpc.method
label: Method
appearance:
donut: large
values:
format: percent
- title: Logs by user agent
size: {w: 24, h: 15}
esql:
type: pie
query: |
FROM logs*
| WHERE user_agent.original IS NOT NULL
| EVAL agent = REPLACE(user_agent.original, "^\\[|\\/.*$|\\ -\\ .*$", "") // Remove leading square bracket, and everything that is after first slash or hyphen (with spaces) including it
| STATS total = COUNT() by agent
| KEEP total, agent
| SORT total DESC
metrics:
- field: total
format:
type: number
decimals: 0
breakdowns:
- field: agent
label: User Agent
appearance:
donut: large
values:
format: percent
- title: Logs by event type
size: {w: 24, h: 15}
esql:
type: pie
query: |
FROM logs*
| KEEP rpc.system
| STATS total = COUNT() by rpc.system
| SORT total DESC
metrics:
- field: total
format:
type: number
decimals: 0
breakdowns:
- field: rpc.system
label: Event Type
appearance:
donut: large
values:
format: percent
- title: Failed operations by error code
size: {w: 24, h: 15}
esql:
type: pie
query: |
FROM logs*
| WHERE aws.error.code IS NOT NULL
| KEEP aws.error.code
| STATS total = COUNT() BY aws.error.code
| SORT total DESC
metrics:
- field: total
format:
type: number
decimals: 0
breakdowns:
- field: aws.error.code
label: Error Code
appearance:
donut: large
values:
format: percent
- title: Recent Events
size: {w: 31, h: 15}
esql:
type: datatable
query: |
FROM logs*
breakdowns:
- id: timestamp
field: '@timestamp'
label: Timestamp
- id: access-key
field: aws.access_key.id
label: Access Key ID
- id: service
field: rpc.service
label: Service
- id: event-type
field: rpc.system
label: Event Type
- id: action
field: rpc.method
label: Action
- id: error-code
field: aws.error.code
label: Error Code
- id: source
field: source.address
label: Source Address
paging:
enabled: true
page_size: 10
- title: Top User IDs
size: {w: 17, h: 15}
esql:
type: datatable
query: |
FROM logs*
| KEEP aws.access_key.id
| STATS total = COUNT() by aws.access_key.id
| SORT total DESC
breakdowns:
- id: user-id
field: aws.access_key.id
label: Access Key ID
metrics:
- id: events
field: total
format:
type: number
decimals: 0
sorting:
column_id: events
direction: desc
paging:
enabled: true
page_size: 10
Prerequisites¶
- AWS CloudTrail: With data streaming via OpenTelemetry
- OpenTelemetry Collector: Configured for CloudTrail logs
- Kibana: Version 8.x or later
Data Requirements¶
- Data stream dataset:
aws.cloudtrail.otel - Data view:
logs-*
Field Reference¶
Core Fields¶
| Field | Description |
|---|---|
@timestamp |
Event timestamp |
data_stream.dataset |
Should equal aws.cloudtrail.otel |
AWS CloudTrail Fields¶
| Field | Description |
|---|---|
aws.access_key.id |
AWS access key ID used for the API call |
aws.error.code |
Error code if the operation failed |
rpc.service |
AWS service name (e.g., s3, ec2) |
rpc.system |
Event type/system |
rpc.method |
AWS API method/action called |
source.address |
Source IP address of the request |
user_agent.original |
User agent string of the client |