IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    监控Netstat数据

    老王发表于 2015-04-09 06:33:37
    love 0

    我的日常工作有很大一部分比重是处理各种网络问题。很多时候,面对突发故障,完全搞不清楚缘由,此时,一个完善的监控系统能起到事半功倍的效果。

    一个好消息是「netstat -s」里的各种计数器包含了很多有用的信息;一个坏消息是计数器记录的通常都是一些硕大无比的绝对值,不够直观。以前,我写过一篇的文章来介绍如何监控相关数据,但写得并不完善;最近,浏览文章时偶然发现一个工具,可以很方便的实时查询计数器相对值的变化情况,可惜不能方便的对接到监控系统里。既然现有的轮子都不太合适我的需求,那么我便有了充足的理由去重新造一个。

    解决问题前需要摸摸底,如下可见命令「netstat -s」的结果是一个层次化的结构:

    netstat -s

    netstat -s

    我们需要把它转换成更利于使用的规范化结构。翠花,上代码:

     $value) {
            $key = $prefix . '.' . $key;
    
            if (is_string($value)) {
                $result[$key] = $value;
            } else {
                $result += one_dimensional_array($value, $key);
            }
        }
    
        return $result;
    }
    
    function multi_dimensional_array($values, $indent = 0) {
        $result = array();
    
        for (reset($values); $v = current($values); next($values)) {
            $space = space($v);
            $last = substr($v, -1);
    
            if ($space == $indent && $last == ':') {
                $title = title($v);
                continue;
            }
    
            if ($last == ':') {
                $_values = array($v);
    
                while ($_value = next($values)) {
                    if (space($_value) > $space) {
                        $_values[] = $_value;
                    } else {
                        prev($values);
                        break;
                    }
                }
    
                $v = multi_dimensional_array($_values, $space);
            }
    
            if (is_string($v)) {
                if (preg_match('/\s(\d+)/', $v, $matches)) {
                    $v = preg_replace("/{$matches[1]}\s?/", '', $v);
                    $result[$title][title($v)] = $matches[1];
                }
            } else {
                $result[$title] += $v;
            }
        }
    
        return $result;
    }
    
    function space($string) {
        return strlen($string) - strlen(ltrim($string));
    }
    
    function title($string) {
        return str_replace(' ', '_', rtrim(trim($string), '\.:'));
    }
    
    ?>

    利用递归把数据先整理成一个层次化数组,再转换成一个扁平化的数组,调用如下:

    最终能生成一百多项网络情况相关数据,很容易就能对接到 Graphite 等监控系统:

    Graphite

    Graphite

    不过需要说明的是,监控的是相对值,不是绝对值!你可以通过 cron 每分钟生成一份当前的绝对值快照,然后对比前一分钟的情况,把相对值发送到监控系统里,例子:

    netstat.TcpExt.fast_retransmits

    netstat.TcpExt.fast_retransmits

    图例监控的是 TcpExt 里的 fast_retransmits 数据,可以明显看到在某一时刻,一部分服务器的 fast_retransmits 变化量明显超过其它服务器,猜测对应的网络可能存在类似丢包等不稳定的情况,有了这些监控,我们就不用再盲人摸象了。

    …

    如果你坚持看到结尾,那么我不得不称赞你是一个有毅力的人,可惜我要告诉你一个坏消息,经网友提醒,Linux 内置的 nstat 命令已经实现了我要的功能,所以所本文写的一大坨代码全都没用了,不过看在我敲了半天的份儿上,就不删除了。



沪ICP备19023445号-2号
友情链接