系统监控之collectd

collectd


简介


collectd是一个守护(daemon)进程,用来定期收集系统和应用程序的性能指标,同时提供了以不同的方式来存储这些指标值的机制。

collectd从各种来源收集指标,例如 操作系统,应用程序,日志文件和外部设备,并存储此信息或通过网络使其可用。 这些统计数据可用于监控系统、查找性能瓶颈(即性能分析)并预测未来的系统负载(即容量规划)等。

优点

  1. 它完全是由C语言编写,故性能很高,可移植性好,它允许运行在系统没有脚本语言支持或者cron daemon的系统上,比如嵌入式系统。同时,它包含优化以及处理成百上千种数据集的新特性。
  2. collectd包含有超过100多种插件。同时,collectd提供强大的网络特性,并且它能以多种方式进行扩充。

缺点

  1. 它本身不能生成图形。虽然它能写RRD文件,但是它不能从这些文件生成图形。
  2. 监控功能只能进行简单的门阀检测。

collectd官方文档地址https://collectd.org/index.shtml

collectd wiki地址https://collectd.org/wiki/index.php/Main_Page


下载、编译、安装


wget https://storage.googleapis.com/collectd-tarballs/collectd-5.7.2.tar.bz2

tar xf collectd-5.7.2.tar.bz2

cd collectd-5.7.2

./configure #编译

也可以在后面加入一些其他可选的选项如:

--prefix=/usr --sysconfdir=/etc -localstatedir=/var --libdir=/usr/lib --mandir=/usr/share/man --enable-all-plugins

make all install #安装

或者

直接执行命令进行安装sudo apt-get install collectd

配置文件目录:/etc/collectd/collectd.conf

启动文件目录:/etc/init.d/collectd

日志文件目录:/var/log/syslog

数据存储目录:/var/lib/collectd/rrd/

若监控集群,则每台服务器都需要下载安装collectd并进行相应的配置。


配置


sudo vim /opt/collectd/etc/collectd.conf

需要监控系统什么项就开启相应的插件,一般有cpu,memory,processes,load,interface,disk,swap等。

一般只需修改network插件这一项:

网络插件可以将数据发送到collectd的远程实例中(例如:数据库,csv文件或缓存等介质中),或者接收从远程服务端发来的数据。

LoadPlugin network       #去掉#就表示载入该插件

#       # client setup:
        Server "10.24.106.1" "25826"  #该地址和端口是接收数据的服务器的地址和端口,例如:安装数据库(influxdb等)的服务器的地址和端口
#        #若需传输加密数据,就配置这一小块部分
#               SecurityLevel Encrypt
#               Username "user"
#               Password "secret"
#               Interface "eth0"
#               ResolveInterval 14400
#       
#       TimeToLive 128
#
#       # server setup:
#       Listen "ff18::efc0:4a42" "25826" #如配置这一部分,表示接收从其他collectd实例中发来的数据
#       
#               SecurityLevel Sign
#               AuthFile "/etc/collectd/passwd"
#               Interface "eth0"
#       
#       MaxPacketSize 1452
#
#       # proxy setup (client and server as above):
#       Forward true
#
#       # statistics about the network plugin itself
#       ReportStats false
#
#       # "garbage collection"
#       CacheFlush 1800


启动


执行命令sudo /etc/init.d/collectd start

或者 systemctl start collectd

并设置开机启动systemctl enable collectd


查看数据


若开启了rrdtool插件就可在/var/lib/collectd/rrd/目录下看到相应的统计数据。

通过下面命令可以查看具体数据:

rrdtool fetch *.rrd AVERAGE

*.rrd表示任何以.rrd结尾的文件,rrdtool命令更详细的用法可以自行百度。

可以看到第一列为timestamp(时间戳),可以通过命令date -d @timestamp把timestamp(以秒为单位)转换为和date命令显示的相同的的时间格式,命令date +%s用时间戳的形式表示时间。


主要插件介绍


  • Plugin: CPU

可视化显示

系统监控之collectd_第1张图片
cpu

指标释义

jiffies: 是一个单位,jiffies是内核中的一个全局变量,用来记录自系统启动一来产生的节拍数,在linux中,一个节拍大致可理解为操作系统进程调度的最小时间单位,不同linux内核可能值有不同,通常在1ms到10ms之间

user: 从系统启动开始累计到当前时刻,处于用户态的运行时间,不包含 nice值为负的进程。

nice: 从系统启动开始累计到当前时刻,nice值为负的进程所占用的CPU时间。

idle: 从系统启动开始累计到当前时刻,除I/O等待时间以外的其它等待时间。

wait-io: 从系统启动开始累计到当前时刻,I/O操作等待时间。

system: 从系统启动开始累计到当前时刻,处于内核态的运行时间。

softIRQ: 从系统启动开始累计到当前时刻,软中断时间。

IRQ:从系统启动开始累计到当前时刻,硬中断时间。

steal:运行在虚拟环境中其他操作系统所花费的时间。

  • Plugin: interface

Interface插件收集关于流量(每秒八位字节),每秒的数据包和接口错误(一秒钟内)的信息。

系统监控之collectd_第2张图片
interface

rxpck/s:每秒钟接收的数据包

txpck/s:每秒钟发送的数据包

rxbyt/s:每秒钟接收的字节数

txbyt/s:每秒钟发送的字节数

  • Plugin: processes
系统监控之collectd_第3张图片
processes
  • Plugin: memory 收集系统的物理内存利用率
系统监控之collectd_第4张图片
processes
  • Plugin: swap 收集swap空间的使用情况
系统监控之collectd_第5张图片
swap
  • Plugin: df 统计文件系统的使用信息

  • Plugin: irq 收集操作系统处理中断的数量

  • Plugin: disk 收集磁盘的性能统计信息

  • Plugin: load 收集系统负载信息,定义为队列中可运行任务的数量

