自动化脚本如何清理未使用监控项

wen 实用脚本 14

本文目录导读:

自动化脚本如何清理未使用监控项

  1. Zabbix 环境清理(使用API)
  2. Prometheus 与 Node Exporter 情况
  3. Nagios / Icinga2 环境
  4. 通用思路:基于历史数据库分析
  5. 建议与注意事项
  6. 推荐执行步骤

清理未使用的监控项(如Zabbix、Prometheus、Nagios等系统中的监控项)通常有两种思路:标记-清理(找出不活跃的并删除)或白名单(只保留指定的),以下是针对不同监控系统的自动化脚本方法。


Zabbix 环境清理(使用API)

Zabbix 提供了强大的API,可以通过 Python 脚本批量删除长时间未收到数据的监控项。

原理: 查询 trendshistory 表中最近N天没有数据的 item,然后调用 item.delete API。

Python 脚本示例:

#!/usr/bin/env python3
import requests
import json
import datetime
# Zabbix 配置
ZABBIX_URL = "http://your-zabbix-server/api_jsonrpc.php"
ZABBIX_USER = "Admin"
ZABBIX_PASSWORD = "zabbix"
DAYS_OLD = 30  # 清理30天内无数据的监控项
# 获取 auth token
def get_auth():
    payload = {
        "jsonrpc": "2.0",
        "method": "user.login",
        "params": {
            "user": ZABBIX_USER,
            "password": ZABBIX_PASSWORD
        },
        "id": 1
    }
    response = requests.post(ZABBIX_URL, json=payload).json()
    return response['result']
# 获取所有监控项及其最新数据时间
def get_stale_items(auth_token, days):
    # 计算截止时间戳(秒)
    time_from = int((datetime.datetime.now() - datetime.timedelta(days=days)).timestamp())
    payload = {
        "jsonrpc": "2.0",
        "method": "item.get",
        "params": {
            "output": ["itemid", "name", "lastclock", "lastvalue", "status"],
            "filter": {"status": 0},  # 只查已启用的监控项
            "sortfield": "lastclock",
            "sortorder": "ASC"
        },
        "id": 2,
        "auth": auth_token
    }
    response = requests.post(ZABBIX_URL, json=payload).json()
    stale_items = []
    for item in response['result']:
        if int(item['lastclock']) < time_from:
            stale_items.append(item)
    return stale_items
# 删除监控项
def delete_items(auth_token, item_ids):
    if not item_ids:
        print("没有需要删除的监控项。")
        return
    payload = {
        "jsonrpc": "2.0",
        "method": "item.delete",
        "params": item_ids,
        "id": 3,
        "auth": auth_token
    }
    response = requests.post(ZABBIX_URL, json=payload).json()
    if 'error' in response:
        print(f"删除失败: {response['error']['data']}")
    else:
        print(f"成功删除 {len(item_ids)} 个监控项")
if __name__ == "__main__":
    token = get_auth()
    stale = get_stale_items(token, DAYS_OLD)
    print(f"找到 {len(stale)} 个超过 {DAYS_OLD} 天无数据的监控项")
    # 列出前10个供检查
    for item in stale[:10]:
        print(f"  - {item['itemid']}: {item['name']} (最后数据: {item['lastclock']})")
    # 确认后删除(生产环境建议先输出到文件再人工审核)
    # delete_items(token, [item['itemid'] for item in stale])

建议: 正式删除前先输出到CSV文件,人工审核后再执行删除。


Prometheus 与 Node Exporter 情况

Prometheus 本身没有“监控项”概念,它通过 up 指标或 scrape_duration_seconds 衡量,清理策略通常是:

  • 清理未使用的指标(Metric):通过 promtool tsdb analyze 分析存储,删除长时间不使用的指标。
  • 清理不活跃的Target:在 relabel_configsscrape_configs 中注释掉不再需要的Job。

自动化脚本思路:

#!/bin/bash
# 使用 promtool 分析TSDB,找出近期(7天)未被查询的指标并删除
PROM_PATH="/path/to/prometheus/data"
DAYS_THRESHOLD=7
# 获取所有指标及其最后写入时间
promtool tsdb analyze $PROM_PATH --extended
# 如果你需要精确清理,需要自己解析 db 或使用 PromQL
# 示例:查询最近7天没有任何查询命中的指标(需要开启查询日志)

更实用的方法:scrape_configs 中增加 relabel_configs,过滤掉不需要的指标,避免数据进入。


Nagios / Icinga2 环境

Nagios 和 Icinga2 的监控项(services)定义在配置文件中,清理通常通过比较配置文件与当前资产清单实现。

Shell 脚本示例(Icinga2):

#!/bin/bash
# 假设使用 Director API 管理配置
ICINGA_DIRECTOR_URL="https://icinga-master/director"
API_USER="admin"
API_PASS="password"
# 1. 获取所有已配置的 Service
curl -u "$API_USER:$API_PASS" \
     "$ICINGA_DIRECTOR_URL/service?limit=10000" \
     | jq -r '.objects[].object_name' > /tmp/configured_services.txt
# 2. 获取当前实际监控的服务(通过 Icinga API 查询 CheckResult)
# 注意:此步依赖于你如何定义“已使用”,有状态且最近有更新
# 这里以“最近1小时有结果”为例
HOUR_AGO=$(date -d "1 hour ago" +%s)
curl -u "$API_USER:$API_PASS" \
     "$ICINGA_DIRECTOR_URL/objects/services?attrs=last_check" \
     | jq -r --arg ago "$HOUR_AGO" \
       '.results[] | select(.attrs.last_check < ($ago | tonumber)) | .name' \
       > /tmp/obsolete_services.txt
# 3. 输出需要删除的项(只保留配置中存在但无结果的)
grep -Ff /tmp/configured_services.txt /tmp/obsolete_services.txt \
    | while read service; do
        echo "准备删除: $service"
        # 实际删除操作(建议注释掉,先打印)
        # curl -X DELETE -u "$API_USER:$API_PASS" \
        #      "$ICINGA_DIRECTOR_URL/service/$service"
    done

通用思路:基于历史数据库分析

无论哪种系统,核心都是查询历史数据表,找出不再产生数据的监控项。

通用查询逻辑(基于 InfluxDB / TimescaleDB 示例):

-- 假设有一个 metrics 表,字段:metric_name, last_seen
-- 查询最近30天无数据的监控项
SELECT metric_name, last_seen
FROM metric_tracking
WHERE last_seen < NOW() - INTERVAL '30 days';

建议与注意事项

要点 说明
先备份 清理前务必导出配置或快照,特别是使用API删除时。
灰度执行 先跑一次只输出不删除的“Dry run”模式。
考虑依赖 有些监控项可能是触发器、图形、仪表盘的基础,删除前检查依赖。
考虑重新启用 可能监控项只是暂时不活跃(如临时关机),建议先禁用(Disable)而非直接删除,观察一段时间。
日志审计 记录所有删除操作的ID和时间,方便回滚。

推荐执行步骤

  1. 查询:用API/CLI获取所有监控项及其最后数据时间。
  2. 筛选:选出超过指定阈值天数的未使用项。
  3. 审核:导出清单,人工或自动检查是否有关联资源(告警、图表)。
  4. 禁用:先禁用这些监控项(而非删除),等待1-2个监控周期确认无异常。
  5. 删除:确认无误后,执行API删除。

如果需要针对特定监控系统的完整脚本示例(如Zabbix、Prometheus或Nagios),我可以进一步完善该系统的具体代码。

抱歉,评论功能暂时关闭!