通过前面大家知道我有一台安装 PVE 系统的 N00 小主机。今天跟跟大家分享一下我使用 Telegraf 收集主机 CPU、固态硬盘、机械硬盘硬件温度数据,然后把数据存储在 InfluxDB 上,并在 Grafana 实时显示硬件数据的过程。
软件功能作用简介
- Telegraf,数据采集工具,可以采集多种组件运行信息,而不需自己手写脚本定时采集,降低数据获取难度。
- InfluxDB,数据存储工具,时间序列数据库,适合存储设备性能、日志、物联网传感器等带有时间戳的数据。
- Grafana,数据可视化工具,帮助用户将数据源中的数据图形化的展示和实时监控,便于用户直观地理解数据。
打开 PVE 指标数据
将 Proxmox 指标收集重定向到 Telegraf 可以使用的本地 Socket。
# 修改 /etc/pve/status.cfg 文件添加如下内容
# root@pve:~# cat /etc/pve/status.cfg
influxdb: telegraf
port 8089
server localhost
# 启动 pvestatd 服务
systemctl restart pvestatd
# 检查 8089 监听状态
root@pve:~# netstat -lnptu | grep 8089
udp6 0 0 :::8089 :::* 2007/telegraf
Telegraf
安装 Telegraf
官方文档 https://docs.influxdata.com/telegraf/v1/install/
curl -s https://repos.influxdata.com/influxdata-archive_compat.key > influxdata-archive_compat.key
echo '393e8779c89ac8d958f81f942f9ad7fb82a25e133faddaf92e15b16e6ac9ce4c influxdata-archive_compat.key' | sha256sum -c && cat influxdata-archive_compat.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg > /dev/null
echo 'deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main' | sudo tee /etc/apt/sources.list.d/influxdata.list
sudo apt-get update && sudo apt-get install telegraf
配置 Telegraf
# 配置文件
root@pve:~# cat /etc/telegraf/telegraf.conf
# 执行脚本
root@pve:~# cat /etc/telegraf/telegraf_temp.sh
# /etc/telegraf/telegraf.conf
[agent]
interval = "10s"
round_interval = true
metric_batch_size = 1000
metric_buffer_limit = 10000
collection_jitter = "0s"
flush_interval = "10s"
flush_jitter = "0s"
precision = ""
hostname = ""
omit_hostname = false
# Configuration for sending metrics to InfluxDB
[[outputs.influxdb_v2]]
urls = ["http://192.168.0.114:8006"]
token = "MNZJG8NzFPW6IXia9sE4VtUqWi5pMg3C54CVD9QUq5YZbxVRWcYVlZYQ9I-fXFVwjP2KibcW0yW3yPpvqKi7dQ=="
organization = "z" # todo pve
bucket = "mybucket"
[[inputs.socket_listener]]
service_address = "udp://:8089"
[[inputs.smart]]
path_smartctl = "/usr/sbin/smartctl"
path_nvme = "/usr/sbin/nvme"
use_sudo = true
devices = [
"/dev/disk/by-id/ata-WDC_WD40EJRX-89AKWY0_WD-WX62D40A9667 --all",
"/dev/disk/by-id/ata-WDC_WD42EJRX-89BFNY0_WD-WX32DB174JFP --all",
"/dev/nvme0 -d nvme"]
[[inputs.sensors]]
remove_numbers = true
timeout = "5s"
[[inputs.exec]]
commands = ["/etc/telegraf/telegraf_temp.sh"]
timeout = "5s"
data_format = "influx"
[[outputs.file]]
files = ["stdout"]
温度获取
- 使用
sensors -j
获取 CPU 和固态硬盘温度 - 使用
smartctl -A /dev/sda
获取机械硬盘温度 - 使用
curl <url>
访问接口,获取本地天气温度
#!/usr/bin/env bash
# /etc/telegraf/telegraf_temp.sh
sensor_data=$(sensors -j)
# 内核的温度
packageid0=$(echo "$sensor_data" | jq '.["coretemp-isa-0000"]["Package id 0"] | select(type == "object") | .temp1_input')
core0=$(echo "$sensor_data" | jq '.["coretemp-isa-0000"]["Core 0"] | select(type == "object") | .temp2_input')
core1=$(echo "$sensor_data" | jq '.["coretemp-isa-0000"]["Core 1"] | select(type == "object") | .temp3_input')
core2=$(echo "$sensor_data" | jq '.["coretemp-isa-0000"]["Core 2"] | select(type == "object") | .temp4_input')
core3=$(echo "$sensor_data" | jq '.["coretemp-isa-0000"]["Core 3"] | select(type == "object") | .temp5_input')
# CPU 插槽附近/上的温度传感器,该传感器可能不可靠
acpitzacpi0=$(echo "$sensor_data" | jq '.["acpitz-acpi-0"]["temp1"] | select(type == "object") | .temp1_input')
nvmepci0500=$(echo "$sensor_data" | jq '.["nvme-pci-0500"]["Composite"] | select(type == "object") | .temp1_input')
wd40ejrx89akwy0=$(smartctl -A /dev/sda | grep -i "temperature" | awk '{print $10}' | tr -d '\n\r')
wd40ejrx89akwy0=$(printf "%.1f" "$wd40ejrx89akwy0")
wd42ejrx89bfny0=$(smartctl -A /dev/sdb | grep -i "temperature" | awk '{print $10}' | tr -d '\n\r')
wd42ejrx89bfny0=$(printf "%.1f" "$wd42ejrx89bfny0")
sz=$(curl -s http://192.168.0.114:8035/api/weather/sz | jq '.data.qw')
sz=$(printf "%.1f" "$sz")
echo "n100_temp,device=cpu,chip=coretemp-isa-0000-packageid0 temp_input=$packageid0"
echo "n100_temp,device=cpu,chip=coretemp-isa-0000-core0 temp_input=$core0"
echo "n100_temp,device=cpu,chip=coretemp-isa-0000-core1 temp_input=$core1"
echo "n100_temp,device=cpu,chip=coretemp-isa-0000-core2 temp_input=$core2"
echo "n100_temp,device=cpu,chip=coretemp-isa-0000-core3 temp_input=$core3"
#echo "n100_temp,device=cpu,chip=acpitz-acpi-0 temp_input=$acpitzacpi0"
echo "n100_temp,device=cpu,chip=nvme-pci-0500 temp_input=$nvmepci0500"
echo "n100_temp,device=hdd,chip=wd40ejrx-89akwy0-wx62d40a9667 temp_input=$wd40ejrx89akwy0"
echo "n100_temp,device=hdd,chip=wd42ejrx-89bfny0-wx32db174jfp temp_input=$wd42ejrx89bfny0"
echo "n100_temp,device=weather,chip=sz temp_input=$sz"
Grafana
Grafana 的部署可以参考前面的【玩 docker】 监控平台 Prometheus + Grafana 的部署。
在 Grafana 添加 InfluxDB 数据源,Query Language, InfluxDB 2.x 和 1.8+ 版本选择 Flux
然后创建 dashboards。
图表
图标的查询语句如下
from(bucket: "mybucket")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_measurement"] == "n100_temp")
|> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)
|> drop(columns: ["_field", "device", "host"])
|> yield(name: "last")