在Linux中,系统相关数据可以通过命令cd /proc/在该目录下查看。


自定义插件


python插件将python解释器嵌入到collectd中并且提供了collectd插件系统接口。

插件配置

LoadPlugin python    #默认是关闭的,需要去掉#,载入插件

       ModulePath "/path/to/your/python/modules" #可以使用多行ModulePath来导入更多的目录
       LogTraces true  #如果python脚本报错,是否要记录下来。如果设置为true,它将记录下和在python解释器中一样的所有报错。
       Interactive true  #这个选项将使module打开一个python解释器在终端显示读与写。
       Import "spam"     #导入spam这个模块

       
               spam "wonderful" "lovely" #配置该Python模块所需要的参数
       

collectd提供了基本的方法用于注册自己插件的配置加载函数、数据读取函数和数据写函数。

函数 描述
collectd.register_config() 该方法实现对模块参数的读取
collectd.register_read() 该方法进行数据的采集
collectd.register_write() 该方法用于对数据的采集进行写处理

以上三个方法的参数中最重要的都是一个回调函数,分别用于读取配置文件、采集监控数据和处理获取的监控数据。

Python模块伪代码

Any Python module will start similar to:
    
    import collectd

A very simple read function might look like:

    def read(data=None):  #定义一个read回调函数
        ```
            实现对指标的数据采集
            collectd有自己的类型,都存储在Types.db中
        ```
        vl = collectd.Values(type='gauge') #gauge是collectd的内建数据类型,也可以在types.db中自定义数据类型
        vl.plugin='python.spam'
        vl.values = [random.random() * 100] 
        vl.dispatch() #发送获取的values,给write插件读取。

A very simple write function might look like:

    def write(vl, data=None): #定义一个write回调函数
        ```
            将获取到的数据按照要求插入自己的数据存储中
            在这里直接打印输出
        ```
        for i in vl.values:
            print "%s (%s): %f" % (vl.plugin, vl.type, i)

To register those functions with collectd:

    collectd.register_read(read)   #注册回调函数read
    collectd.register_write(write)  #注册回调函数write

实例分析


首先在collectd.conf文件中配置Python插件如下:

  
    ModulePath "/opt/collectd/lib/collectd"  
    Import "cpu_usage_plugin"  
      
        Interval 30  
        PluginName "cpu_usage"  
        HostName "demo_host"  
        Verbose false  
      
  

模块cpu_usage_plugin.py内容如下:

#!/usr/bin/env python  

import subprocess  
import traceback  


def get_cpu_usage():  
    cmd = "grep 'cpu ' /proc/stat | awk '{usage=($2+$4)*100/($2+$4+$5)} END {print usage}'"  
    result = run(cmd)  
    for line in result:  
        try:  
            usage = float(line)  
            return usage  
        except:  
            raise Exception("Failed to parse cpu usage")  


def run(cmd):  
    try:  
        result = []  
        proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, close_fds=True)  
        (stdout, stderr) = proc.communicate()  
        output = stdout.split("\n")  
        for line in output:  
            if line == '':  
                continue  
            result.append(line)  
        return result  
    except Exception as err:  
        raise Exception("failed to execute command: %s, reason: %s" % (' '.join(cmd), err.message))  


class CPUStatMon(object):  
    
    def __init__(self):  
        self.plugin_name = "cpu_stat"  
        self.interval = 30  
        self.hostname = None  
        self.verbose_logging = False  

    def log_verbose(self, msg):  
        if not self.verbose_logging:  
            return  
        collectd.info('%s plugin [verbose]: %s' % (self.plugin_name, msg))  



    def configure_callback(self, conf):  
        for node in conf.children:  
            val = str(node.values[0])  
            if node.key == "HostName":  
                self.hostname = val  
            elif node.key == 'Interval':  
                self.interval = int(float(val))  
            elif node.key == 'Verbose':  
                self.verbose_logging = val in ['True', 'true']  
            elif node.key == 'PluginName':  
                self.plugin_name = val  
            else:  
                collectd.warning('[plugin] %s: unknown config key: %s' % (self.plugin_name, node.key))  

    def dispatch_value(self, plugin, host, type, type_instance, value):  
        self.log_verbose("Dispatching value plugin=%s, host=%s, type=%s, type_instance=%s, value=%s" %(plugin, host, type, type_instance, str(value)))  
        val = collectd.Values(type=type)  
        val.plugin = plugin  
        val.host = host  
        val.type_instance = type_instance  
        val.interval = self.interval  
        val.values = [value]  
        val.dispatch()  
        self.log_verbose("Dispatched value plugin=%s, host=%s, type=%s, type_instance=%s, value=%s" %(plugin, host, type, type_instance, str(value)))  

    def read_callback(self):  
        try:  
            usage = get_cpu_usage()  
            type = 'cpu_usage_percent'  
            type_instance = "used"  
            value = usage  
            self.dispatch_value(self.plugin_name, self.hostname, type, type_instance, value)  

        except Exception as exp:  
            self.log_verbose(traceback.print_exc())  
            self.log_verbose("plugin %s run into exception" % (self.plugin_name))  
            self.log_verbose(exp.message)  
    
    def write_callback(self,val):
        
        pass #可以把数据写进数据库或文件中。

if __name__ == '__main__':  
    result = get_cpu_usage()  
    print result  

else:  
    import collectd  
    cpu_status_mon = CPUStatMon()  
    collectd.register_config(cpu_status_mon.configure_callback)  
    collectd.register_read(cpu_status_mon.read_callback)
    collectd.register_write(cpu_status_mon.write_callback)  

END

你可能感兴趣的:(系统监控之collectd)