├── windows ├── raid_trapper_checks_task.xml ├── lsi_raid.conf ├── raid_check.ps1 ├── raid_discovery.ps1 └── raid_trapper_checks.ps1 ├── template ├── LSI_RAID_valuemaps.xml └── LSI_RAID_template.xml ├── README.md └── unix ├── raid_discovery.pl ├── raid_trapper_check.pl └── raid_check.pl /windows/raid_trapper_checks_task.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Art3mK/Zabbix-LSI-RAID-Monitoring/HEAD/windows/raid_trapper_checks_task.xml -------------------------------------------------------------------------------- /windows/lsi_raid.conf: -------------------------------------------------------------------------------- 1 | # Check path and add this string to zabbix agent config 2 | # Include=C:\Program Files\zabbix_agent\conf.d\lsi_raid\lsi_raid.conf 3 | UserParameter=hw.raid.physical_disk[*],C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File "C:\Program Files\zabbix_agent\conf.d\lsi_raid\raid_check.ps1" -mode pdisk -item $4 -adapter $1 -enc $2 -pdisk $3 4 | UserParameter=hw.raid.logical_disk[*],C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File "C:\Program Files\zabbix_agent\conf.d\lsi_raid\raid_check.ps1" -mode vdisk -item $3 -adapter $1 -vdisk $2 5 | UserParameter=hw.raid.bbu[*],C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File "C:\Program Files\zabbix_agent\conf.d\lsi_raid\raid_check.ps1" -mode bbu -item $2 -adapter $1 6 | UserParameter=hw.raid.adapter[*],C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File "C:\Program Files\zabbix_agent\conf.d\lsi_raid\raid_check.ps1" -mode adapter -item $2 -adapter $1 -------------------------------------------------------------------------------- /template/LSI_RAID_valuemaps.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 3.2 4 | 2017-12-28T11:59:23Z 5 | 6 | 7 | LSI RAID BBU & LD Status 8 | 9 | 10 | 0 11 | Optimal 12 | 13 | 14 | 1 15 | Failed 16 | 17 | 18 | 19 | 20 | LSI RAID PhysDrv Status 21 | 22 | 23 | 0 24 | (Online|Hostpare|Unconfigured good) 25 | 26 | 27 | 1 28 | Failed 29 | 30 | 31 | 2 32 | Rebuild 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Zabbix template for Intel/LSI/Symbios RAID Controllers 2 | 3 | [Topic](https://www.zabbix.com/forum/showthread.php?t=41439) on zabbix forum 4 | 5 | ## LSI_RAID_valuemaps 6 | Zabbix value mappings for "Template LSI RAID". Should be imported before template via "Administration" -> "General" -> "Value mapping" -> "Import". 7 | 8 | ### Available items: 9 | **LSI RAID BBU & LD Status** 10 | - 0 -> Optimal 11 | - 1 -> Failed 12 | 13 | **LSI RAID PhysDrv Status** 14 | - 0 -> (Online|Hostpare|Unconfigured good) 15 | - 1 -> Failed 16 | - 2 -> Rebuild 17 | 18 | ## LSI_RAID_template 19 | Zabbix template "Template LSI RAID". Should be imported after Zabbix value mappings via "Configuration" -> "Templates" -> "Import". 20 | 21 | ### Available items: 22 | **Adapter** 23 | - Adapter model 24 | - Firmware version 25 | 26 | **Battery Backup Unit** 27 | - BBU State (+trigger) 28 | - BBU State of charge (+trigger) 29 | - BBU manufacture date (disabled by default) 30 | - BBU design capacity (disabled by default) 31 | - BBU current capacity (disabled by default) 32 | 33 | **Physical drives** 34 | - Firmware state (+trigger) 35 | - Predictive errors (+trigger) 36 | - Media errors (+trigger) 37 | - Size 38 | - Model 39 | 40 | **Logical volumes** 41 | - Volume state (+trigger) 42 | - Volume size 43 | 44 | ## Scripts 45 | 3 scripts are available for windows (powershell) and unix (perl) servers 46 | 47 | ### RAID Discovery script 48 | This script is used for Low Level Discovery of RAID configuration. Scripts uses zabbix_sender and agent configuration file to report RAID configuration to zabbix. 49 | ### RAID checks script 50 | This script is used by zabbix agent to check "non critical" items, such as adapter model, physical drive size, etc. But this script also supports checking of all items from template (i.e. you can change type for all items from 'Zabbix trapper' to 'Zabbix Agent'). I've created "trapper" version of this script, because zabbix agent very often reports that some item is not supported (I noticed that problem only on Windows servers). Probably there are some locking occurs, when zabbix agent checks a lot of items at the same time. 51 | ### RAID "trapper" check script 52 | This scrips reports all values for "critical" items at once. Currently it reports BBU state and state of charge, physical drives state, predictive and media erros, logical volumes states. All other checks are performed by zabbix agent using RAID checks scripts and userparameters. 53 | 54 | Discovery and "trapper" scripts are executed by system scheduler. 55 | 56 | ## Agent userparameters: 57 | 58 | ### Windows 59 | 60 | UserParameter=hw.raid.physical_disk[*],C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File "C:\Program Files\zabbix_agent\raid_check.ps1" -mode pdisk -item $4 -adapter $1 -enc $2 -pdisk $3 61 | UserParameter=hw.raid.logical_disk[*],C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File "C:\Program Files\zabbix_agent\raid_check.ps1" -mode vdisk -item $3 -adapter $1 -vdisk $2 62 | UserParameter=hw.raid.bbu[*],C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File "C:\Program Files\zabbix_agent\raid_check.ps1" -mode bbu -item $2 -adapter $1 63 | UserParameter=hw.raid.adapter[*],C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File "C:\Program Files\zabbix_agent\raid_check.ps1" -mode adapter -item $2 -adapter $1 64 | 65 | ### Unix/Linux 66 | 67 | UserParameter=hw.raid.physical_disk[*],/usr/bin/perl -w /etc/zabbix/scripts/raid_check.pl -mode pdisk -item $4 -adapter $1 -enclosure $2 -pdisk $3 68 | UserParameter=hw.raid.logical_disk[*],/usr/bin/perl -w /etc/zabbix/scripts/raid_check.pl -mode vdisk -item $3 -adapter $1 -vdisk $2 69 | UserParameter=hw.raid.bbu[*],/usr/bin/perl -w /etc/zabbix/scripts/raid_check.pl -mode bbu -item $2 -adapter $1 70 | UserParameter=hw.raid.adapter[*],/usr/bin/perl -w /etc/zabbix/scripts/raid_check.pl -mode adapter -item $2 -adapter $1 71 | 72 | For agents on unix servers RAID tool should be executed via sudo, add this to sudoers file: 73 | 74 | Defaults:zabbix !requiretty 75 | # path to your tool can be different 76 | zabbix ALL=NOPASSWD:/opt/MegaRAID/CmdTool2/CmdTool2 77 | 78 | ## Scheduled Tasks 79 | 80 | The script raid_trapper_checks must be run via cron/scheduled tasks. There is a trigger defined that alerts when the data is older than 10 minutes, so the script should be executed every 5 minutes or so. 81 | 82 | ### Windows 83 | 84 | Adapt the paths in `raid_trapper_checks_task.xml` to your needs and import it in the Task Scheduler. 85 | 86 | ### Linux/Unix 87 | 88 | # crontab -e -u zabbix 89 | * */5 * * * perl /path/to/your/raid_trapper_check.pl 90 | 91 | I'm not a programmer, so code review will be appreciated :) 92 | -------------------------------------------------------------------------------- /windows/raid_check.ps1: -------------------------------------------------------------------------------- 1 | Param( 2 | [parameter(Position=0,Mandatory=$true)] 3 | [ValidateSet("pdisk", "vdisk", "bbu", "adapter")] 4 | [alias("m")] 5 | [String] 6 | $mode 7 | , 8 | [parameter()] 9 | [ValidateNotNullOrEmpty()] 10 | [alias("p","item")] 11 | [string] 12 | $mode_item 13 | , 14 | [parameter(Mandatory=$true)] 15 | [ValidateRange(0,5)] 16 | [alias("a","adp")] 17 | [int] 18 | $adapter 19 | , 20 | [parameter()] 21 | [ValidateRange(0,4096)] 22 | [alias("e","enc")] 23 | [int] 24 | $enclosure_id 25 | , 26 | [parameter()] 27 | [ValidateRange(0,256)] 28 | [alias("pdisk")] 29 | [int] 30 | $disk_id 31 | , 32 | [parameter()] 33 | [ValidateRange(0,256)] 34 | [alias("vdisk")] 35 | [int] 36 | $vdisk_id 37 | ) 38 | 39 | $CLI = "C:\raid\CmdTool2_64.exe" 40 | 41 | function pdisk_item($item,$adapter,$enclosure_id,$disk_id) { 42 | $regex = '' 43 | switch ($item) { 44 | 'firmware_state' { $regex = "Firmware state:\s(.*)" } 45 | 'raw_size' { $regex = "Raw Size:\s+(\d+\.\d+\s..)" } 46 | 'predictive_errors' { $regex = "Predictive Failure Count:\s(.*)" } 47 | 'inquiry_data' { $regex = "Inquiry Data:\s+(.*)" } 48 | 'media_errors' { $regex = "Media Error Count:\s(.*)" } 49 | } 50 | 51 | if ($enclosure_id -eq 2989) { $enclosure_id = '' } 52 | $output = (& $CLI -pdinfo -PhysDrv["$enclosure_id":"$disk_id"] -a $adapter -NoLog | Select-String $regex -AllMatches | % { $_.Matches } | % { $_.groups[1].value }) 53 | if ($item -eq 'firmware_state') { 54 | if ($output -Match '^(Unconfigured\(good\).*|Online,\sSpun.*|Hotspare,\sSpun.*)$') { 55 | $output = 0 56 | } 57 | elseif ($output -Match '^Rebuild') { 58 | $output = 2 59 | } 60 | else { 61 | $output = 1 62 | } 63 | } 64 | write-host $output 65 | } 66 | 67 | function vdisk_item($item,$adapter,$vd) { 68 | $regex = '' 69 | switch ($item) { 70 | 'vd_state' { $regex = "^State\s+:\s(.*)$" } 71 | 'vd_size' { $regex = "^Size\s+:\s(\d+\.\d+\s..)" } 72 | } 73 | 74 | $output = (& $CLI -LDinfo -L $vd -a $adapter -NoLog | Select-String $regex -AllMatches | % { $_.Matches } | % { $_.groups[1].value }) 75 | if ($item -eq 'vd_state') { 76 | if ($output -Match '^Optimal$') { $output = 0 } else { $output = 1 } 77 | } 78 | write-host $output 79 | } 80 | 81 | function bbu_item($item,$adapter){ 82 | $regex = '' 83 | $command = '' 84 | switch ($item) { 85 | 'bbu_state' { $command = '-GetBbuStatus'; $regex = "Battery State\s*:\s(.*)$"; $wanted_group = 1 } 86 | 'design_capacity' { $command = '-GetBBUDesignInfo'; $regex = "Design\sCapacity:\s(\d+)\s(mAh|J)"; $wanted_group = 1 } 87 | 'full_capacity' { $command = '-GetBBUCapacityInfo'; $regex = "(Full\sCharge\sCapacity|.*Pack\senergy\s*):\s(\d+)\s(mAh|J)"; $wanted_group = 2 } 88 | 'state_of_charge' { $command = '-GetBBUCapacityInfo'; $regex = "Absolute\sState\sof\scharge\s*:\s(\d+).*%"; $wanted_group = 1 } 89 | 'date_manufactured' { $command = '-GetBBUDesignInfo'; $regex = "Date\sof\sManufacture\s*:\s(.*)$"; $wanted_group = 1 } 90 | } 91 | if ($bbu_state -Match '^(Optimal|Operational)$') { $bbu_state = 0 } else { $bbu_state = 1 } 92 | $output = (& $CLI -AdpBbuCmd $command -a $adapter -NoLog | Select-String $regex | % {$_.Matches} | % { $_.groups[$wanted_group].value }) 93 | if ($item -eq 'bbu_state') { 94 | if ($output -Match '^(Optimal|Operational)$') { $output = 0 } else { $output = 1 } 95 | } 96 | write-host $output 97 | } 98 | 99 | function adapter_item($item,$adapter){ 100 | $regex = '' 101 | switch ($item) { 102 | 'fw_version' { $regex = "^\s*FW\sPackage\sBuild:\s(.*)$" } 103 | 'product_name' { $regex = "^\s*Product\sName\s*:\s(.*)$" } 104 | } 105 | 106 | $output = (& $CLI -AdpAllInfo -a $adapter -NoLog | Select-String $regex | % {$_.Matches} | % { $_.groups[1].value }) 107 | write-host $output 108 | } 109 | 110 | ### Start doing our job 111 | 112 | switch ($mode) { 113 | "pdisk" { pdisk_item $mode_item $adapter $enclosure_id $disk_id } 114 | "vdisk" { vdisk_item $mode_item $adapter $vdisk_id } 115 | "bbu" { bbu_item $mode_item $adapter } 116 | "adapter" { adapter_item $mode_item $adapter } 117 | } 118 | -------------------------------------------------------------------------------- /unix/raid_discovery.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | use strict; 4 | use warnings; 5 | 6 | my $cli = '/opt/MegaRAID/MegaCli/MegaCli64'; 7 | my $zabbix_config = '/etc/zabbix_agentd.conf'; 8 | my $zabbix_sender = '/usr/bin/zabbix_sender'; 9 | my $tmp_path = '/tmp/raid-discovery-zsend-data.tmp'; 10 | my %enclosures = (); 11 | my %adapters = (); 12 | my %battery_units = (); 13 | my %physical_drives = (); 14 | my %virtual_drives = (); 15 | 16 | my $adp_count = `$cli -AdpCount -NoLog`; 17 | # Controller Count: 1. 18 | if ($adp_count =~ m/.*Controller\sCount:\s(\d)\.*/i) { 19 | $adp_count = $1; 20 | } else { 21 | print "Didn't find any adapter, check regex or $cli\n"; 22 | exit(1); 23 | } 24 | 25 | for (my $adapter = 0; $adapter < $adp_count; $adapter++) { 26 | my $pd_num = `$cli -pdGetNum -a $adapter -NoLog`; 27 | # Number of Physical Drives on Adapter 0: 6 28 | if ($pd_num =~ m/.*Number\sof\sPhysical\sDrives\son\sAdapter\s$adapter:\s(\d+)\n.*/) { 29 | $pd_num = $1; 30 | if ($pd_num == 0) { 31 | print "No physical disks found on adapter $adapter\n"; 32 | next; 33 | } else { 34 | $adapters{$adapter} = "{ \"{#ADAPTER_ID}\":\"$adapter\" }"; 35 | } 36 | } 37 | 38 | my $number_of_lds = `$cli -LDGetNum -a $adapter -NoLog`; 39 | # Number of Virtual Drives Configured on Adapter 0: 3 40 | if ($number_of_lds=~ m/.*Number\sof\sVirtual\sDrives\sConfigured\son\sAdapter\s$adapter:\s(\d+)/) { 41 | $number_of_lds = $1; 42 | if ($number_of_lds == 0) { 43 | print "No virtual disks found on adapter $adapter\n"; 44 | next; 45 | } 46 | my @vd_list = `$cli -LDinfo -Lall -a $adapter -NoLog`; 47 | my $vdrive_id = -1; 48 | foreach my $line (@vd_list) { 49 | if ($line =~ m/^\s*Virtual\sDrive:\s(\d+)\s.*$/) { 50 | $vdrive_id = $1; 51 | $virtual_drives{"$adapter$vdrive_id"} = "{ \"{#VDRIVE_ID}\":\"$vdrive_id\", \"{#ADAPTER_ID}\":\"$adapter\" }"; 52 | } else { 53 | next; 54 | } 55 | } 56 | } 57 | 58 | my $bbu_info = `$cli -AdpBbuCmd -GetBbuStatus -a $adapter -NoLog`; 59 | if (!($bbu_info =~ m/.*Get BBU Status Failed.*/)) { 60 | $battery_units{$adapter} = "{ \"{#ADAPTER_ID}\":\"$adapter\" }"; 61 | } 62 | 63 | my @pd_list = `$cli -pdlist -a $adapter -NoLog`; 64 | my $check_next_line = 0; 65 | my $enclosure_id = -1; 66 | # Determine Slot Number for each drive on current enclosure 67 | foreach my $line (@pd_list) { 68 | if ($line =~ m/^Enclosure\sDevice\sID:\s(\d+)$/) { 69 | $enclosure_id = $1; 70 | $check_next_line = 1; 71 | } elsif ($line =~ m/^\s*Enclosure\sDevice\sID:\sN\/A$/) { 72 | # This can happen, if embedded raid controller is in use, there are drives and logical disks, but no enclosures 73 | $enclosure_id = 2989; # 0xBAD, :( magic hack 74 | $check_next_line = 1; 75 | } elsif (($line =~ m/^Slot\sNumber:\s(\d+)$/) && $check_next_line) { 76 | $physical_drives{"$adapter$enclosure_id$1"} = "{ \"{#ENCLOSURE_ID}\":\"$enclosure_id\", \"{#PDRIVE_ID}\":\"$1\", \"{#ADAPTER_ID}\":\"$adapter\" }"; 77 | $check_next_line = 0; 78 | } else { 79 | next; 80 | } 81 | } 82 | } 83 | 84 | open(ZSEND_FILE,">$tmp_path") or die "Can't open $tmp_path: $!"; 85 | 86 | my $phd_count = keys %physical_drives; 87 | my $lds_count = keys %virtual_drives; 88 | 89 | if (($phd_count != 0) && ($lds_count != 0)) { 90 | my $i = 1; 91 | print ZSEND_FILE "- hw.raid.discovery.pdisks { \"data\":["; 92 | foreach my $drive (keys %physical_drives) { 93 | if ($i < $phd_count) { 94 | print ZSEND_FILE "$physical_drives{$drive},"; 95 | $i++; 96 | } else { 97 | print ZSEND_FILE "$physical_drives{$drive}]}\n"; 98 | } 99 | } 100 | $i = 1; 101 | print ZSEND_FILE "- hw.raid.discovery.vdisks { \"data\":["; 102 | foreach my $vdrive (keys %virtual_drives) { 103 | if ($i < $lds_count) { 104 | print ZSEND_FILE "$virtual_drives{$vdrive},"; 105 | $i++; 106 | } else { 107 | print ZSEND_FILE "$virtual_drives{$vdrive}]}\n"; 108 | } 109 | } 110 | $i = 1; 111 | my $bbu_count = keys %battery_units; 112 | if ($bbu_count != 0) { 113 | print ZSEND_FILE "- hw.raid.discovery.bbu { \"data\":["; 114 | foreach my $bbu (keys %battery_units) { 115 | if ($i < $bbu_count) { 116 | print ZSEND_FILE "$battery_units{$bbu},"; 117 | $i++; 118 | } else { 119 | print ZSEND_FILE "$battery_units{$bbu}]}\n"; 120 | } 121 | } 122 | } 123 | $i = 1; 124 | my $adp_count = keys %adapters; 125 | if ($adp_count != 0) { 126 | print ZSEND_FILE "- hw.raid.discovery.adapters { \"data\":["; 127 | foreach my $adapter (keys %adapters) { 128 | if ($i < $adp_count) { 129 | print ZSEND_FILE "$adapters{$adapter},"; 130 | $i++; 131 | } else { 132 | print ZSEND_FILE "$adapters{$adapter}]}\n"; 133 | } 134 | } 135 | } 136 | } 137 | close (ZSEND_FILE) or die "Can't close $tmp_path: $!"; 138 | 139 | my @cmd_args = ($zabbix_sender,'-c',$zabbix_config,'-i',$tmp_path); 140 | system(@cmd_args); -------------------------------------------------------------------------------- /unix/raid_trapper_check.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | use strict; 4 | use warnings; 5 | 6 | my $cli = '/opt/MegaRAID/CmdTool2/CmdTool2'; 7 | my $zabbix_config = '/etc/zabbix_agentd.conf'; 8 | my $zabbix_sender = '/usr/bin/zabbix_sender'; 9 | my $tmp_path = '/tmp/raid-discovery-zsend-trapper-data.tmp'; 10 | my %enclosures = (); 11 | 12 | my $adp_count = `$cli -AdpCount -NoLog`; 13 | # Controller Count: 1. 14 | if ($adp_count =~ m/.*Controller\sCount:\s(\d)\.*/i) { 15 | $adp_count = $1; 16 | } else { 17 | print "Didn't find any adapter, check regex or $cli\n"; 18 | exit(1); 19 | } 20 | 21 | unlink $tmp_path if (-e $tmp_path); 22 | 23 | for (my $adapter = 0; $adapter < $adp_count; $adapter++) { 24 | my $pd_num = `$cli -pdGetNum -a $adapter -NoLog`; 25 | # Number of Physical Drives on Adapter 0: 6 26 | if ($pd_num =~ m/.*Number\sof\sPhysical\sDrives\son\sAdapter\s$adapter:\s(\d+)\n.*/) { 27 | $pd_num = $1; 28 | if ($pd_num == 0) { 29 | print "No physical disks found on adapter $adapter\n"; 30 | next; 31 | } 32 | } 33 | 34 | my $number_of_lds = `$cli -LDGetNum -a $adapter -NoLog`; 35 | # Number of Virtual Drives Configured on Adapter 0: 3 36 | if ($number_of_lds=~ m/.*Number\sof\sVirtual\sDrives\sConfigured\son\sAdapter\s$adapter:\s(\d+)/) { 37 | $number_of_lds = $1; 38 | if ($number_of_lds == 0) { 39 | print "No virtual disks found on adapter $adapter\n"; 40 | next; 41 | } 42 | } 43 | 44 | open(ZSEND_FILE,">>$tmp_path") or die "Can't open $tmp_path: $!"; 45 | 46 | my $bbu_info = `$cli -AdpBbuCmd -GetBbuStatus -a $adapter -NoLog`; 47 | if (!($bbu_info =~ m/.*Get BBU Status Failed.*/)) { 48 | my @bbu_data = `$cli -AdpBBUCMD -a $adapter -NoLog`; 49 | 50 | foreach my $line (@bbu_data) { 51 | if ($line =~ m/Battery State\s*:\s(.*)$/) { 52 | my $bbu_state = 1; 53 | $bbu_state = 0 if ($1 =~ m/^(Optimal|Operational)$/); 54 | print ZSEND_FILE "- hw.raid.bbu[$adapter,\"bbu_state\"] \"$bbu_state\"\n"; 55 | } elsif (($line =~ m/(?:Relative|Absolute)\sState\sof\sCharge\s*:\s(\d+).*%/i)) { 56 | my $state_of_charge = $1; 57 | print ZSEND_FILE "- hw.raid.bbu[$adapter,\"state_of_charge\"] \"$state_of_charge\"\n"; 58 | } else { 59 | next; 60 | } 61 | } 62 | } 63 | 64 | my @vd_list = `$cli -LDinfo -Lall -a $adapter -NoLog`; 65 | my $check_next_line = -1; 66 | my $vdrive_id = -1; 67 | foreach my $line (@vd_list) { 68 | if ($line =~ m/^\s*Virtual\sDrive:\s(\d+)\s.*$/) { 69 | $vdrive_id = $1; 70 | $check_next_line = 1; 71 | } elsif (($line =~ m/^\s*State\s+:\s(.*)$/) && ($check_next_line != -1) && ($vdrive_id != -1)) { 72 | my $state = 1; 73 | $state = 0 if ($1 =~ m/^Optimal$/); 74 | print ZSEND_FILE "- hw.raid.logical_disk[$adapter,$vdrive_id,\"vd_state\"] \"$state\"\n"; 75 | $check_next_line = -1; 76 | $vdrive_id = -1; 77 | } else { 78 | next; 79 | } 80 | } 81 | 82 | my @pd_list = `$cli -pdlist -a $adapter -NoLog`; 83 | $check_next_line = 0; 84 | my $enclosure_id = -1; 85 | my $drive_id = -1; 86 | # Determine Slot Number for each drive on current enclosure 87 | foreach my $line (@pd_list) { 88 | if ($line =~ m/^Enclosure\sDevice\sID:\s(\d+)$/) { 89 | $enclosure_id = $1; 90 | $check_next_line = 1; 91 | } if ($line =~ m/^Enclosure\sDevice\sID:\sN\/A$/) { 92 | # This can happen, if embedded raid controller is in use, there are drives and logical disks, but no enclosures 93 | $enclosure_id = 2989; # 0xBAD, :( magic hack 94 | $check_next_line = 1; 95 | } elsif (($line =~ m/^Slot\sNumber:\s(\d+)$/) && $check_next_line && ($enclosure_id != -1)) { 96 | $drive_id = $1; 97 | $check_next_line = 1; 98 | } elsif (($line =~ m/^Media Error Count:\s(.*)/) && $check_next_line && ($drive_id != -1)) { 99 | my $media_errors = $1; 100 | print ZSEND_FILE "- hw.raid.physical_disk[$adapter,$enclosure_id,$drive_id,\"media_errors\"] \"$media_errors\"\n"; 101 | $check_next_line = 1; 102 | } elsif (($line =~ m/^Predictive Failure Count:\s(.*)/) && $check_next_line && ($drive_id != -1)) { 103 | my $predictive_errors = $1; 104 | print ZSEND_FILE "- hw.raid.physical_disk[$adapter,$enclosure_id,$drive_id,\"predictive_errors\"] \"$predictive_errors\"\n"; 105 | $check_next_line = 1; 106 | } elsif (($line =~ m/^Firmware state:\s(.*)/) && $check_next_line && ($drive_id != -1)) { 107 | my $firmware_state; 108 | if ($1 =~ m/^(Unconfigured\(good\).*|Online,\sSpun.*|Hotspare,\sSpun.*)$/) { 109 | $firmware_state = 0; 110 | } 111 | elsif ($1 =~ m/^Rebuild/) { 112 | $firmware_state = 2; 113 | } 114 | else { 115 | $firmware_state = 1; 116 | } 117 | print ZSEND_FILE "- hw.raid.physical_disk[$adapter,$enclosure_id,$drive_id,\"firmware_state\"] \"$firmware_state\"\n"; 118 | $check_next_line = 0; 119 | $drive_id = -1; 120 | $enclosure_id = -1; 121 | } else { 122 | next; 123 | } 124 | } 125 | close (ZSEND_FILE) or die "Can't close $tmp_path: $!"; 126 | } 127 | 128 | my @cmd_args = ($zabbix_sender,'-c',$zabbix_config,'-i',$tmp_path); 129 | system(@cmd_args); 130 | -------------------------------------------------------------------------------- /unix/raid_check.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | use strict; 4 | use warnings; 5 | use Getopt::Long; 6 | use Switch; 7 | 8 | my ($mode,$mode_item,$adapter,$enclosure_id,$disk_id,$vdisk_id); 9 | 10 | GetOptions ( 11 | "mode=s" => \$mode, 12 | "item=s" => \$mode_item, 13 | "adapter=i" => \$adapter, 14 | "enclosure:i" => \$enclosure_id, 15 | "pdisk:i" => \$disk_id, 16 | "vdisk:i" => \$vdisk_id 17 | ) or die("Error in command line arguments\n"); 18 | 19 | my $cli = '/usr/bin/sudo /opt/MegaRAID/CmdTool2/CmdTool2'; 20 | 21 | die("Mode is not defined. Use --mode paramater") if !defined $mode; 22 | die("Adapter is not defined. Use --adapter paramater") if !defined $adapter; 23 | 24 | switch ($mode) { 25 | case 'pdisk' { &pdisk_item(item=>$mode_item,adapter=>$adapter,enclosure=>$enclosure_id,disk=>$disk_id) } 26 | case 'vdisk' { &vdisk_item(item=>$mode_item,adapter=>$adapter,vd=>$vdisk_id) } 27 | case 'bbu' { &bbu_item(item=>$mode_item,adapter=>$adapter) } 28 | case 'adapter' { &adapter_item(item=>$mode_item,adapter=>$adapter) } 29 | else { die("Unknown mode, use pdisk, vdisk, bbu or adapter mode") } 30 | } 31 | 32 | sub pdisk_item() { 33 | my %options = @_; 34 | my $item = $options{item} if defined $options{item} or die("use --item to define which item should be checked"); 35 | my $enclosure = $options{enclosure} if defined $options{enclosure} or die("use --enclosure to define enclosure on adapter"); 36 | my $adapter = $options{adapter} if defined $options{adapter} or die("use --adapter to define which adapter should be checked"); 37 | my $disk = $options{disk} if defined $options{disk} or die("use --pdisk to define which physical disk should be checked"); 38 | 39 | my $regex = ''; 40 | my $item_found = 0; 41 | my $output = ''; 42 | 43 | switch ($item) { 44 | case 'firmware_state' { $regex = '^Firmware state:\s(.*)' } 45 | case 'raw_size' { $regex = '^Raw Size:\s+(\d+\.\d+\s..)' } 46 | case 'predictive_errors' { $regex = '^Predictive Failure Count:\s(.*)' } 47 | case 'inquiry_data' { $regex = '^Inquiry Data:\s+(.*)' } 48 | case 'media_errors' { $regex = '^Media Error Count:\s(.*)' } 49 | else { die("Unknown item $item for physical disk check") } 50 | } 51 | 52 | my @cli_output = `$cli -pdinfo -PhysDrv[$enclosure_id:$disk_id] -a $adapter -NoLog`; 53 | 54 | foreach my $line (@cli_output) { 55 | if ($line =~ $regex) { 56 | $output = $1; 57 | $item_found=1; 58 | last; 59 | } 60 | } 61 | if ($item_found) { 62 | if ($item eq 'firmware_state') { 63 | if ($output =~ m/^(Unconfigured\(good\).*|Online,\sSpun.*|Hotspare,\sSpun.*)$/) { 64 | $output = 0; 65 | } 66 | elsif ($output =~ m/^Rebuild/) { 67 | $output = 2; 68 | } 69 | else { 70 | $output = 1; 71 | } 72 | } 73 | print $output; 74 | } 75 | } 76 | 77 | sub vdisk_item() { 78 | my %options = @_; 79 | my $item = $options{item} if defined $options{item} or die("use --item to define which item should be checked"); 80 | my $adapter = $options{adapter} if defined $options{adapter} or die("use --adapter to define which adapter should be checked"); 81 | my $vd = $options{vd} if defined $options{vd} or die("use --vdisk to define which virtual disk should be checked"); 82 | my $item_found = 0; 83 | my $regex = ''; 84 | my $output = ''; 85 | 86 | switch ($item) { 87 | case 'vd_state' { $regex = '^State\s+:\s(.*)$' } 88 | case 'vd_size' { $regex = '^Size\s+:\s(\d+\.\d+\s..)' } 89 | else { die("Unknown item $item for virtual disk check") } 90 | } 91 | 92 | my @cli_output = `$cli -LDinfo -L $vd -a $adapter -NoLog`; 93 | 94 | foreach my $line (@cli_output) { 95 | if ($line =~ $regex) { 96 | $output = $1; 97 | $item_found = 1; 98 | last; 99 | } 100 | } 101 | if ($item_found) { 102 | if ($item eq 'vd_state') { if ($output =~ m/^Optimal$/) { $output = 0 } else { $output = 1 } } 103 | print $output; 104 | } 105 | } 106 | 107 | sub bbu_item() { 108 | my %options = @_; 109 | my $item = $options{item} if defined $options{item} or die("use --item to define which item should be checked"); 110 | my $adapter = $options{adapter} if defined $options{adapter} or die("use --adapter to define which adapter should be checked"); 111 | my $regex = ''; 112 | my $command = ''; 113 | my $output = ''; 114 | my $wanted_group = -1; 115 | my $item_found = 0; 116 | 117 | switch ($item) { 118 | case 'bbu_state' { $command = '-GetBbuStatus'; $regex = 'Battery State\s*:\s(.*)$'; $wanted_group = 1; } 119 | case 'design_capacity' { $command = '-GetBBUDesignInfo'; $regex = 'Design\sCapacity:\s(\d+)\smAh'; $wanted_group = 1; } 120 | case 'full_capacity' { $command = '-GetBBUCapacityInfo'; $regex = '(Full\sCharge\sCapacity|.*Pack\senergy\s*):\s(\d+)\s(mAh|J)'; $wanted_group = 2; } 121 | case 'state_of_charge' { $command = '-GetBBUCapacityInfo'; $regex = 'Absolute\sState\sof\scharge\s*:\s(\d+).*%'; $wanted_group = 1; } 122 | case 'date_manufactured' { $command = '-GetBBUDesignInfo'; $regex = 'Date\sof\sManufacture\s*:\s(.*)$'; $wanted_group = 1; } 123 | else { die("Unknown item $item for battery unit check") } 124 | } 125 | 126 | my @cli_output = `$cli -AdpBbuCmd $command -a $adapter -NoLog`; 127 | foreach my $line (@cli_output) { 128 | if ($line =~ $regex) { 129 | $output = $1 if $wanted_group == 1; 130 | $output = $2 if $wanted_group == 2; 131 | $item_found=1; 132 | last; 133 | } 134 | } 135 | if ($item_found) { 136 | if ($item eq 'bbu_state') { if ($output =~ m/^(Optimal|Operational)$/) { $output = 0 } else { $output = 1 } } 137 | print $output; 138 | } 139 | } 140 | 141 | sub adapter_item() { 142 | my %options = @_; 143 | my $item = $options{item} if defined $options{item} or die("use --item to define which item should be checked"); 144 | my $adapter = $options{adapter} if defined $options{adapter} or die("use --adapter to define which adapter should be checked"); 145 | my $regex = ''; 146 | my $item_found = 0; 147 | 148 | switch ($item) { 149 | case 'fw_version' { $regex = '^\s*FW\sPackage\sBuild:\s(.*)$' } 150 | case 'product_name' { $regex = '^\s*Product\sName\s*:\s(.*)$' } 151 | else { die("Unknown item $item for adapter check") } 152 | } 153 | 154 | my @cli_output = `$cli -AdpAllInfo -a $adapter -NoLog`; 155 | foreach my $line (@cli_output) { 156 | if ($line =~ $regex) { 157 | print $1; 158 | $item_found=1; 159 | last; 160 | } 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /windows/raid_discovery.ps1: -------------------------------------------------------------------------------- 1 | $CLI = 'C:\Program Files\zabbix_agent\conf.d\lsi_raid\MegaCli64.exe' 2 | $sender = 'C:\Program Files\zabbix_agent\zabbix_sender.exe' 3 | $agent_config = 'C:\Program Files\zabbix_agent\zabbix_agentd.win.conf' 4 | 5 | $number_of_adapters = [int](& $CLI -adpCount -NoLog | Select-String "Controller Count: (\d+)" -AllMatches | % {$_.Matches} | % {$_.groups[1].value}) 6 | $physical_drives = @{} 7 | $virtual_drives = @{} 8 | $battery_units = @{} 9 | $adapters = @{} 10 | for ($adapter = 0; $adapter -lt $number_of_adapters;$adapter++) { 11 | # check number of physical disks on this adapter 12 | $number_of_disks = [int](& $CLI -pdGetNum -a $adapter -NoLog | Select-String "Number of Physical Drives on Adapter $adapter\: (\d)" -AllMatches | % {$_.Matches} | % {$_.groups[1].value}) 13 | if ($number_of_disks -eq 0) { 14 | write-host "No physical disks found on adapter $adapter. Skipping this adapter" 15 | Continue 16 | } 17 | 18 | # check number of configured RAID volumes 19 | $number_of_lds = [int](& $CLI -LDGetNum -a $adapter -NoLog | Select-String "Number of Virtual Drives Configured on Adapter $adapter\:\s(\d+)" -AllMatches | % {$_.Matches} | % {$_.groups[1].value}) 20 | if ($number_of_lds -eq 0) { 21 | write-host "No virtual disks found on adapter $adapter. Skipping this adapter" 22 | Continue 23 | } 24 | 25 | # check IDs for configured RAID volumes (IDs could be sequential, or not) 26 | $tmp_file = Join-Path ${env:temp} "raid_vdrives-$(Get-Date -Format yyyy-MM-dd-HH-mm-ss).tmp" 27 | & $CLI -LDinfo -Lall -a $adapter -NoLog | Out-File $tmp_file 28 | [regex]$regex_vd_id = "^\s*Virtual\sDrive:\s(\d+)\s.*$" 29 | $reader = [System.IO.File]::OpenText($tmp_file) 30 | $vdrive_id = -1; 31 | try { 32 | for(;;) { 33 | $line = $reader.ReadLine() 34 | if ($line -eq $null) { break } 35 | if (($regex_vd_id.isMatch($line)) -eq $True) { 36 | $vdrive_id = $regex_vd_id.Matches($line) | % {$_.groups[1].value} 37 | $virtual_drives.Add("$adapter-$vdrive_id","{ `"{#VDRIVE_ID}`":`"$vdrive_id`", `"{#ADAPTER_ID}`":`"$adapter`" }") 38 | } else { 39 | Continue 40 | } 41 | } 42 | } 43 | finally { 44 | $reader.Close() 45 | } 46 | remove-item $tmp_file 47 | 48 | # List Battery unit 49 | $bbu_is_missing = (& $CLI -AdpBbuCmd -GetBbuStatus -a $adapter -NoLog | Select-String ".*Get BBU Status Failed.*" | % {$_.Matches}) 50 | if (!$bbu_is_missing) { 51 | $battery_units.Add($adapter,"{ `"{#ADAPTER_ID}`":`"$adapter`" }") 52 | } 53 | 54 | # List physical drives 55 | $enclosure_number = [int](& $CLI -EncInfo -a $adapter -NoLog | Select-String "Number of enclosures on adapter $adapter -- (\d)" -AllMatches | % {$_.Matches} | % {$_.groups[1].value}) 56 | $enclosures = @{} 57 | if (($enclosure_number -eq 0) -and ($number_of_disks -eq 0)) { 58 | write-host "No enclosures/drives detected, skipping adapter" 59 | Continue 60 | } else { 61 | # Detected enclosure (or no enclosure, but drives), try to add current adapter to adapters list 62 | if (!($adapters.ContainsKey($adapter))) { 63 | $adapters.Add($adapter,"{ `"{#ADAPTER_ID}`":`"$adapter`" }") 64 | } 65 | # ======== 66 | # List all physical drives 67 | # ======== 68 | $check_next_line = 0 69 | [regex]$regex_enc = "^\s*Enclosure\sDevice\sID:\s(\d+)$" 70 | [regex]$regex_enc_na = "^\s*Enclosure\sDevice\sID:\sN\/A$" 71 | [regex]$regex_slot = "^\s*Slot\sNumber:\s(\d+)$" 72 | 73 | $tmp_file = Join-Path ${env:temp} "raid_enclosures-$(Get-Date -Format yyyy-MM-dd-HH-mm-ss).tmp" 74 | & $CLI -pdlist -a $adapter -NoLog | Out-File $tmp_file 75 | $reader = [System.IO.File]::OpenText($tmp_file) 76 | 77 | # Determine Slot Number for each drive on enclosure 78 | $enclosure_id = -1; 79 | try { 80 | for(;;) { 81 | $line = $reader.ReadLine() 82 | if ($line -eq $null) { break } 83 | # Line contains enc id, next line is slot id 84 | if (($regex_enc.isMatch($line)) -eq $True) { 85 | $enclosure_id = $regex_enc.Matches($line) | % {$_.groups[1].value} 86 | $check_next_line = 1 87 | } elseif (($regex_enc_na.isMatch($line)) -eq $True) { 88 | # This can happen, if embedded raid controller is in use, there are drives and logical disks, but no enclosures 89 | $enclosure_id = 2989 # 0xBAD, :( magic hack 90 | $check_next_line = 1 91 | } elseif ((($regex_slot.isMatch($line)) -eq $True) -and ($check_next_line -eq 1) -and ($enclosure_id -ne -1)) { 92 | $drive_id = $regex_slot.Matches($line) | % {$_.groups[1].value} 93 | $physical_drives.Add("$adapter-$enclosure_id-$drive_id","{ `"{#ENCLOSURE_ID}`":`"$enclosure_id`", `"{#PDRIVE_ID}`":`"$drive_id`", `"{#ADAPTER_ID}`":`"$adapter`" }") 94 | $check_next_line = 0 95 | $enclosure_id = -1 96 | } else { 97 | Continue 98 | } 99 | } 100 | } 101 | finally { 102 | $reader.Close() 103 | } 104 | remove-item $tmp_file 105 | } 106 | } 107 | 108 | # create file with json 109 | $zsend_data = Join-Path $(Split-Path -Parent $CLI) 'zsend_data.txt' 110 | 111 | if (($physical_drives.Count -ne 0) -and ($virtual_drives.Count -ne 0)) { 112 | $writer = new-object io.streamwriter($zsend_data,$False) 113 | $i = 1 114 | $writer.Write('- hw.raid.discovery.pdisks { "data":[') 115 | foreach ($physical_drive in $physical_drives.Keys) { 116 | if ($i -lt $physical_drives.Count) { 117 | $string = "$($physical_drives.Item($physical_drive))," 118 | } else { 119 | $string = "$($physical_drives.Item($physical_drive)) ]}" 120 | } 121 | $i++ 122 | $writer.Write($string) 123 | } 124 | $writer.WriteLine('') 125 | $writer.Write('- hw.raid.discovery.vdisks { "data":[') 126 | $i = 1 127 | foreach ($virtual_drive in $virtual_drives.Keys) { 128 | if ($i -lt $virtual_drives.Count) { 129 | $string = "$($virtual_drives.Item($virtual_drive))," 130 | } else { 131 | $string = "$($virtual_drives.Item($virtual_drive)) ]}" 132 | } 133 | $i++ 134 | $writer.Write($string) 135 | } 136 | $i = 1 137 | if ($battery_units.Count -ne 0) { 138 | $writer.WriteLine('') 139 | $writer.Write('- hw.raid.discovery.bbu { "data":[') 140 | foreach ($battery_unit in $battery_units.Keys) { 141 | if ($i -lt $battery_units.Count) { 142 | $string = "$($battery_units.Item($battery_unit))," 143 | } else { 144 | $string = "$($battery_units.Item($battery_unit)) ]}" 145 | } 146 | $i++ 147 | $writer.Write($string) 148 | } 149 | } 150 | $i = 1 151 | if ($adapters.Count -ne 0) { 152 | $writer.WriteLine('') 153 | $writer.Write('- hw.raid.discovery.adapters { "data":[') 154 | foreach ($adapter in $adapters.Keys) { 155 | if ($i -lt $adapters.Count) { 156 | $string = "$($adapters.Item($adapter))," 157 | } else { 158 | $string = "$($adapters.Item($adapter)) ]}" 159 | } 160 | $i++ 161 | $writer.Write($string) 162 | } 163 | } 164 | $writer.WriteLine('') 165 | $writer.Close() 166 | } 167 | 168 | & $sender -c $agent_config -i $zsend_data -------------------------------------------------------------------------------- /windows/raid_trapper_checks.ps1: -------------------------------------------------------------------------------- 1 | $CLI = 'C:\Program Files\zabbix_agent\scripts\hw.raid\CmdTool2_64.exe' 2 | $sender = 'C:\Program Files\zabbix_agent\zabbix_sender.exe' 3 | $agent_config = 'C:\Program Files\zabbix_agent\zabbix_agentd.win.conf' 4 | 5 | $number_of_adapters = [int](& $CLI -adpCount -NoLog | Select-String "Controller Count: (\d+)" -AllMatches | % {$_.Matches} | % {$_.groups[1].value}) 6 | $physical_drives = @() 7 | $virtual_drives = @() 8 | $zsend_data = Join-Path $(Split-Path -Parent $CLI) 'zsend_trapper_data.txt' 9 | 10 | if (Test-Path $zsend_data) { remove-item $zsend_data } 11 | 12 | for ($adapter = 0; $adapter -lt $number_of_adapters;$adapter++) { 13 | # check number of physical disks on this adapter 14 | $number_of_disks = [int](& $CLI -pdGetNum -a $adapter -NoLog | Select-String "Number of Physical Drives on Adapter $adapter\: (\d)" -AllMatches | % {$_.Matches} | % {$_.groups[1].value}) 15 | if ($number_of_disks -eq 0) { 16 | write-host "No physical disks found on adapter $adapter. Skipping this adapter" 17 | Continue 18 | } 19 | 20 | # check number of configured RAID volumes 21 | $number_of_lds = [int](& $CLI -LDGetNum -a $adapter -NoLog | Select-String "Number of Virtual Drives Configured on Adapter $adapter\:\s(\d+)" -AllMatches | % {$_.Matches} | % {$_.groups[1].value}) 22 | if ($number_of_lds -eq 0) { 23 | write-host "No virtual disks found on adapter $adapter. Skipping this adapter" 24 | Continue 25 | } 26 | 27 | # List Battery unit 28 | $bbu_is_missing = (& $CLI -AdpBbuCmd -GetBbuStatus -a $adapter -NoLog | Select-String ".*Get BBU Status Failed.*" | % {$_.Matches}) 29 | if (!$bbu_is_missing) { 30 | $tmp_file = Join-Path ${env:temp} "raid_bbu-$(Get-Date -Format yyyy-MM-dd-HH-mm-ss).tmp" 31 | & $CLI -AdpBBUCMD -a $adapter -NoLog | Out-File $tmp_file 32 | $reader = [System.IO.File]::OpenText($tmp_file) 33 | [regex]$regex_bbu_state = "Battery State\s*:\s(.*)$" 34 | [regex]$regex_state_of_charge = "Absolute\sState\sof\scharge\s*:\s(\d+).*%" 35 | try { 36 | $writer = new-object io.streamwriter($zsend_data,$True) 37 | for(;;) { 38 | $line = $reader.ReadLine() 39 | if ($line -eq $null) { 40 | break 41 | } elseif (($regex_bbu_state.isMatch($line)) -eq $True) { 42 | $bbu_state = $regex_bbu_state.Matches($line) | % {$_.groups[1].value} 43 | if ($bbu_state -Match '^(Optimal|Operational)$') { $bbu_state = 0 } else { $bbu_state = 1 } 44 | $writer.WriteLine("- hw.raid.bbu[$adapter,`"bbu_state`"] `"$bbu_state`"") 45 | } elseif ((($regex_state_of_charge.isMatch($line)) -eq $True)) { 46 | $state_of_charge = $regex_state_of_charge.Matches($line) | % {$_.groups[1].value} 47 | $writer.WriteLine("- hw.raid.bbu[$adapter,`"state_of_charge`"] `"$state_of_charge`"") 48 | } else { Continue } 49 | } 50 | } 51 | finally { 52 | $reader.Close() 53 | $writer.Close() 54 | remove-item $tmp_file 55 | } 56 | } 57 | 58 | # List RAID Volumes and its states 59 | $tmp_file = Join-Path ${env:temp} "raid_vdrives-$(Get-Date -Format yyyy-MM-dd-HH-mm-ss).tmp" 60 | & $CLI -LDinfo -Lall -a $adapter -NoLog | Out-File $tmp_file 61 | [regex]$regex_vd_id = "^\s*Virtual\sDrive:\s(\d+)\s.*$" 62 | [regex]$regex_vd_state = "^\s*State\s+:\s(.*)$" 63 | $reader = [System.IO.File]::OpenText($tmp_file) 64 | $check_next_line = 0 65 | $vdrive_id = -1; 66 | try { 67 | $writer = new-object io.streamwriter($zsend_data,$True) 68 | for(;;) { 69 | $line = $reader.ReadLine() 70 | if ($line -eq $null) { break } 71 | if (($regex_vd_id.isMatch($line)) -eq $True) { 72 | $vdrive_id = $regex_vd_id.Matches($line) | % {$_.groups[1].value} 73 | $check_next_line = 1 74 | } elseif ((($regex_vd_state.isMatch($line)) -eq $True) -and ($check_next_line -eq 1) -and ($vdrive_id -ne -1)) { 75 | $state = $regex_vd_state.Matches($line) | % {$_.groups[1].value} 76 | if ($state -Match '^Optimal$') { $state = 0 } else { $state = 1 } 77 | $writer.WriteLine("- hw.raid.logical_disk[$adapter,$vdrive_id,`"vd_state`"] `"$state`"") 78 | $check_next_line = -1 79 | $vdrive_id = -1 80 | } else { 81 | Continue 82 | } 83 | } 84 | } 85 | finally { 86 | $reader.Close() 87 | $writer.Close() 88 | } 89 | remove-item $tmp_file 90 | 91 | # List physical drives 92 | $enclosure_number = [int](& $CLI -EncInfo -a $adapter -NoLog | Select-String "Number of enclosures on adapter $adapter -- (\d)" -AllMatches | % {$_.Matches} | % {$_.groups[1].value}) 93 | $enclosures = @{} 94 | if (($enclosure_number -eq 0) -and ($number_of_disks -eq 0)) { 95 | write-host "No enclosures/disks detected, skipping adapter" 96 | Continue 97 | } else { 98 | # ======== 99 | # List all physical drives and its states 100 | # ======== 101 | $tmp_file = Join-Path ${env:temp} "raid_enclosures-$(Get-Date -Format yyyy-MM-dd-HH-mm-ss).tmp" 102 | & $CLI -pdlist -a $adapter -NoLog | Out-File $tmp_file 103 | $reader = [System.IO.File]::OpenText($tmp_file) 104 | $check_next_line = 0 105 | [regex]$regex_enc = "^\s*Enclosure\sDevice\sID:\s(\d+)$" 106 | [regex]$regex_enc_na = "^\s*Enclosure\sDevice\sID:\sN\/A$" 107 | [regex]$regex_slot = "^\s*Slot\sNumber:\s(\d+)$" 108 | [regex]$regex_media_errors = "Media Error Count:\s(.*)" 109 | [regex]$regex_predictive_errors = "Predictive Failure Count:\s(.*)" 110 | [regex]$regex_firmware_state = "Firmware state:\s(.*)" 111 | # Determine Slot Number for each drive on enclosure 112 | $enclosure_id = -1; 113 | $drive_id = -1 114 | try { 115 | $writer = new-object io.streamwriter($zsend_data,$True) 116 | for(;;) { 117 | $line = $reader.ReadLine() 118 | if ($line -eq $null) { break } 119 | # Line contains enc id, next line is slot id 120 | if (($regex_enc.isMatch($line)) -eq $True) { 121 | $enclosure_id = $regex_enc.Matches($line) | % {$_.groups[1].value} 122 | $check_next_line = 1 123 | } elseif (($regex_enc_na.isMatch($line)) -eq $True) { 124 | # This can happen, if embedded raid controller is use, there are drives and logical disks, but no enclosures 125 | $enclosure_id = 2989 # 0xBAD, :( magic hack 126 | $check_next_line = 1 127 | } elseif ((($regex_slot.isMatch($line)) -eq $True) -and ($check_next_line -eq 1) -and ($enclosure_id -ne -1)) { 128 | $drive_id = $regex_slot.Matches($line) | % {$_.groups[1].value} 129 | $check_next_line = 1 130 | } elseif ( 131 | ($check_next_line -eq 1) -and 132 | ($drive_id -ne -1) -and 133 | ($enclosure_id -ne -1) -and 134 | (($regex_media_errors.isMatch($line)) -eq $True) 135 | ) { 136 | $media_errors = $regex_media_errors.Matches($line) | % {$_.groups[1].value} 137 | $writer.WriteLine("- hw.raid.physical_disk[$adapter,$enclosure_id,$drive_id,`"media_errors`"] $media_errors") 138 | $check_next_line = 1 139 | } elseif ( 140 | ($check_next_line -eq 1) -and 141 | ($drive_id -ne -1) -and 142 | ($enclosure_id -ne -1) -and 143 | (($regex_predictive_errors.isMatch($line)) -eq $True) 144 | ) { 145 | $predictive_errors = $regex_predictive_errors.Matches($line) | % {$_.groups[1].value} 146 | $writer.WriteLine("- hw.raid.physical_disk[$adapter,$enclosure_id,$drive_id,`"predictive_errors`"] $predictive_errors") 147 | $check_next_line = 1 148 | } elseif ( 149 | ($check_next_line -eq 1) -and 150 | ($drive_id -ne -1) -and 151 | ($enclosure_id -ne -1) -and 152 | (($regex_firmware_state.isMatch($line)) -eq $True) 153 | ) { 154 | $firmware_state = $regex_firmware_state.Matches($line) | % {$_.groups[1].value} 155 | if ($firmware_state -match '^(Unconfigured\(good\).*|Online,\sSpun.*|Hotspare,\sSpun.*)$') { 156 | $firmware_state = 0 157 | } 158 | elseif ($firmware_state -match '^Rebuild') { 159 | $firmware_state = 2 160 | } 161 | else { 162 | $firmware_state = 1 163 | } 164 | $writer.WriteLine("- hw.raid.physical_disk[$adapter,$enclosure_id,$drive_id,`"firmware_state`"] `"$firmware_state`"") 165 | $check_next_line = 1 166 | } else { Continue } 167 | } 168 | } 169 | finally { 170 | $reader.Close() 171 | $writer.Close() 172 | } 173 | remove-item $tmp_file 174 | } 175 | } 176 | 177 | & $sender -c $agent_config -i $zsend_data 178 | -------------------------------------------------------------------------------- /template/LSI_RAID_template.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 2.0 4 | 2014-02-10T14:00:39Z 5 | 6 | 7 | Templates 8 | 9 | 10 | 11 | 859 | 860 | 861 | --------------------------------------------------------------------------------