为 ONVIF 设备增加经纬度标签以支持 Geomap

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Super User
2026-02-25 05:17:57 -05:00
parent 95a09fd9d8
commit 84d2bcc2cf
4 changed files with 35 additions and 15 deletions

View File

@@ -31,7 +31,7 @@ ONVIF_TEMP=$(mktemp)
PING_TEMP=$(mktemp)
# 处理CSV文件跳过注释行和标题行
tail -n +2 "$CSV_FILE" | grep -v '^#' | while IFS=',' read -r type ip device group network device_type model location username password onvif_port; do
tail -n +2 "$CSV_FILE" | grep -v '^#' | while IFS=',' read -r type ip device group network device_type model location username password onvif_port lat lon; do
# 去除空格
type=$(echo "$type" | xargs)
ip=$(echo "$ip" | xargs)
@@ -49,6 +49,8 @@ tail -n +2 "$CSV_FILE" | grep -v '^#' | while IFS=',' read -r type ip device gro
username=$(echo "$username" | xargs)
password=$(echo "$password" | xargs)
onvif_port=$(echo "$onvif_port" | xargs)
lat=$(echo "$lat" | xargs)
lon=$(echo "$lon" | xargs)
labels="{
\"device_type\": \"$device_type\",
@@ -61,6 +63,16 @@ tail -n +2 "$CSV_FILE" | grep -v '^#' | while IFS=',' read -r type ip device gro
labels="$labels,
\"onvif_port\": \"$onvif_port\""
fi
if [ -n "$lat" ]; then
labels="$labels,
\"lat\": \"$lat\""
fi
if [ -n "$lon" ]; then
labels="$labels,
\"lon\": \"$lon\""
fi
labels="$labels
}"

View File

@@ -1,13 +1,14 @@
# 统一监控目标配置文件
# 格式: type,ip,device,group,network,device_type,model,location,username,password,onvif_port
# 格式: type,ip,device,group,network,device_type,model,location,username,password,onvif_port,lat,lon
# type: onvif 或 ping
# 对于 onvif 类型,需要填写: ip,device_type,model,location,username,password,onvif_port
# 对于 ping 类型,需要填写: ip,device,group,network
type,ip,device,group,network,device_type,model,location,username,password,onvif_port
ping,192.168.2.1,main_router,network,internal,,,,,,
ping,8.8.8.8,google_dns,external,external,,,,,,
# 对于 onvif 类型,需要填写: ip,device_type,model,location,username,password,onvif_port,lat,lon
# - lat / lon 为摄像头地理位置坐标(十进制度数),用于在 Geomap 上打点
# 对于 ping 类型,需要填写: ip,device,group,networklat / lon 可选)
type,ip,device,group,network,device_type,model,location,username,password,onvif_port,lat,lon
ping,192.168.2.1,main_router,network,internal,,,,,,,,
ping,8.8.8.8,google_dns,external,external,,,,,,,,
# ONVIF 设备示例(取消注释并填写实际信息)
# onvif,192.168.1.100,,,front_door,camera,HIKVISION_DS-2CD2342WD-I,front_door,admin,password1,80
# onvif,192.168.1.101,,,back_yard,camera,DAHUA_IPC-HFW1230S,back_yard,admin,password2,80
# onvif,192.168.1.102,,,living_room,camera,UNIVIEW_IPC3120SR,living_room,admin,password3,8080
# onvif,192.168.1.50,,,server_rack,nvr,HIKVISION_DS-7608NI-I2,server_rack,admin,password4,80
# onvif,192.168.1.100,,,front_door,camera,HIKVISION_DS-2CD2342WD-I,front_door,admin,password1,80,22.1234,113.5678
# onvif,192.168.1.101,,,back_yard,camera,DAHUA_IPC-HFW1230S,back_yard,admin,password2,80,22.2234,113.6678
# onvif,192.168.1.102,,,living_room,camera,UNIVIEW_IPC3120SR,living_room,admin,password3,8080,22.3234,113.7678
# onvif,192.168.1.50,,,server_rack,nvr,HIKVISION_DS-7608NI-I2,server_rack,admin,password4,80,22.4234,113.8678
1 # 统一监控目标配置文件
2 # 格式: type,ip,device,group,network,device_type,model,location,username,password,onvif_port # 格式: type,ip,device,group,network,device_type,model,location,username,password,onvif_port,lat,lon
3 # type: onvif 或 ping
4 # 对于 onvif 类型,需要填写: ip,device_type,model,location,username,password,onvif_port # 对于 onvif 类型,需要填写: ip,device_type,model,location,username,password,onvif_port,lat,lon
5 # 对于 ping 类型,需要填写: ip,device,group,network # - lat / lon 为摄像头地理位置坐标(十进制度数),用于在 Geomap 上打点
6 type,ip,device,group,network,device_type,model,location,username,password,onvif_port # 对于 ping 类型,需要填写: ip,device,group,network(lat / lon 可选)
7 ping,192.168.2.1,main_router,network,internal,,,,,, type,ip,device,group,network,device_type,model,location,username,password,onvif_port,lat,lon
8 ping,8.8.8.8,google_dns,external,external,,,,,, ping,192.168.2.1,main_router,network,internal,,,,,,,,
9 ping,8.8.8.8,google_dns,external,external,,,,,,,,
10 # ONVIF 设备示例(取消注释并填写实际信息)
11 # onvif,192.168.1.100,,,front_door,camera,HIKVISION_DS-2CD2342WD-I,front_door,admin,password1,80 # onvif,192.168.1.100,,,front_door,camera,HIKVISION_DS-2CD2342WD-I,front_door,admin,password1,80,22.1234,113.5678
12 # onvif,192.168.1.101,,,back_yard,camera,DAHUA_IPC-HFW1230S,back_yard,admin,password2,80 # onvif,192.168.1.101,,,back_yard,camera,DAHUA_IPC-HFW1230S,back_yard,admin,password2,80,22.2234,113.6678
13 # onvif,192.168.1.102,,,living_room,camera,UNIVIEW_IPC3120SR,living_room,admin,password3,8080 # onvif,192.168.1.102,,,living_room,camera,UNIVIEW_IPC3120SR,living_room,admin,password3,8080,22.3234,113.7678
14 # onvif,192.168.1.50,,,server_rack,nvr,HIKVISION_DS-7608NI-I2,server_rack,admin,password4,80 # onvif,192.168.1.50,,,server_rack,nvr,HIKVISION_DS-7608NI-I2,server_rack,admin,password4,80,22.4234,113.8678

