├── 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 |
12 | Template LSI RAID
13 | Template LSI RAID (agent + trapper)
14 |
15 |
16 | Templates
17 |
18 |
19 |
20 |
21 | LSI RAID adapter
22 |
23 |
24 | LSI RAID BBU
25 |
26 |
27 | LSI RAID Logical Volume
28 |
29 |
30 | LSI RAID Physical Volume
31 |
32 |
33 |
34 |
35 |
36 | RAID discovery adapters
37 | 2
38 |
39 |
40 | hw.raid.discovery.adapters
41 | 0
42 | 0
43 |
44 |
45 |
46 | 0
47 | 0
48 |
49 | 0
50 |
51 |
52 |
53 |
54 | 0
55 |
56 |
57 |
58 |
59 |
60 | :
61 | 30
62 |
63 |
64 |
65 | Adapter {#ADAPTER_ID} firmware
66 | 0
67 |
68 | 0
69 |
70 | hw.raid.adapter[{#ADAPTER_ID},"fw_version"]
71 | 86400
72 | 7
73 | 365
74 | 0
75 | 1
76 |
77 |
78 | 0
79 |
80 |
81 | 0
82 | 0
83 |
84 | 0
85 |
86 | 1
87 |
88 |
89 |
90 | 0
91 | 0
92 |
93 |
94 |
95 |
96 |
97 |
98 | 0
99 |
100 |
101 | LSI RAID adapter
102 |
103 |
104 |
105 |
106 |
107 |
108 | Adapter {#ADAPTER_ID} model
109 | 0
110 |
111 | 0
112 |
113 | hw.raid.adapter[{#ADAPTER_ID},"product_name"]
114 | 86400
115 | 7
116 | 365
117 | 0
118 | 1
119 |
120 |
121 | 0
122 |
123 |
124 | 0
125 | 0
126 |
127 | 0
128 |
129 | 1
130 |
131 |
132 |
133 | 0
134 | 0
135 |
136 |
137 |
138 |
139 |
140 |
141 | 0
142 |
143 |
144 | LSI RAID adapter
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 | RAID discovery bbu
157 | 2
158 |
159 |
160 | hw.raid.discovery.bbu
161 | 0
162 | 0
163 |
164 |
165 |
166 | 0
167 | 0
168 |
169 | 0
170 |
171 |
172 |
173 |
174 | 0
175 |
176 |
177 |
178 |
179 |
180 | :
181 | 30
182 |
183 |
184 |
185 | BBU current capacity on adapter:{#ADAPTER_ID}
186 | 0
187 |
188 | 0
189 |
190 | hw.raid.bbu[{#ADAPTER_ID},"full_capacity"]
191 | 300
192 | 7
193 | 365
194 | 1
195 | 3
196 |
197 |
198 | 0
199 |
200 |
201 | 0
202 | 0
203 |
204 | 0
205 |
206 | 1
207 |
208 |
209 |
210 | 0
211 | 0
212 |
213 |
214 |
215 |
216 |
217 |
218 | 0
219 |
220 |
221 | LSI RAID BBU
222 |
223 |
224 |
225 |
226 |
227 |
228 | BBU design capacity on adapter:{#ADAPTER_ID}
229 | 0
230 |
231 | 0
232 |
233 | hw.raid.bbu[{#ADAPTER_ID},"design_capacity"]
234 | 86400
235 | 1
236 | 365
237 | 1
238 | 3
239 |
240 |
241 | 0
242 |
243 |
244 | 0
245 | 0
246 |
247 | 0
248 |
249 | 1
250 |
251 |
252 |
253 | 0
254 | 0
255 |
256 |
257 |
258 |
259 |
260 |
261 | 0
262 |
263 |
264 | LSI RAID BBU
265 |
266 |
267 |
268 |
269 |
270 |
271 | BBU on adapter {#ADAPTER_ID}:manufacture date
272 | 0
273 |
274 | 0
275 |
276 | hw.raid.bbu[{#ADAPTER_ID},"date_manufactured"]
277 | 86400
278 | 7
279 | 365
280 | 1
281 | 1
282 |
283 |
284 | 0
285 |
286 |
287 | 0
288 | 0
289 |
290 | 0
291 |
292 | 1
293 |
294 |
295 |
296 | 0
297 | 0
298 |
299 |
300 |
301 |
302 |
303 |
304 | 0
305 |
306 |
307 | LSI RAID BBU
308 |
309 |
310 |
311 |
312 |
313 |
314 | BBU state of charge on adapter:{#ADAPTER_ID}
315 | 2
316 |
317 | 0
318 |
319 | hw.raid.bbu[{#ADAPTER_ID},"state_of_charge"]
320 | 0
321 | 7
322 | 365
323 | 0
324 | 3
325 |
326 | %
327 | 0
328 |
329 |
330 | 0
331 | 0
332 |
333 | 0
334 |
335 | 1
336 |
337 |
338 |
339 | 0
340 | 0
341 |
342 |
343 |
344 |
345 |
346 |
347 | 0
348 |
349 |
350 | LSI RAID BBU
351 |
352 |
353 |
354 |
355 |
356 |
357 | BBU state on adapter:{#ADAPTER_ID}
358 | 2
359 |
360 | 0
361 |
362 | hw.raid.bbu[{#ADAPTER_ID},"bbu_state"]
363 | 0
364 | 7
365 | 365
366 | 0
367 | 3
368 |
369 |
370 | 0
371 |
372 |
373 | 0
374 | 0
375 |
376 | 0
377 |
378 | 1
379 |
380 |
381 |
382 | 0
383 | 0
384 |
385 |
386 |
387 |
388 |
389 |
390 | 0
391 |
392 |
393 | LSI RAID BBU
394 |
395 |
396 |
397 | LSI RAID BBU & LD Status
398 |
399 |
400 |
401 |
402 |
403 |
404 | {Template LSI RAID:hw.raid.bbu[{#ADAPTER_ID},"bbu_state"].last()}=1
405 | BBU is not in optimal state on adapter:{#ADAPTER_ID}
406 |
407 | 0
408 | 4
409 | Backup Battery Unit on RAID adapter is not in operational state. RAID volumes performance can be degraded
410 | 0
411 |
412 |
413 | {Template LSI RAID:hw.raid.bbu[{#ADAPTER_ID},"state_of_charge"].avg(#3)}<55
414 | BBU on adapter:{#ADAPTER_ID} charge capacity degraded
415 |
416 | 0
417 | 2
418 |
419 | 0
420 |
421 |
422 | {Template LSI RAID:hw.raid.bbu[{#ADAPTER_ID},"bbu_state"].nodata(720)}=1
423 | RAID info is outdated on {HOST.NAME}
424 |
425 | 0
426 | 5
427 | RAID INFO not updated more than 10 minutes. Check task scheduler on host and connectivity
428 | 0
429 |
430 |
431 |
432 |
433 |
434 |
435 | RAID discovery pdisks
436 | 2
437 |
438 |
439 | hw.raid.discovery.pdisks
440 | 0
441 | 0
442 |
443 |
444 |
445 | 0
446 | 0
447 |
448 | 0
449 |
450 |
451 |
452 |
453 | 0
454 |
455 |
456 |
457 |
458 |
459 | :
460 | 30
461 |
462 |
463 |
464 | Disk Media errors Adapter:{#ADAPTER_ID},ENC:{#ENCLOSURE_ID},Disk:{#PDRIVE_ID}
465 | 2
466 |
467 | 0
468 |
469 | hw.raid.physical_disk[{#ADAPTER_ID},{#ENCLOSURE_ID},{#PDRIVE_ID},"media_errors"]
470 | 0
471 | 7
472 | 365
473 | 0
474 | 3
475 |
476 |
477 | 0
478 |
479 |
480 | 0
481 | 0
482 |
483 | 0
484 |
485 | 1
486 |
487 |
488 |
489 | 0
490 | 0
491 |
492 |
493 |
494 |
495 |
496 |
497 | 0
498 |
499 |
500 | LSI RAID Physical Volume
501 |
502 |
503 |
504 |
505 |
506 |
507 | Disk model Adapter:{#ADAPTER_ID},ENC:{#ENCLOSURE_ID},Disk:{#PDRIVE_ID}
508 | 0
509 |
510 | 0
511 |
512 | hw.raid.physical_disk[{#ADAPTER_ID},{#ENCLOSURE_ID},{#PDRIVE_ID},"inquiry_data"]
513 | 86400
514 | 7
515 | 365
516 | 0
517 | 4
518 |
519 |
520 | 0
521 |
522 |
523 | 0
524 | 0
525 |
526 | 0
527 |
528 | 1
529 |
530 |
531 |
532 | 0
533 | 0
534 |
535 |
536 |
537 |
538 |
539 |
540 | 0
541 |
542 |
543 | LSI RAID Physical Volume
544 |
545 |
546 |
547 |
548 |
549 |
550 | Disk predictive errors Adapter:{#ADAPTER_ID},ENC:{#ENCLOSURE_ID},Disk:{#PDRIVE_ID}
551 | 2
552 |
553 | 0
554 |
555 | hw.raid.physical_disk[{#ADAPTER_ID},{#ENCLOSURE_ID},{#PDRIVE_ID},"predictive_errors"]
556 | 0
557 | 7
558 | 365
559 | 0
560 | 3
561 |
562 |
563 | 0
564 |
565 |
566 | 0
567 | 0
568 |
569 | 0
570 |
571 | 1
572 |
573 |
574 |
575 | 0
576 | 0
577 |
578 |
579 |
580 |
581 |
582 |
583 | 0
584 |
585 |
586 | LSI RAID Physical Volume
587 |
588 |
589 |
590 |
591 |
592 |
593 | Disk size Adapter:{#ADAPTER_ID},ENC:{#ENCLOSURE_ID},Disk:{#PDRIVE_ID}
594 | 0
595 |
596 | 0
597 |
598 | hw.raid.physical_disk[{#ADAPTER_ID},{#ENCLOSURE_ID},{#PDRIVE_ID},"raw_size"]
599 | 86400
600 | 7
601 | 365
602 | 0
603 | 1
604 |
605 |
606 | 0
607 |
608 |
609 | 0
610 | 0
611 |
612 | 0
613 |
614 | 1
615 |
616 |
617 |
618 | 0
619 | 0
620 |
621 |
622 |
623 |
624 |
625 |
626 | 0
627 |
628 |
629 | LSI RAID Physical Volume
630 |
631 |
632 |
633 |
634 |
635 |
636 | Disk state Adapter:{#ADAPTER_ID},ENC:{#ENCLOSURE_ID},Disk:{#PDRIVE_ID}
637 | 2
638 |
639 | 0
640 |
641 | hw.raid.physical_disk[{#ADAPTER_ID},{#ENCLOSURE_ID},{#PDRIVE_ID},"firmware_state"]
642 | 0
643 | 7
644 | 365
645 | 0
646 | 3
647 |
648 |
649 | 0
650 |
651 |
652 | 0
653 | 0
654 |
655 | 0
656 |
657 | 1
658 |
659 |
660 |
661 | 0
662 | 0
663 |
664 |
665 |
666 |
667 |
668 |
669 | 0
670 |
671 |
672 | LSI RAID Physical Volume
673 |
674 |
675 |
676 | LSI RAID PhysDrv Status
677 |
678 |
679 |
680 |
681 |
682 |
683 | {Template LSI RAID:hw.raid.physical_disk[{#ADAPTER_ID},{#ENCLOSURE_ID},{#PDRIVE_ID},"media_errors"].last(0)}#0
684 | Disk have media errors Adapter:{#ADAPTER_ID},ENC:{#ENCLOSURE_ID},Disk:{#PDRIVE_ID}
685 |
686 | 0
687 | 2
688 |
689 | 0
690 |
691 |
692 | {Template LSI RAID:hw.raid.physical_disk[{#ADAPTER_ID},{#ENCLOSURE_ID},{#PDRIVE_ID},"predictive_errors"].last(0)}#0
693 | Disk have predictive errors Adapter:{#ADAPTER_ID},ENC:{#ENCLOSURE_ID},Disk:{#PDRIVE_ID}
694 |
695 | 0
696 | 2
697 |
698 | 0
699 |
700 |
701 | {Template LSI RAID:hw.raid.physical_disk[{#ADAPTER_ID},{#ENCLOSURE_ID},{#PDRIVE_ID},"firmware_state"].last()}=1
702 | Disk state Adapter:{#ADAPTER_ID},ENC:{#ENCLOSURE_ID},Disk:{#PDRIVE_ID} is not Optimal
703 |
704 | 0
705 | 4
706 |
707 | 0
708 |
709 |
710 | {Template LSI RAID:hw.raid.physical_disk[{#ADAPTER_ID},{#ENCLOSURE_ID},{#PDRIVE_ID},"firmware_state"].last()}=2
711 | Disk state Adapter:{#ADAPTER_ID},ENC:{#ENCLOSURE_ID},Disk:{#PDRIVE_ID} is Rebuild
712 |
713 | 0
714 | 2
715 |
716 | 0
717 |
718 |
719 |
720 |
721 |
722 |
723 | RAID discovery vdisks
724 | 2
725 |
726 |
727 | hw.raid.discovery.vdisks
728 | 0
729 | 0
730 |
731 |
732 |
733 | 0
734 | 0
735 |
736 | 0
737 |
738 |
739 |
740 |
741 | 0
742 |
743 |
744 |
745 |
746 |
747 | :
748 | 30
749 |
750 |
751 |
752 | RAID Volume size Adapter:{#ADAPTER_ID},ID:{#VDRIVE_ID}
753 | 0
754 |
755 | 0
756 |
757 | hw.raid.logical_disk[{#ADAPTER_ID},{#VDRIVE_ID},"vd_size"]
758 | 86400
759 | 7
760 | 365
761 | 0
762 | 4
763 |
764 |
765 | 0
766 |
767 |
768 | 0
769 | 0
770 |
771 | 0
772 |
773 | 1
774 |
775 |
776 |
777 | 0
778 | 0
779 |
780 |
781 |
782 |
783 |
784 |
785 | 0
786 |
787 |
788 | LSI RAID Logical Volume
789 |
790 |
791 |
792 |
793 |
794 |
795 | RAID Volume state Adapter:{#ADAPTER_ID},ID:{#VDRIVE_ID}
796 | 2
797 |
798 | 0
799 |
800 | hw.raid.logical_disk[{#ADAPTER_ID},{#VDRIVE_ID},"vd_state"]
801 | 0
802 | 7
803 | 365
804 | 0
805 | 3
806 |
807 |
808 | 0
809 |
810 |
811 | 0
812 | 0
813 |
814 | 0
815 |
816 | 1
817 |
818 |
819 |
820 | 0
821 | 0
822 |
823 |
824 |
825 |
826 |
827 |
828 | 0
829 |
830 |
831 | LSI RAID Logical Volume
832 |
833 |
834 |
835 | LSI RAID BBU & LD Status
836 |
837 |
838 |
839 |
840 |
841 |
842 | {Template LSI RAID:hw.raid.logical_disk[{#ADAPTER_ID},{#VDRIVE_ID},"vd_state"].last()}=1
843 | RAID Volume Adapter:{#ADAPTER_ID},ID:{#VDRIVE_ID} state is not Optimal
844 |
845 | 0
846 | 4
847 |
848 | 0
849 |
850 |
851 |
852 |
853 |
854 |
855 |
856 |
857 |
858 |
859 |
860 |
861 |
--------------------------------------------------------------------------------