zabbix 从放弃到入门——监控 使用 vnstat 统计每日流量

2022年2月23日 0 条评论 988 次阅读 0 人点赞
统计流量的文章搜索了一下不是很多,其中一个大致思路是 凌晨一个监控获取当前网卡流量数,然后一个递增监控网卡流量总数,再一个递增监控可计算的差值到接近凌晨的时候就是当日流量,这样每日流量就出来了,不过那个 可计算的 值一直写不对,搞了一段时间了放弃,直接用 vnstat 获取每日流量后json输出然后javascipt计算总数到一个监控里面。

1、准备工作

安装了 Zabbix  https://www.sevenfal.com/2022/02/10/1853.html 

于被监控主机上,安装 vnstat:

CentOS8 可以 yum 直接安装 vnstat2.6 

CentOS7 采用先 yum 安装 vnstat1.5 然后再把编译好的 vnstat2.6 替换对应文件的方式

    /usr/bin/vnstat
    /usr/sbin/vnstatd
    /etc/vnstat.conf
    /usr/lib/systemd/system/vnstat.service

下载和编译方式参考 https://github.com/vergoh/vnstat/blob/master/INSTALL.md 
安装好后,确认 vnstat -d 有输出内容,服务运行正常等。
zabbix-agent 配置文件 /etc/zabbix/zabbix_agentd.conf 中添加了 AllowKey=system.run[*]  并且重启了 zabbix-agent 服务
或 zabbix-agent2 配置文件 /etc/zabbix/zabbix_agent2.conf 中添加了 AllowKey=system.run[*]  并且重启了 zabbix-agent2 服务

2、添加监控项

采用直接在自带模板 Linux network interfaces by Zabbix agent —— 自动发现清单 Network interface discovery —— 监控原型 中添加监控,方便使用 LLD宏 {#IFNAME} (不知道这个宏在模板哪里获取的)

键值为 system.run[/usr/bin/vnstat --json d 1 -i {#IFNAME}]

image.png

进程 JavaScript —— 参数:

var days=JSON.parse(value)["interfaces"][0]["traffic"]["day"][0];
return days["tx"]+days["rx"];

image.png

image.png

提交修改即可

3、设置 图形

编辑仪表盘——添加组建 Add widget —— 类型: 图形 —— 数据设置: 添加 需要查看的主机 —— 监控模式: 选择 上方添加监控项 的名称
1647010520668910.png
时间期间如需要设置当日,则设置为 now/d ,可以参考查看数据时候右上方的选项设置出来的结果。

4、 修正查看内容中流量排名

将鼠标放在图表或者点击的时候,会出现对应时间详细内容:
image.png
由于没有按照流量使用排序,看起来不是很方便,找了一下 Zabbix 代码后,找到对应位置修改增加排序的函数和代码,上方图片为实现后的效果。
由于水平有限,查了一圈,Zabbix 大致输出步骤是根据设置的主机和选择的监控项,直接出了结果,找了一圈只找到了 JS 中的输出位置,为了保障流量大小可读性,思路就是将 "477 GB" 这样的字符串,先转换为 B 单位的整数类型,然后使用 数组排序 之后, 再转换成 GB MB这种可读单位。
首先把显示所有数据内容限制打开,位于 /usr/share/zabbix/include/defines.inc.php:1101

define('SVG_GRAPH_MAX_NUMBER_OF_METRICS', 200); // 将此处数值修改为你监控主机*监控项的数值,确保显示了所有数据

JS 位置: /usr/share/zabbix/js/class.csvggraph.js 

// 250 行
     function findValues(graph, x) {
         var data_sets = [],
             conver_ = 0, // 新增此行,设置排序判断变量
             nodes = graph.querySelectorAll('[data-set]');

// 366 行
             if ( pv != null && pv.indexOf("B") > -1){ conver_ = 1;} // 新增此行,当监控值包含 B 的时候设置排序
             data_sets.push({g: nodes[i], x: px, y: py, v: pv, p: pp, s: ps});
         }

    // 以下为新增内容
    if ( conver_ == 1 ){ // 当监控值包含 B 的时候排序
        // 历遍数组将 可读包含单位内容 转换为 B 单位整数类型,便于排序
        for ( i = 0, len = data_sets.length; i < len; i++){
        var source_ = data_sets[i].v;
        if(source_){
            source_ = source_.split(" ");
            switch (source_[1]){
                case "TB":
                    data_sets[i].v = source_[0] * 1024 * 1024 * 1024 * 1024;
                    break;
                case "GB":
                    data_sets[i].v = source_[0] * 1024 * 1024 * 1024 ;
                    break;
                case "MB":
                    data_sets[i].v = source_[0] * 1024 * 1024 ;
                    break; 
                case "KB":
                    data_sets[i].v = source_[0] * 1024 ;
                    break; 
                case "B":
                    data_sets[i].v = source_[0] ;
                    break; 
                }
            }
        }
    
        // 排序数组
        data_sets.sort(sortExp('v',false));
    
        // 将排序完后的数组恢复 可读单位内容
        for ( i = 0, len = data_sets.length; i < len; i++){
            data_sets[i].v = bytesToSize(data_sets[i].v);
        }
    }
    
    // 由于要将所有内容排序,内容太多也不合适,在这里设置排序后可见条目
    data_sets.length = 50;
    
    // 以下为原内容
    return data_sets;
    }
    
    // 以下内容为新增
    // 上面用到的排序函数.
    var sortExp=function(key,isAsc){
        return function(x,y){
            if(isNaN(key)){
                if(x[key]>y[key]){
                    return 1*(isAsc?1:-1);
                }else if(x[key]<y[key]){
                    return -1*(isAsc?1:-1);
                }else{
                    return 0;
                }
            }else{
                return (x[key]-y[key])*(isAsc?1:-1)
            }
        }
    }
    
    // 上面用到的单位转换函数
    function bytesToSize(bytes) {
        if (bytes === 0) return '0 B';
        var k = 1024, // or 1024
            sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
            i = Math.floor(Math.log(bytes) / Math.log(k));

        return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i];
    }

如仅需统计显示每日流量使用大小区别,设置 更新间隔 为 0 ,自定义时间间隔 调度 h23m55-59/1 。

Sevenfal

这个人太懒什么东西都没留下

文章评论(0)