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.