このページには Grafonnet で定義する Grafana 用のパネルのサンプルコードについて書いてあります。
Prometheus Node Exporter 用パネル #
グラフ #
CPU 使用率 #
local cpuUsage =
grafana.graphPanel.new(
title='CPU usage',
format='percent',
fill=7,
max=100,
min=0,
stack=true,
)
.addTarget(
grafana.prometheus.target('sum(rate(node_cpu_seconds_total{mode!="idle"}[$__interval])) by (mode) * 100'),
);
CPU 使用率は、次の項目ごとに取得されます。すべてを合計すると 100% になるため、上記は idle 以外を表示する例です。
- ユーザー (user)
- システム (system)
- 優先度付きプロセス (nice)
- ハードウェア割込み (irq)
- ソフトウェア割込み (softirq)
- IO 待ちプロセス (iowait)
- steal 時間 (steal)
- アイドル時間 (idle)
メモリー容量使用率 #
local memoryUsage =
grafana.graphPanel.new(
title='Memory usage',
format='bytes',
fill=2,
fillGradient=4,
linewidth=3,
min=0,
legend_values=true,
legend_current=true,
)
.addTargets([
grafana.prometheus.target('node_memory_MemTotal_bytes', legendFormat='Available'),
grafana.prometheus.target('node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes', legendFormat='Used'),
]);
ディスク容量使用率 #
local diskUsage =
grafana.graphPanel.new(
title='Disk usage',
format='bytes',
fill=2,
fillGradient=4,
linewidth=3,
min=0,
legend_values=true,
legend_current=true,
)
.addTargets([
grafana.prometheus.target('max(node_filesystem_avail_bytes{fstype=~"ext.?|xfs"} + node_filesystem_size_bytes{fstype=~"ext.?|xfs"} - node_filesystem_free_bytes{fstype=~"ext.?|xfs"})', legendFormat='Available'),
grafana.prometheus.target('max(node_filesystem_size_bytes{fstype=~"ext.?|xfs"} - node_filesystem_free_bytes{fstype=~"ext.?|xfs"})', legendFormat='Used'),
]);
1つのノードに複数のディスクデバイスや、複数のマウントポイントがあることもあります。 この例ではそのうちのディスク容量が最大のもののみを対象としています。 次以降のディスク関連のメトリックスはすべて同様に最大のもののみを対象にしています。
ディスク処理リクエスト発行時間 (await) #
local diskAwait =
grafana.graphPanel.new(
title='Disk await',
format='s',
nullPointMode='null as zero',
legend_values=true,
legend_current=true,
legend_max=true,
legend_min=true,
legend_avg=true,
legend_alignAsTable=true,
labelY1='Read (-) / Write (+)'
)
.addSeriesOverride({"alias": "Read", "transform": "negative-Y"})
.addTargets([
grafana.prometheus.target('max(rate(node_disk_write_time_seconds_total[$__interval]) / rate(node_disk_writes_completed_total[$__interval]))', legendFormat='Write'),
grafana.prometheus.target('max(rate(node_disk_read_time_seconds_total[$__interval]) / rate(node_disk_reads_completed_total[$__interval]))', legendFormat='Read'),
]);
iostat の r_wait と w_await に相当するメトリクスです。 メトリックスの計算方法は こちら の記事参考にしているだけで、確からしさの検証はしておりません。
次以降の iostat に相当するメトリクスも同様上記サイトを参考にしております。
ディスクビジー率 (%util) #
local diskUtil =
grafana.graphPanel.new(
title='Disk Util',
format='percent',
fill=2,
fillGradient=4,
linewidth=1,
min=0,
legend_values=true,
legend_current=true,
legend_max=true,
legend_min=true,
legend_avg=true,
legend_alignAsTable=true,
)
.addTargets([
grafana.prometheus.target('max(rate(node_disk_io_time_seconds_total[$__interval])) * 100', legendFormat='Disk util'),
]);
iostat の %util に相当するメトリクスです。
ディスク IOPS #
local diskIOPS =
grafana.graphPanel.new(
title='Disk I/O per second',
fill=2,
fillGradient=4,
linewidth=1,
min=0,
legend_values=true,
legend_current=true,
legend_max=true,
legend_min=true,
legend_avg=true,
legend_alignAsTable=true,
)
.addTargets([
grafana.prometheus.target('max(rate(node_disk_reads_completed_total[$__interval]) + rate(node_disk_writes_completed_total[$__interval]))', legendFormat='IOPS'),
]);
iostat の tps (transfers per second、I/O per second) に相当するメトリクスです。
ネットワークトラフィック #
local networkTraffic =
grafana.graphPanel.new(
title='Network traffic',
format='bps',
fill=2,
fillGradient=4,
linewidth=1,
nullPointMode='null as zero',
legend_values=true,
legend_current=true,
legend_max=true,
legend_min=true,
legend_avg=true,
legend_alignAsTable=true,
labelY1='Receive (-) / Transmit (+)'
)
.addSeriesOverride({"alias": "Receive", "transform": "negative-Y"})
.addTargets([
grafana.prometheus.target('max(rate(node_network_transmit_bytes_total{device=~"^(eth|en|wlan|ww).*"}[$__interval])*8)', legendFormat='Transmit'),
grafana.prometheus.target('max(rate(node_network_receive_bytes_total{device=~"^(eth|en|wlan|ww).*"}[$__interval])*8)', legendFormat='Receive'),
]);
表示するネットワークインターフェースはインターフェース名が eth/en/wlan/ww で始まるもののうち最大のものとしています。 上記のインターフェース名は一般的に Debian 系の OS で使われる物理インターフェース名です。
テーブル #
ノード状態の一覧表 #
Prometheus に登録されているすべてのインスタンスに対して、これまでに紹介した上記のメトリクスなどの瞬時値を一覧表示したテーブルの例です。
local overviewTable =
grafana.tablePanel.new(
title='Overview',
styles=[
{
alias: 'IP address',
pattern: 'instance',
},
{
alias: 'Hostname',
pattern: 'nodename',
},
{
alias: '# of cores',
pattern: 'Value #B',
},
{
alias: 'Memory',
pattern: 'Value #C',
type: 'number',
unit: 'bytes',
},
{
alias: 'Disk size',
pattern: 'Value #D',
type: 'number',
unit: 'bytes',
},
{
alias: 'Uptime',
pattern: 'Value #E',
type: 'number',
unit: 's',
},
{
alias: 'Load',
pattern: 'Value #F',
},
{
alias: 'CPU usage',
pattern: 'Value #G',
type: 'number',
unit: 'percent',
colorMode: 'cell',
colors: [
"rgba(50, 172, 45, 0.97)",
"rgba(237, 129, 40, 0.89)",
"rgba(245, 54, 54, 0.9)",
],
thresholds: ["50", "80"],
},
{
alias: 'Mem usage',
pattern: 'Value #H',
type: 'number',
unit: 'percent',
colorMode: 'cell',
colors: [
"rgba(50, 172, 45, 0.97)",
"rgba(237, 129, 40, 0.89)",
"rgba(245, 54, 54, 0.9)",
],
thresholds: ["50", "80"],
},
{
alias: 'Disk usage',
pattern: 'Value #I',
type: 'number',
unit: 'percent',
colorMode: 'cell',
colors: [
"rgba(50, 172, 45, 0.97)",
"rgba(237, 129, 40, 0.89)",
"rgba(245, 54, 54, 0.9)",
],
thresholds: ["50", "80"],
},
{
alias: 'Disk read await ',
pattern: 'Value #J',
type: 'number',
unit: 's',
colorMode: 'cell',
colors: [
"rgba(50, 172, 45, 0.97)",
"rgba(237, 129, 40, 0.89)",
"rgba(245, 54, 54, 0.9)",
],
thresholds: ["10", "100"],
},
{
alias: 'Disk write await',
pattern: 'Value #K',
type: 'number',
unit: 's',
colorMode: 'cell',
colors: [
"rgba(50, 172, 45, 0.97)",
"rgba(237, 129, 40, 0.89)",
"rgba(245, 54, 54, 0.9)",
],
thresholds: ["10", "100"],
},
{
alias: 'Disk util',
pattern: 'Value #L',
type: 'number',
unit: 'percent',
colorMode: 'cell',
colors: [
"rgba(50, 172, 45, 0.97)",
"rgba(237, 129, 40, 0.89)",
"rgba(245, 54, 54, 0.9)",
],
thresholds: ["50", "80"],
},
{
alias: 'Rx traffic',
pattern: 'Value #M',
type: 'number',
unit: 'bps',
colorMode: 'cell',
colors: [
"rgba(50, 172, 45, 0.97)",
"rgba(237, 129, 40, 0.89)",
"rgba(245, 54, 54, 0.9)",
],
thresholds: ["10000000", "50000000"],
},
{
alias: 'Tx traffic',
pattern: 'Value #N',
type: 'number',
unit: 'bps',
colorMode: 'cell',
colors: [
"rgba(50, 172, 45, 0.97)",
"rgba(237, 129, 40, 0.89)",
"rgba(245, 54, 54, 0.9)",
],
thresholds: ["10000000", "50000000"],
},
],
)
.addTargets([
grafana.prometheus.target(
// Value #A
expr='node_uname_info',
format='table',
instant=true,
),
grafana.prometheus.target(
// Value #B: Number of CPU cores
expr='count(node_cpu_seconds_total{mode="system"}) by (instance)',
format='table',
instant=true,
),
grafana.prometheus.target(
// Value #C: Memory size
expr='node_memory_MemTotal_bytes - 0',
format='table',
instant=true,
),
grafana.prometheus.target(
// Value #D: Disk size
expr='max(node_filesystem_size_bytes) by (instance)',
format='table',
instant=true,
),
grafana.prometheus.target(
// Value #E: Uptime
expr='sum(time() - node_boot_time_seconds) by (instance)',
format='table',
instant=true,
),
grafana.prometheus.target(
// Value #F: 5-min. Load
expr='node_load5 - 0',
format='table',
instant=true,
),
grafana.prometheus.target(
// Value #G: CPU usage
expr='sum(rate(node_cpu_seconds_total{mode=~"(user|system|nice|irq|softirq)"}[$__interval])) by (instance) * 100 / count(node_cpu_seconds_total{mode="user"}) by (instance)',
format='table',
instant=true,
),
grafana.prometheus.target(
// Value #H: Memory usage
expr='(1 - (node_memory_MemAvailable_bytes / (node_memory_MemTotal_bytes))) * 100',
format='table',
instant=true,
),
grafana.prometheus.target(
// Value #I: Disk usage
expr='max((node_filesystem_size_bytes{fstype=~"ext.?|xfs"} - node_filesystem_free_bytes{fstype=~"ext.?|xfs"}) * 100 / (node_filesystem_avail_bytes{fstype=~"ext.?|xfs"} + (node_filesystem_size_bytes{fstype=~"ext.?|xfs"} - node_filesystem_free_bytes{fstype=~"ext.?|xfs"}))) by (instance)',
format='table',
instant=true,
),
grafana.prometheus.target(
// Value #J: Disk await (read)
expr='max(rate(node_disk_read_time_seconds_total[$__interval]) / rate(node_disk_reads_completed_total[$__interval])) by (instance)',
format='table',
instant=true,
),
grafana.prometheus.target(
// Value #K: Disk await (write)
expr='max(rate(node_disk_write_time_seconds_total[$__interval]) / rate(node_disk_writes_completed_total[$__interval])) by (instance)',
format='table',
instant=true,
),
grafana.prometheus.target(
// Value #L: Disk util
expr='max(rate(node_disk_io_time_seconds_total[$__interval]) * 100) by (instance)',
format='table',
instant=true,
),
grafana.prometheus.target(
// Value #M: Rx traffic (only physical NICs)
expr='max(rate(node_network_receive_bytes_total{device=~"^(eth|en|wlan|ww).*"}[$__interval])*8) by (instance)',
format='table',
instant=true,
),
grafana.prometheus.target(
// Value #N: Tx traffic
expr='max(rate(node_network_transmit_bytes_total{device=~"^(eth|en|wlan|ww).*"}[$__interval])*8) by (instance)',
format='table',
instant=true,
),
])
.hideColumn('Time')
.hideColumn('__name__')
.hideColumn('domainname')
.hideColumn('job')
.hideColumn('machine')
.hideColumn('release')
.hideColumn('sysname')
.hideColumn('version')
.hideColumn('Value #A');
パネルのテンプレートととなる関数を作る #
同じフォーマットのパネルであれば、共通部分を関数として定義しておけば、少ないコードでパネルを定義できます。
たとえば、上で定義した Prometheus 用のメモリー容量使用率とディスク容量使用率のパネルのフォーマットは同じです。 これを共通関数として次のように定義できます。
local usageGraphTemplate(title, format, avail_query, used_query) =
grafana.graphPanel.new(
title='%s' % title,
format='%s' % format,
fill=2,
fillGradient=4,
linewidth=3,
min=0,
legend_values=true,
legend_current=true,
)
.addTargets([
grafana.prometheus.target('%s' % avail_query, legendFormat='Available'),
grafana.prometheus.target('%s' % used_query, legendFormat='Used'),
]);
この関数を用いるとメモリー容量使用率とディスク容量使用率はそれぞれ次のように定義できます。
local memoryUsage = usageGraphTemplate(
'Memoty usage',
'bytes',
'node_memory_MemTotal_bytes{instance="$instance"}',
'node_memory_MemTotal_bytes{instance="$instance"} - node_memory_MemAvailable_bytes{instance="$instance"}');
local diskUsage = usageGraphTemplate(
'Disk usage',
'bytes',
'max(node_filesystem_avail_bytes{fstype=~"ext.?|xfs", instance="$instance"} + node_filesystem_size_bytes{fstype=~"ext.?|xfs", instance="$instance"} - node_filesystem_free_bytes{fstype=~"ext.?|xfs", instance="$instance"})',
'max(node_filesystem_size_bytes{fstype=~"ext.?|xfs", instance="$instance"} - node_filesystem_free_bytes{fstype=~"ext.?|xfs", instance="$instance"})');