zoukankan      html  css  js  c++  java
  • Zabbix整合MegaCLI实现物理硬盘的自动发现和监控

    MegaCLI是LSI提供的用户空间管理RAID卡(LSI芯片)工具,适用于大多数的Dell服务器。

    MegaCLI介绍:

    http://zh.community.dell.com/techcenter/b/weblog/archive/2013/03/07/megacli-command-share

    http://blog.chinaunix.net/uid-25135004-id-3139293.html

    Zabbix提供low_level_discovery的机制去实现自动发现监控目标,自动添加监项的功能。Zabbix默认就基于low_level_discovery提供了文件系统挂载点和网卡的自动发现和监控。

    所以,物理硬盘的自动发现和监控也是基于zabbix的low_level_discovery机制,我所需要做的就是写一个Python脚本来衔接Zabbix和MegaCLI。后面就不再阐述原理和细节了,过程如下:

    1. 安装MegaCLI

    去LSI官网上下载一个最新版本的MegaCLI,注意操作系统32位还是64位。

    安装包默认是rpm的,CentOS等系统能轻松安装。

    Ubuntu活debian可参考下面步骤安装:

    mkdir /opt/MegaCLI
    cd /opt/MegaCLI
    wget -c http://xxx/8.07.14_MegaCLI.zip .
    
    unzip 8.07.14_MegaCLI.zip
    cd /opt/MegaCLI/Linux
    apt-get install rpm2cpio
    rpm2cpio MegaCli-8.07.14-1.noarch.rpm | cpio -idmv
    mv opt/MegaRAID /opt/

    root@controller:~# ls -lh /opt/MegaRAID/MegaCli
    total 5.7M
    -rw-r--r-- 1 root root 296 Sep 24 19:10 CmdTool.log
    -rwx------ 1 root root 528K Dec 16 2013 libstorelibir-2.so.14.07-0
    -rwxr-xr-x 1 root root 2.4M Dec 16 2013 MegaCli
    -rwsr-sr-x 1 root root 2.6M Dec 16 2013 MegaCli64
    -rw-r--r-- 1 root root 139K Oct 10 17:43 MegaSAS.log

    后面都默认MegaCli安装在/opt/MegaRAID/MegaCli

    2. 编辑raid.py

    https://gist.github.com/AlexYangYu/14161ce866417f817508

    /opt/DiskMonitoring/raid.py (chmod +x /opt/DiskMonitoring/raid.py)

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    #
    # Description:
    #   This application is used to discovery the pyhsical disk by using the MegaCLI tool.
    #
    # Author: Alex Yang <alex890714@gmail.com>
    #
    
    
    import commands
    import os
    import sys
    import json
    from optparse import OptionParser
    
    
    MEGACLI_EXEC = '/opt/MegaRAID/MegaCli/MegaCli64'
    LIST_DISK_OPT = '-PDList -aALL'
    
    SLOT_NUMBER = 'Slot Number'
    DEVICE_ID = 'Device Id'
    WWN = 'WWN'
    MEC = 'Media Error Count'
    OEC = 'Other Error Count'
    PFC = 'Predictive Failure Count'
    PD_TYPE = 'PD Type'
    RAW_SIZE = 'Raw Size'
    FIRMWARE_STATE = 'Firmware state'
    INQUIRY_DATA = 'Inquiry Data'
    
    
    class Disk(object):
        def __init__(self, dev_id, slot_number, wwn, mec, oec, pfc, pd_type,
                     raw_size, firmware_state, inquiry_data):
            self.dev_id = dev_id
            self.slot_number = slot_number
            self.wwn = wwn
            # Media Error Count
            self.mec = mec
            # Other Error Count
            self.oec = oec
            # Predictive Failure Count
            self.pfc = pfc
            # PD Type
            self.pd_type = pd_type
            # Size
            self.raw_size = raw_size
            # Firmware State ("Failed", "Online, Spun Up", "Online, Spun Down", "Unconfigured(bad)", "Unconfigured(good), Spun down", "Hotspare, Spun down", "Hotspare, Spun up" or "not Online")
                    self.firmware_state = firmware_state
            # Inquiry data
            self.inquiry_data = inquiry_data
    
        def jsonfiy(self):
            pass
    
        def __str__(self):
            return '%s %s %s %s %s %s %s %s %s %s' % (
                self.dev_id, self.slot_number, self.wwn, self.mec, self.oec,
                self.pfc, self.pd_type, self.raw_size, self.firmware_state,
                self.inquiry_data
            )
    
    
    def check_megacli(cli_path):
        if not os.path.exists(cli_path) or not os.access(cli_path, os.X_OK):
            print 'MegaCLI is needed in %s with executable priviledge.' % (cli_path)
            os.exit(1)
    
    
    def line_generator(string):
        line = []
        for c in string:
            if c != '
    ':
                line.append(c)
            else:
                yield ''.join(line)
                line = []
    
    
    def get_value(line):
        return line.split(':')[1].strip()
    
    
    def make_disk_array(mega_output):
        disk_array = []
        for line in line_generator(mega_output):
            if line.startswith(SLOT_NUMBER):
                slot_number = get_value(line)
            elif line.startswith(DEVICE_ID):
                dev_id = get_value(line)
            elif line.startswith(WWN):
                wwn = get_value(line)
            elif line.startswith(MEC):
                mec = get_value(line)
            elif line.startswith(OEC):
                oec = get_value(line)
            elif line.startswith(PFC):
                pfc = get_value(line)
            elif line.startswith(PD_TYPE):
                pd_type = get_value(line)
            elif line.startswith(RAW_SIZE):
                raw_size = get_value(line)
            elif line.startswith(FIRMWARE_STATE):
                fw_state = get_value(line)
            elif line.startswith(INQUIRY_DATA):
                inquiry_data = get_value(line)
    
                disk = Disk(dev_id, slot_number, wwn, mec, oec, pfc, pd_type,
                            raw_size, fw_state, inquiry_data)
                disk_array.append(disk)
        return disk_array
    
    
    def discovery_physical_disk(disk_array):
        array = []
        for d in disk_array:
            disk = {}
            disk['{#DISK_ID}'] = d.dev_id
            disk['{#WWN}'] = d.wwn
            array.append(disk)
        return json.dumps({'data': array}, indent=4, separators=(',',':'))
    
    
    def count_media_error(disk_array, disk_id):
        for disk in disk_array:
            if int(disk.dev_id) == int(disk_id):
                return disk.mec
        return '-1'
    
    def count_other_error(disk_array, disk_id):
        for disk in disk_array:
            if int(disk.dev_id) == int(disk_id):
                return disk.oec
        return '-1'
    
    def count_predictive_error(disk_array, disk_id):
        for disk in disk_array:
            if int(disk.dev_id) == int(disk_id):
                return disk.pfc
        return '-1'
    
    
    def get_disk_array():
        check_megacli(MEGACLI_EXEC)
        (status, output) = commands.getstatusoutput('%s %s' % (MEGACLI_EXEC, LIST_DISK_OPT))
        if status != 0:
            print 'Exec MegaCLI failed, please check the log.'
            os.exit(1)
        disk_array = make_disk_array(output)
        return disk_array
    
    
    def init_option():
        usage = """
        """
        parser = OptionParser(usage=usage, version="0.1")
        return parser
    
    
    parser = init_option()
    
    
    if __name__ == '__main__':
        (options, args) = parser.parse_args()
    
        if len(args) < 1:
            print parser.print_help()
            sys.exit(1)
    
        disk_array = get_disk_array()
    
        command = args.pop(0)
        if command == 'pd_discovery':
            print discovery_physical_disk(disk_array)
        elif command == 'mec':
            print count_media_error(disk_array, args.pop())
        elif command == 'oec':
            print count_other_error(disk_array, args.pop())
        elif command == 'pfc':
            print count_predictive_error(disk_array, args.pop())
    View Code

    3. 配置Zabbix Agent

    编辑zabbix_agentd.conf,确保如下两个配置正确。

    Include=/etc/zabbix/zabbix_agentd.conf.d/
    UnsafeUserParameters=1

    将zabbix用户添加到sudoers中

    echo "zabbix ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/zabbix

    编辑/etc/zabbix/zabbix_agentd.conf.d/disk.conf, 添加自定义用户参数

    UserParameter=raid.phy.discovery,sudo /opt/DiskMonitoring/raid.py pd_discovery
    UserParameter=raid.phy.mec[*],sudo /opt/DiskMonitoring/raid.py mec $1
    UserParameter=raid.phy.oec[*],sudo /opt/DiskMonitoring/raid.py oec $1
    UserParameter=raid.phy.pfc[*],sudo /opt/DiskMonitoring/raid.py pfc $1

    4. 配置Zabbix Server

    创建一个template,然后创建一个discovery rule,然后创建3个ITEM原型

    Media Error Count的配置参考

    后面只需要将模板关联到相关机器,并在相关机器上部署监控脚本即可。报警什么的就可以按自己的需求去设置。 

  • 相关阅读:
    set<char*>s
    sscanf()函数。
    C语言函数sscanf()的用法 (转载
    zjut 1179 平均数
    C++数据间隔
    C++ 保留小数
    c++ 保留小数
    c语言 保留两位小数
    c++ 如何实现保留小数并 且 不进行四舍五入
    uva-657-搜索
  • 原文地址:https://www.cnblogs.com/alexyang8/p/4270865.html
Copyright © 2011-2022 走看看