Skip to content

Docker OpenTelemetry Dashboards

Docker container monitoring dashboards using OpenTelemetry Docker Stats Receiver metrics.

Overview

These dashboards provide comprehensive monitoring for Docker containers including CPU, memory, disk I/O, and network metrics.

Note: Based on the Elastic integrations repository dashboards. Licensed under Elastic License 2.0.

Dashboards

Dashboard File Description
Containers Overview 01-containers-overview.yaml Multi-container monitoring with CPU, memory, disk I/O, and network metrics
Container Stats 02-container-stats.yaml Detailed single-container performance analysis and resource utilization

All dashboards include navigation links for easy switching between views.

Dashboard Definitions

Containers Overview (01-containers-overview.yaml)
---
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
# or more contributor license agreements. Licensed under the Elastic License 2.0;
# you may not use this file except in compliance with the Elastic License 2.0.
# See ../../licenses/ELASTIC-LICENSE-2.0.txt for the full license text.
#
# This file is derived from the Elastic integrations repository:
# https://github.com/elastic/integrations/tree/main/packages/docker_otel
#
dashboards:
  - id: docker-otel-overview
    name: '[Metrics Docker] Overview'
    description: >-
      Docker container metrics overview using OpenTelemetry Docker Stats
      receiver (ES|QL version)
    controls:
      - type: options
        label: Container image
        data_view: metrics-*
        field: container.image.name
      - type: options
        label: Container name
        data_view: metrics-*
        field: container.name
      - type: options
        label: Container hostname
        data_view: metrics-*
        field: container.hostname
      - type: options
        label: Container ID
        data_view: metrics-*
        field: container.id
    filters:
      - field: data_stream.dataset
        equals: dockerstatsreceiver.otel
    panels:
      # Navigation Links
      - title: Navigation Links
        size: {w: 48, h: 2}
        links:
          layout: horizontal
          items:
            - label: Overview
              dashboard: docker-otel-overview
            - label: Container Stats
              dashboard: docker-otel-container-stats

      # KPI Metrics Row
      - title: Containers
        hide_title: true
        size: {w: 8, h: 4}
        esql:
          type: metric
          query:
            - FROM metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - WHERE `@timestamp` >= ?_tstart AND `@timestamp` <= ?_tend
            - STATS containers = COUNT_DISTINCT(container.id)
          primary:
            field: containers
            label: Containers
            format:
              type: number
              decimals: 0
      - title: Unique Images
        description: Count of distinct container image names (excluding version tags). Helps identify image diversity and potential standardization
          opportunities.
        hide_title: true
        size: {w: 8, h: 4}
        esql:
          type: metric
          query:
            - FROM metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - WHERE `@timestamp` >= ?_tstart AND `@timestamp` <= ?_tend
            - EVAL image_parts = SPLIT(container.image.name, ":")
            - EVAL image_name = MV_FIRST(image_parts)
            - STATS unique_images = COUNT_DISTINCT(image_name)
          primary:
            field: unique_images
            label: Unique Images
            format:
              type: number
              decimals: 0
      - title: Unpinned Images
        description: Count of distinct images using the 'latest' tag (unpinned). Unpinned images can lead to unpredictable deployments as they
          may pull different versions over time.
        hide_title: true
        size: {w: 8, h: 4}
        esql:
          type: metric
          query:
            - FROM metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - WHERE `@timestamp` >= ?_tstart AND `@timestamp` <= ?_tend
            - EVAL image_parts = SPLIT(container.image.name, ":")
            - EVAL image_version = CASE(MV_FIRST(image_parts) == MV_LAST(image_parts), "latest", MV_LAST(image_parts))
            - WHERE image_version == "latest"
            - STATS unpinned_images = COUNT_DISTINCT(container.image.name)
          primary:
            field: unpinned_images
            label: Unpinned Images
            format:
              type: number
              decimals: 0
      - title: Unique Image Versions
        description: Count of distinct container images including version tags. Higher than Unique Images when multiple versions of the same image
          are deployed.
        hide_title: true
        size: {w: 8, h: 4}
        esql:
          type: metric
          query:
            - FROM metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - WHERE `@timestamp` >= ?_tstart AND `@timestamp` <= ?_tend
            - STATS unique_image_versions = COUNT_DISTINCT(container.image.name)
          primary:
            field: unique_image_versions
            label: Unique Image Versions
            format:
              type: number
              decimals: 0
      - title: Total Memory Used
        description: Aggregate memory consumption across all containers. Useful for capacity planning and identifying overall resource utilization.
        hide_title: true
        size: {w: 8, h: 4}
        esql:
          type: metric
          query:
            - TS metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - WHERE container.memory.usage.total IS NOT NULL
            - STATS total_memory = SUM(container.memory.usage.total)
          primary:
            field: total_memory
            label: Total Memory Used
            format:
              type: bytes
      - title: Containers >90% Memory
        description: Count of containers with average memory utilization above 90%. High memory usage may indicate memory leaks, insufficient
          limits, or need for optimization.
        hide_title: true
        size: {w: 8, h: 4}
        esql:
          type: metric
          query:
            - TS metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - WHERE container.memory.percent IS NOT NULL
            - STATS avg_memory = AVG(container.memory.percent) BY container_id = container.id
            - WHERE avg_memory > 90
            - STATS high_memory_containers = COUNT_DISTINCT(container_id)
          primary:
            field: high_memory_containers
            label: Containers >90% Memory
            format:
              type: number
              decimals: 0
      - title: Containers Over Time
        description: Container count trends over time. Helps identify scaling patterns, deployment frequency, and container lifecycle changes.
        hide_title: true
        size: {w: 48, h: 8}
        esql:
          type: line
          query:
            - TS metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - STATS containers = COUNT_DISTINCT(container.id) BY time_bucket = BUCKET(`@timestamp`, 20, ?_tstart, ?_tend)
            - SORT time_bucket ASC
          dimension:
            field: time_bucket
          metrics:
            - field: containers
              label: Containers
              format:
                type: number
                decimals: 0

      # Inventory Tables
      - title: Containers by Runtime
        description: Distribution of containers by runtime type (e.g., containerd, docker). Helps understand infrastructure diversity.
        size: {w: 16, h: 14}
        esql:
          type: datatable
          query:
            - FROM metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - STATS Containers = COUNT_DISTINCT(container.id) BY Runtime = container.runtime
            - SORT Containers DESC
            - LIMIT 10
          breakdowns:
            - field: Runtime
          metrics:
            - field: Containers
      - title: Containers by Image
        description: Top container images by instance count. Identifies most commonly deployed images and potential standardization opportunities.
        size: {w: 16, h: 14}
        esql:
          type: datatable
          query:
            - FROM metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - EVAL image_parts = SPLIT(container.image.name, ":")
            - EVAL `Image Name` = MV_FIRST(image_parts)
            - EVAL `Image Version` = CASE(MV_FIRST(image_parts) == MV_LAST(image_parts), "latest", MV_LAST(image_parts))
            - STATS Containers = COUNT_DISTINCT(container.id) BY `Image Name`, `Image Version`
            - SORT Containers DESC
            - LIMIT 100
          breakdowns:
            - field: Image Name
            - field: Image Version
          metrics:
            - field: Containers
      - title: Containers by Name
        description: Top container names by instance count. Useful for identifying frequently deployed services and naming patterns.
        size: {w: 16, h: 14}
        esql:
          type: datatable
          query:
            - FROM metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - STATS Containers = COUNT_DISTINCT(container.id) BY Name = container.name
            - SORT Containers DESC
            - LIMIT 100
          breakdowns:
            - field: Name
          metrics:
            - field: Containers

      # Markdown separator
      - title: Top Containers
        hide_title: true
        size: {w: 48, h: 5}
        markdown:
          content: '## Top Containers by Resource Usage'

      # Top Containers by Resource Usage
      - title: Top Containers by CPU Usage
        description: Top 100 containers by average CPU utilization. Helps identify containers consuming the most CPU resources.
        size: {w: 16, h: 20}
        esql:
          type: datatable
          query:
            - TS metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - WHERE container.cpu.utilization IS NOT NULL
            - STATS `CPU Usage` = AVG(container.cpu.utilization) / 100 BY `Container Name` = container.name, `Container ID` = container.id
            - SORT `CPU Usage` DESC
            - LIMIT 100
          breakdowns:
            - field: Container Name
            - field: Container ID
          metrics:
            - field: CPU Usage
              format:
                type: percent
      - title: Top Containers by Memory Usage
        description: Top 100 containers by average memory usage. Helps identify containers consuming the most memory resources.
        size: {w: 16, h: 20}
        esql:
          type: datatable
          query:
            - TS metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - WHERE container.memory.percent IS NOT NULL
            - STATS `Memory Usage` = AVG(container.memory.percent) / 100 BY `Container Name` = container.name, `Container ID` = container.id
            - SORT `Memory Usage` DESC
            - LIMIT 100
          breakdowns:
            - field: Container Name
            - field: Container ID
          metrics:
            - field: Memory Usage
              format:
                type: percent
      - title: Top Containers by Memory (Bytes)
        description: Top 100 containers by total memory consumption in bytes. Shows absolute memory usage regardless of limits.
        size: {w: 16, h: 20}
        esql:
          type: datatable
          query:
            - TS metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - WHERE container.memory.usage.total IS NOT NULL
            - STATS `Memory (Bytes)` = AVG(container.memory.usage.total) BY `Container Name` = container.name, `Container ID` = container.id
            - SORT `Memory (Bytes)` DESC
            - LIMIT 100
          breakdowns:
            - field: Container Name
            - field: Container ID
          metrics:
            - field: Memory (Bytes)
              format:
                type: bytes