View File

@@ -4,12 +4,15 @@
## 指标
- `onvif_device_up`1=可达0=不可达标签instance, location, model, device_type
- `onvif_probe_duration_seconds`:探测耗时(秒)
- `onvif_device_up`1=可达0=不可达
- 标签:`instance`, `location`, `model`, `device_type`, `lat`, `lon`
- `onvif_probe_duration_seconds`:探测耗时(秒)
- 标签同上
## 配置
-**config/onvif-targets.json** 读取设备列表(与 `targets.csv` 中 onvif 行一致,由 `config/update-configs.sh` 生成)。
- 支持字段:`device_type`, `model`, `location`, `username`, `password`, `onvif_port`, `lat`, `lon`
- 环境变量:`TARGETS_FILE`(默认 `/config/targets.json`)、`EXPORTER_PORT`(默认 9600
## 构建与运行

View File

@@ -37,11 +37,11 @@ func main() {
up := prometheus.NewGaugeVec(prometheus.GaugeOpts{
Name: "onvif_device_up",
Help: "1 if ONVIF device is reachable, 0 otherwise",
}, []string{"instance", "location", "model", "device_type"})
}, []string{"instance", "location", "model", "device_type", "lat", "lon"})
duration := prometheus.NewGaugeVec(prometheus.GaugeOpts{
Name: "onvif_probe_duration_seconds",
Help: "ONVIF probe duration in seconds",
}, []string{"instance", "location", "model", "device_type"})
}, []string{"instance", "location", "model", "device_type", "lat", "lon"})
reg := prometheus.NewRegistry()
reg.MustRegister(up, duration)
@@ -87,6 +87,8 @@ func probe(targetsFile string, up, duration *prometheus.GaugeVec) {
user := strings.TrimSpace(g.Labels["username"])
pass := strings.TrimSpace(g.Labels["password"])
location := strings.TrimSpace(g.Labels["location"])
lat := strings.TrimSpace(g.Labels["lat"])
lon := strings.TrimSpace(g.Labels["lon"])
model := strings.TrimSpace(g.Labels["model"])
deviceType := strings.TrimSpace(g.Labels["device_type"])
instance := ip + ":" + port
@@ -95,6 +97,8 @@ func probe(targetsFile string, up, duration *prometheus.GaugeVec) {
"location": location,
"model": model,
"device_type": deviceType,
"lat": lat,
"lon": lon,
}
start := time.Now()