• Zabbix监控硬盘状态

##通过zabbix监控机房硬盘状态,减少跑机房次数,提前进行硬盘故障预警。

#亲测可以使用的脚本


  • 准备包

megacli-8.02.21-1-mdv2012.0.x86_64.rpm

通过salt直接安装到每台服务器


  • 修改zabbix_agentd配置

增加配置文件

raid_check.conf


UserParameter=raid.phy.discovery,sudo /usr/local/zabbix/scripts/RaidCheck.py pd_discovery

UserParameter=raid.phy.mec[*],sudo /usr/local/zabbix/scripts/RaidCheck.py mec $1

UserParameter=raid.phy.oec[*],sudo /usr/local/zabbix/scripts/RaidCheck.py oec $1

UserParameter=raid.phy.pfc[*],sudo /usr/local/zabbix/scripts/RaidCheck.py pfc $1

UserParameter=raid.phy.fw_state[*],sudo /usr/local/zabbix/scripts/RaidCheck.py fw_state $1


Zabbix_agentd端增加检测脚本

RaidCheck.py


#!/usr/bin/python

# -*- coding: utf-8 -*-

#

# Description:

#   This application is used to discovery the pyhsical disk by using the MegaCLI tool.

#

#



import commands

import os

import sys

import json

from optparse import OptionParser



MEGACLI_EXEC = '/sbin/megacli'

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 != '\n':

            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 firmware_state(disk_array, disk_id):

    for disk in disk_array:

if int(disk.dev_id) == int(disk_id):

    return disk.firmware_state



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())

    elif command == 'fw_state':

print firmware_state(disk_array, args.pop())


配置权限

#tail /etc/sudoers

zabbix  ALL=(root)      NOPASSWD:/usr/local/zabbix/scripts/RaidCheck.py


  • 重启zabbix_agentd

zabbix_server端,通过zabbix_get -s *** -k raid.phy.discovery

可以获取到对应机器的硬盘信息



###资料来源:

https://www.cnblogs.com/alexyang8/p/4270865.html