Container Stats (02-container-stats.yaml)
---
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
# or more contributor license agreements. Licensed under the Elastic License 2.0;
# you may not use this file except in compliance with the Elastic License 2.0.
# See ../../licenses/ELASTIC-LICENSE-2.0.txt for the full license text.
#
# This file is derived from the Elastic integrations repository:
# https://github.com/elastic/integrations/tree/main/packages/docker_otel
#
# Modified by kb-yaml-to-lens contributors to convert from Kibana JSON format
# to YAML format for use as documentation examples.
#
# ES|QL Version - Uses TS command for time-series optimization
dashboards:
  - id: docker-otel-container-stats
    name: '[Metrics Docker] Container Stats'
    description: >-
      Docker container statistics using OpenTelemetry Docker Stats
      receiver (ES|QL version). Shows resource usage broken down by container with detailed breakdowns by CPU mode, device, and network interface.
    controls:
      - type: options
        label: Container image
        data_view: metrics-*
        field: container.image.name
      - type: options
        label: Container name
        data_view: metrics-*
        field: container.name
      - type: options
        label: Container hostname
        data_view: metrics-*
        field: container.hostname
      - type: options
        label: Container ID
        data_view: metrics-*
        field: container.id
    filters:
      - field: data_stream.dataset
        equals: dockerstatsreceiver.otel
    panels:
      # Navigation Links
      - title: Navigation Links
        description: Navigate between dashboard views.
        size: {w: 48, h: 2}
        links:
          layout: horizontal
          items:
            - label: Overview
              dashboard: docker-otel-overview
            - label: Container Stats
              dashboard: docker-otel-container-stats

      # KPI Metrics Row
      - title: Containers
        description: Number of distinct containers matching the current filters. Use filters at the top to focus on specific containers.
        hide_title: true
        size: {w: 8, h: 4}
        esql:
          type: metric
          query:
            - FROM metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - WHERE `@timestamp` >= ?_tstart AND `@timestamp` <= ?_tend
            - STATS containers = COUNT_DISTINCT(container.id)
          primary:
            field: containers
            label: Containers
            format:
              type: number
              decimals: 0
      - title: Unique Images
        description: Number of distinct container images including version tags. Helps identify image diversity and potential consolidation opportunities.
        hide_title: true
        size: {w: 8, h: 4}
        esql:
          type: metric
          query:
            - FROM metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - WHERE `@timestamp` >= ?_tstart AND `@timestamp` <= ?_tend
            - STATS unique_images = COUNT_DISTINCT(container.image.name)
          primary:
            field: unique_images
            label: Unique Images
            format:
              type: number
              decimals: 0
      - title: Avg CPU Usage
        description: Average CPU utilization across all selected containers. CPU can exceed 100% on multi-core systems.
        hide_title: true
        size: {w: 10, h: 4}
        esql:
          type: metric
          query:
            - TS metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - WHERE container.cpu.utilization IS NOT NULL
            - STATS avg_cpu = AVG(container.cpu.utilization) / 100
          primary:
            field: avg_cpu
            label: Avg CPU Usage
            format:
              type: percent
      - title: Avg Memory Used
        description: Average memory consumption per container. Useful for understanding typical memory footprint of containers.
        hide_title: true
        size: {w: 10, h: 4}
        esql:
          type: metric
          query:
            - TS metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - WHERE container.memory.usage.total IS NOT NULL
            - STATS avg_memory = AVG(container.memory.usage.total)
          primary:
            field: avg_memory
            label: Avg Memory Used
            format:
              type: bytes
      - title: Total Memory Used
        description: Aggregate memory consumption across all selected containers. Useful for capacity planning and resource allocation.
        hide_title: true
        size: {w: 12, h: 4}
        esql:
          type: metric
          query:
            - TS metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - WHERE container.memory.usage.total IS NOT NULL
            - STATS total_memory = SUM(container.memory.usage.total)
          primary:
            field: total_memory
            label: Total Memory Used
            format:
              type: bytes

      # Container info table
      - title: Container info
        description: Current resource usage snapshot per container. Shows CPU utilization, memory consumption, and container metadata. Use filters
          at the top to focus on specific containers.
        size: {w: 48, h: 14}
        esql:
          type: datatable
          query:
            - TS metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - STATS `CPU Usage` = AVG(container.cpu.utilization) / 100, `Memory (Bytes)` = AVG(container.memory.usage.total), `Memory %` = AVG(container.memory.percent)
              / 100 BY `Container Name` = container.name, Image = container.image.name, Runtime = container.runtime, `Container ID` = container.id,
              Hostname = container.hostname
            - KEEP `Container Name`, Image, Runtime, `Container ID`, Hostname, `CPU Usage`, `Memory (Bytes)`, `Memory %`
            - LIMIT 10
          breakdowns:
            - field: Container Name
              label: Container Name
            - field: Image
              label: Image
            - field: Runtime
              label: Runtime
            - field: Container ID
              label: Container ID
            - field: Hostname
              label: Hostname
          metrics:
            - field: CPU Usage
              label: CPU Usage
              format:
                type: percent
            - field: Memory (Bytes)
              label: Memory (Bytes)
              format:
                type: bytes
            - field: Memory %
              label: Memory %
              format:
                type: percent

      # CPU Usage (line chart)
      - title: CPU Usage
        description: CPU utilization over time broken down by container. Shows overall CPU usage trends for each container.
        size: {w: 48, h: 9}
        esql:
          type: line
          query:
            - TS metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - WHERE container.cpu.utilization IS NOT NULL
            - STATS cpu_usage = AVG(container.cpu.utilization) / 100 BY time_bucket = BUCKET(`@timestamp`, 20, ?_tstart, ?_tend), container.id,
              container.name
            - EVAL container_id_short = SUBSTRING(TO_STRING(container.id), 0, 6)
            - EVAL breakdown_label = CONCAT(container.name, " - ", container_id_short)
            - SORT time_bucket ASC
          legend:
            visible: show
            position: right
          dimension:
            field: time_bucket
          metrics:
            - field: cpu_usage
              label: CPU Usage
              format:
                type: percent
          breakdown:
            field: breakdown_label

      # Memory Usage (line chart)
      - title: Memory Usage
        description: Memory consumption in bytes over time broken down by container. Shows absolute memory usage trends for each container.
        size: {w: 48, h: 9}
        esql:
          type: line
          query:
            - TS metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - WHERE container.memory.usage.total IS NOT NULL
            - STATS memory_bytes = AVG(container.memory.usage.total) BY time_bucket = BUCKET(`@timestamp`, 20, ?_tstart, ?_tend), container.id,
              container.name
            - EVAL container_id_short = SUBSTRING(TO_STRING(container.id), 0, 6)
            - EVAL breakdown_label = CONCAT(container.name, " - ", container_id_short)
            - SORT time_bucket ASC
          legend:
            visible: show
            position: right
          dimension:
            field: time_bucket
          metrics:
            - field: memory_bytes
              label: Memory Usage
              format:
                type: bytes
          breakdown:
            field: breakdown_label

      # Disk I/O (line chart by device)
      - title: Disk I/O
        description: Aggregate disk I/O rates (read and write combined) over time broken down by container. Shows total disk activity per container.
        size: {w: 48, h: 9}
        esql:
          type: line
          query:
            - TS metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - WHERE container.blockio.io_service_bytes_recursive IS NOT NULL
            - STATS io_rate = SUM(RATE(container.blockio.io_service_bytes_recursive)) BY time_bucket = BUCKET(`@timestamp`, 20, ?_tstart, ?_tend),
              container.id, container.name
            - EVAL container_id_short = SUBSTRING(TO_STRING(container.id), 0, 6)
            - EVAL breakdown_label = CONCAT(container.name, " - ", container_id_short)
            - SORT time_bucket ASC
          legend:
            visible: show
            position: right
          dimension:
            field: time_bucket
          metrics:
            - field: io_rate
              label: Bytes
              format:
                type: bytes
          breakdown:
            field: breakdown_label

      # Network I/O (line chart with rx and tx)
      - title: Network I/O
        description: Network traffic rates (received and transmitted) over time broken down by container. Shows aggregate network activity per
          container across all interfaces.
        size: {w: 48, h: 9}
        esql:
          type: line
          query:
            - TS metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - WHERE container.network.io.usage.rx_bytes IS NOT NULL OR container.network.io.usage.tx_bytes IS NOT NULL
            - STATS rx_rate = SUM(RATE(container.network.io.usage.rx_bytes)), tx_rate = SUM(RATE(container.network.io.usage.tx_bytes)) BY time_bucket
              = BUCKET(`@timestamp`, 20, ?_tstart, ?_tend), container.id, container.name
            - EVAL container_id_short = SUBSTRING(TO_STRING(container.id), 0, 6)
            - EVAL breakdown_label = CONCAT(container.name, " - ", container_id_short)
            - SORT time_bucket ASC
          legend:
            visible: show
            position: right
          dimension:
            field: time_bucket
          metrics:
            - field: rx_rate
              label: Received Bytes
              format:
                type: bytes
            - field: tx_rate
              label: Transmitted Bytes
              format:
                type: bytes
          breakdown:
            field: breakdown_label

      # "Detailed information" markdown panel
      - size: {w: 48, h: 3}
        markdown:
          content: '## Detailed information'

      # CPU Usage (area stacked chart)
      - title: CPU Usage
        description: CPU usage broken down by execution mode (kernelmode/usermode) and container. Kernel mode represents time spent in system
          calls and kernel operations, while user mode represents time spent executing application code. Labels show mode, container name, and
          first 6 characters of container ID (e.g., "kernelmode - mycontainer - abc123").
        size: {w: 48, h: 9}
        esql:
          type: area
          mode: stacked
          query:
            - TS metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - FORK ( WHERE container.cpu.usage.kernelmode IS NOT NULL | STATS cpu_rate = AVG(RATE(container.cpu.usage.kernelmode)) BY time_bucket
              = BUCKET(`@timestamp`, 20, ?_tstart, ?_tend), container.id, container.name | EVAL cpu_mode = "kernelmode" ) ( WHERE container.cpu.usage.usermode
              IS NOT NULL | STATS cpu_rate = AVG(RATE(container.cpu.usage.usermode)) BY time_bucket = BUCKET(`@timestamp`, 20, ?_tstart, ?_tend),
              container.id, container.name | EVAL cpu_mode = "usermode" )
            - EVAL container_id_short = SUBSTRING(TO_STRING(container.id), 0, 6)
            - EVAL breakdown_label = CONCAT(cpu_mode, " - ", container.name, " - ", container_id_short)
            - STATS cpu_usage = AVG(cpu_rate) / 1000000000 BY time_bucket, breakdown_label
            - SORT time_bucket ASC
          legend:
            visible: show
            position: right
          dimension:
            field: time_bucket
          metrics:
            - field: cpu_usage
              label: CPU %
              format:
                type: percent
          breakdown:
            field: breakdown_label

      # Memory Usage with limit (line chart)
      - title: Memory Usage with limit
        description: Shows actual memory usage alongside the configured memory limit per container. Helps identify containers approaching or exceeding
          their limits.
        size: {w: 24, h: 9}
        esql:
          type: line
          query:
            - TS metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - WHERE container.memory.usage.total IS NOT NULL OR container.memory.usage.limit IS NOT NULL
            - STATS memory_usage = AVG(container.memory.usage.total), memory_limit = MAX(container.memory.usage.limit) BY time_bucket = BUCKET(`@timestamp`,
              20, ?_tstart, ?_tend), container.id, container.name
            - EVAL container_id_short = SUBSTRING(TO_STRING(container.id), 0, 6)
            - EVAL breakdown_label = CONCAT(container.name, " - ", container_id_short)
            - SORT time_bucket ASC
          legend:
            visible: show
            position: right
          dimension:
            field: time_bucket
          metrics:
            - field: memory_usage
              label: Memory Usage
              format:
                type: bytes
            - field: memory_limit
              label: Memory Limit
              format:
                type: bytes
          breakdown:
            field: breakdown_label

      # Memory Usage (line chart percentage)
      - title: Memory Usage
        description: Memory utilization as a percentage of the configured limit over time. Values approaching 100% indicate containers near their
          memory limits.
        size: {w: 24, h: 9}
        esql:
          type: line
          query:
            - TS metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - WHERE container.memory.percent IS NOT NULL
            - STATS memory_pct = AVG(container.memory.percent) / 100 BY time_bucket = BUCKET(`@timestamp`, 20, ?_tstart, ?_tend), container.id,
              container.name
            - EVAL container_id_short = SUBSTRING(TO_STRING(container.id), 0, 6)
            - EVAL breakdown_label = CONCAT(container.name, " - ", container_id_short)
            - SORT time_bucket ASC
          legend:
            visible: show
            position: right
          dimension:
            field: time_bucket
          metrics:
            - field: memory_pct
              label: Memory %
              format:
                type: percent
          breakdown:
            field: breakdown_label

      # Disk I/O (line chart by device) - second visualization
      - title: Disk I/O
        description: Disk I/O broken down by device major number and container. Device major numbers identify the type of block device (e.g.,
          8 for SCSI disks, 259 for NVMe). Labels show device major number, container name, and first 6 characters of container ID (e.g., "8 -
          mycontainer - abc123"). Use this to identify which physical devices each container is accessing.
        size: {w: 48, h: 9}
        esql:
          type: line
          query:
            - TS metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - WHERE container.blockio.io_service_bytes_recursive IS NOT NULL
            - STATS io_rate = SUM(RATE(container.blockio.io_service_bytes_recursive)) BY time_bucket = BUCKET(`@timestamp`, 20, ?_tstart, ?_tend),
              device = attributes.device_major, container.id, container.name
            - EVAL container_id_short = SUBSTRING(TO_STRING(container.id), 0, 6)
            - EVAL breakdown_label = CONCAT(TO_STRING(device), " - ", container.name, " - ", container_id_short)
            - SORT time_bucket ASC
          legend:
            visible: show
            position: right
          dimension:
            field: time_bucket
          metrics:
            - field: io_rate
              label: Bytes
              format:
                type: bytes
          breakdown:
            field: breakdown_label

      # Network - Received Bytes (line chart)
      - title: Network - Received Bytes
        description: Network received bytes broken down by network interface and container. Interface names identify the network interface (e.g.,
          "eth0" for the first Ethernet interface, "docker0" for Docker bridge). Labels show interface name, container name, and first 6 characters
          of container ID (e.g., "eth0 - mycontainer - abc123"). Use this to see which network interfaces each container is receiving traffic
          on.
        size: {w: 24, h: 9}
        esql:
          type: line
          query:
            - TS metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - WHERE container.network.io.usage.rx_bytes IS NOT NULL
            - STATS rx_rate = SUM(RATE(container.network.io.usage.rx_bytes)) BY time_bucket = BUCKET(`@timestamp`, 20, ?_tstart, ?_tend), interface
              = attributes.interface, container.id, container.name
            - EVAL container_id_short = SUBSTRING(TO_STRING(container.id), 0, 6)
            - EVAL breakdown_label = CONCAT(interface, " - ", container.name, " - ", container_id_short)
            - SORT time_bucket ASC
          legend:
            visible: show
            position: right
          dimension:
            field: time_bucket
          metrics:
            - field: rx_rate
              label: Bytes
              format:
                type: bytes
          breakdown:
            field: breakdown_label

      # Network - Transmitted Bytes (line chart)
      - title: Network - Transmitted Bytes
        description: Network transmitted bytes broken down by network interface and container. Interface names identify the network interface
          (e.g., "eth0" for the first Ethernet interface, "docker0" for Docker bridge). Labels show interface name, container name, and first
          6 characters of container ID (e.g., "eth0 - mycontainer - abc123"). Use this to see which network interfaces each container is sending
          traffic through.
        size: {w: 24, h: 9}
        esql:
          type: line
          query:
            - TS metrics-*
            - WHERE data_stream.dataset == "dockerstatsreceiver.otel"
            - WHERE container.network.io.usage.tx_bytes IS NOT NULL
            - STATS tx_rate = SUM(RATE(container.network.io.usage.tx_bytes)) BY time_bucket = BUCKET(`@timestamp`, 20, ?_tstart, ?_tend), interface
              = attributes.interface, container.id, container.name
            - EVAL container_id_short = SUBSTRING(TO_STRING(container.id), 0, 6)
            - EVAL breakdown_label = CONCAT(interface, " - ", container.name, " - ", container_id_short)
            - SORT time_bucket ASC
          legend:
            visible: show
            position: right
          dimension:
            field: time_bucket
          metrics:
            - field: tx_rate
              label: Bytes
              format:
                type: bytes
          breakdown:
            field: breakdown_label

Prerequisites

  • Docker: Docker Engine with containers running
  • OpenTelemetry Collector: Collector Contrib with Docker Stats receiver configured
  • Kibana: Version 8.x or later

Data Requirements

  • Data stream dataset: dockerstatsreceiver.otel
  • Data view: metrics-*

OpenTelemetry Collector Configuration

receivers:
  docker_stats:
    endpoint: unix:///var/run/docker.sock
    collection_interval: 10s

exporters:
  elasticsearch:
    endpoints: ["https://your-elasticsearch-instance:9200"]

service:
  pipelines:
    metrics:
      receivers: [docker_stats]
      exporters: [elasticsearch]

Metrics Reference

Default Metrics

Metric Type Unit Description Attributes
container.blockio.io_service_bytes_recursive Sum By Bytes transferred to/from disk device_major, device_minor, operation
container.cpu.usage.kernelmode Sum ns CPU time in kernel mode
container.cpu.usage.total Sum ns Total CPU time consumed
container.cpu.usage.usermode Sum ns CPU time in user mode
container.cpu.utilization Gauge 1 Percent of CPU used by container
container.memory.file Sum By Filesystem cache memory (cgroups v2)
container.memory.percent Gauge 1 Percentage of memory used
container.memory.total_cache Sum By Memory with block devices
container.memory.usage.limit Sum By Memory limit set for container
container.memory.usage.total Sum By Memory usage excluding cache
container.network.io.usage.rx_bytes Sum By Bytes received interface
container.network.io.usage.rx_dropped Sum {packets} Incoming packets dropped interface
container.network.io.usage.tx_bytes Sum By Bytes transmitted interface
container.network.io.usage.tx_dropped Sum {packets} Outgoing packets dropped interface

Optional Metrics (60+ additional available)

Category Example Metrics
Block I/O io_merged, io_queued, io_service_time, io_serviced, io_time, io_wait_time
CPU limit, logical.count, shares, throttling_data.*, usage.percpu, usage.system
Memory active_anon, active_file, cache, dirty, inactive_anon, inactive_file, pgfault, pgmajfault, rss, writeback
Network rx_errors, rx_packets, tx_errors, tx_packets
Container restarts, uptime, pids.count, pids.limit

Metric Attributes

Attribute Values Description
device_major Device number Major device number
device_minor Device number Minor device number
operation read, write, sync, async, discard, total Block I/O operation
interface Interface name Network interface

Resource Attributes

Attribute Description Default
container.id Container ID Enabled
container.name Container name Enabled
container.hostname Container hostname Enabled
container.image.name Container image name Enabled
container.image.id Container image ID Enabled
container.runtime Container runtime Enabled
container.command_line Container command line Disabled

Metrics Not Used in Dashboards

The following default metrics are available but not currently visualized in the dashboards:

Metric Type Unit Description Attributes
container.cpu.usage.kernelmode Sum ns CPU time in kernel mode
container.cpu.usage.usermode Sum ns CPU time in user mode
container.memory.file Sum By Filesystem cache memory (cgroups v2)
container.memory.total_cache Sum By Memory with block devices
container.network.io.usage.rx_dropped Sum {packets} Incoming packets dropped interface
container.network.io.usage.tx_dropped Sum {packets} Outgoing packets dropped interface

All optional metrics (60+) listed in the "Optional Metrics" section above are also not used in the current dashboards. See the OpenTelemetry Docker Stats Receiver documentation for details on enabling these metrics.