/usr/share/check_mk/checks/smart is in check-mk-server 1.2.6p12-1.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | #!/usr/bin/python
# -*- encoding: utf-8; py-indent-offset: 4 -*-
# +------------------------------------------------------------------+
# | ____ _ _ __ __ _ __ |
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
# | | |___| | | | __/ (__| < | | | | . \ |
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
# | |
# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
# +------------------------------------------------------------------+
#
# This file is part of Check_MK.
# The official homepage is at http://mathias-kettner.de/check_mk.
#
# check_mk is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation in version 2. check_mk is distributed
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
# ails. You should have received a copy of the GNU General Public
# License along with GNU Make; see the file COPYING. If not, write
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301 USA.
# Author: Lars Michelsen <lm@mathias-kettner.de>
# EXAMPLE DATA FROM: WDC SSC-D0128SC-2100
#<<<smart>>>
#/dev/sda ATA WDC_SSC-D0128SC- 1 Raw_Read_Error_Rate 0x000b 100 100 050 Pre-fail Always - 16777215
#/dev/sda ATA WDC_SSC-D0128SC- 3 Spin_Up_Time 0x0007 100 100 050 Pre-fail Always - 0
#/dev/sda ATA WDC_SSC-D0128SC- 5 Reallocated_Sector_Ct 0x0013 100 100 050 Pre-fail Always - 0
#/dev/sda ATA WDC_SSC-D0128SC- 7 Seek_Error_Rate 0x000b 100 100 050 Pre-fail Always - 0
#/dev/sda ATA WDC_SSC-D0128SC- 9 Power_On_Hours 0x0012 100 100 000 Old_age Always - 1408
#/dev/sda ATA WDC_SSC-D0128SC- 10 Spin_Retry_Count 0x0013 100 100 050 Pre-fail Always - 0
#/dev/sda ATA WDC_SSC-D0128SC- 12 Power_Cycle_Count 0x0012 100 100 000 Old_age Always - 523
#/dev/sda ATA WDC_SSC-D0128SC- 168 Unknown_Attribute 0x0012 100 100 000 Old_age Always - 1
#/dev/sda ATA WDC_SSC-D0128SC- 175 Program_Fail_Count_Chip 0x0003 100 100 010 Pre-fail Always - 0
#/dev/sda ATA WDC_SSC-D0128SC- 192 Power-Off_Retract_Count 0x0012 100 100 000 Old_age Always - 0
#/dev/sda ATA WDC_SSC-D0128SC- 194 Temperature_Celsius 0x0022 040 100 000 Old_age Always - 40 (Lifetime Min/Max 30/60)
#/dev/sda ATA WDC_SSC-D0128SC- 197 Current_Pending_Sector 0x0012 100 100 000 Old_age Always - 0
#/dev/sda ATA WDC_SSC-D0128SC- 240 Head_Flying_Hours 0x0013 100 100 050 Pre-fail Always - 0
#/dev/sda ATA WDC_SSC-D0128SC- 170 Unknown_Attribute 0x0003 100 100 010 Pre-fail Always - 1769478
#/dev/sda ATA WDC_SSC-D0128SC- 173 Unknown_Attribute 0x0012 100 100 000 Old_age Always - 4217788040605
smart_temp_default_levels = (35, 40)
smart_stats_default_levels = {
'realloc_events': (1, 1),
'realloc_sectors': (1, 1),
'spin_retries': (1, 1),
'pending_retries': (1, 1),
'pending_sectors': (1, 1),
'cmd_timeouts': (5, 10),
'e2e_errs': (1, 1),
'uncorr_errs': (1, 1),
'udma_crcs': (1, 1),
}
def parse_smart(info):
disks = {}
disk_name = None
for line in info:
if len(line) >= 13:
if line[0] != disk_name:
disk_name = line[0]
disk = {}
disks[disk_name] = disk
field = line[4]
if field != "Unknown_Attribute":
value = saveint(line[12])
disk[field] = value
return disks
smart_stats_fields = [
'Reallocated_Sector_Ct',
'Spin_Retry_Count',
'Reallocated_Event_Count',
'Current_Pending_Sector',
'Command_Timeout',
'End-to-End_Error',
'Reported_Uncorrect',
'UDMA_CRC_Error_Count', ]
def inventory_smart_stats(info):
disks = parse_smart(info)
inventory = []
for disk_name, disk in disks.items():
for field in disk.keys():
if field in smart_stats_fields: # found at least one interesting field
cleaned = dict([(f, disk[f]) for f in smart_stats_fields if f in disk])
inventory.append((disk_name, cleaned))
break
return inventory
def check_smart_stats(item, params, info):
# params is a snapshot of all counters at the point of time of inventory
disks = parse_smart(info)
if item not in disks:
return 3, "Disk not found"
disk = disks[item]
state = 0
infos = []
perfdata = []
for unit, field, descr in [
(' hours', 'Power_On_Hours', 'Powered on', ),
('', 'Power_Cycle_Count', 'Power cycles', ),
('', 'Reallocated_Sector_Ct', 'Reallocated sectors', ),
('', 'Reallocated_Event_Count', 'Reallocated events', ),
('', 'Spin_Retry_Count', 'Spin retries', ),
('', 'Current_Pending_Sector', 'Pending sectors', ),
('', 'Command_Timeout', 'Command timeouts', ),
('', 'End-to-End_Error', 'End-to-End errors', ),
('', 'Reported_Uncorrect', 'Uncorrectable errors', ),
('', 'UDMA_CRC_Error_Count', 'UDMA CRC errors', )]:
if field in disk:
value = disk[field]
infos.append("%s: %d%s" % (descr, value, unit))
perfdata.append((field, value))
if field in params:
ref_value = params[field]
if value > ref_value:
state = 2
infos[-1] += " - was %d during inventory(!!)" % ref_value
return state, ", ".join(infos), perfdata
check_info["smart.stats"] = {
'check_function': check_smart_stats,
'inventory_function': inventory_smart_stats,
'has_perfdata': True,
'service_description': 'SMART %s Stats',
}
def inventory_smart_temp(info):
disks = parse_smart(info)
return [(disk_name, 'smart_temp_default_levels')
for disk_name, disk in disks.items()
if "Temperature_Celsius" in disk]
def check_smart_temp(item, params, info):
disks = parse_smart(info)
if item not in disks:
return
disk = disks[item]
return check_temperature(disk["Temperature_Celsius"], params)
check_info["smart.temp"] = {
'check_function': check_smart_temp,
'inventory_function': inventory_smart_temp,
'service_description': 'Temperature SMART %s',
'group': 'disk_temperature',
'has_perfdata': True,
'includes': [ 'temperature.include' ],
}
|