• 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

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

###资料来源: