Skip to content

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