aboutsummaryrefslogtreecommitdiff
path: root/text_collector_examples
diff options
context:
space:
mode:
authorMatt Bostock <matt@mattbostock.com>2016-10-04 09:38:00 +0100
committerMatt Bostock <matt@mattbostock.com>2016-12-22 22:55:58 +0000
commit2c025710400b7d15b2b5dd4d7845423ec0caf823 (patch)
treec3cea797b4ac12016ecc435892a4dfc87b2c39ab /text_collector_examples
parent296d7fdd2e3bc48af436e733f029eaece8947d9a (diff)
downloadprometheus_node_collector-2c025710400b7d15b2b5dd4d7845423ec0caf823.tar.bz2
prometheus_node_collector-2c025710400b7d15b2b5dd4d7845423ec0caf823.tar.xz
prometheus_node_collector-2c025710400b7d15b2b5dd4d7845423ec0caf823.zip
Add StorCli text collector example script
Collect metrics from the StorCLI utility on the health of MegaRAID hardware RAID controllers and write them to stdout so that they can be used by the textfile collector. We parse the JSON output that StorCLI provides. Script must be run as root or with appropriate capabilities for storcli to access the RAID card. Designed to run under Python 2.7, using the system Python provided with many Linux distributions. The metrics look like this: mbostock@host:~$ sudo ./storcli.py megaraid_status_code 0 megaraid_controllers_count 1 megaraid_emergency_hot_spare{controller="0"} 1 megaraid_scheduled_patrol_read{controller="0"} 1 megaraid_virtual_drives{controller="0"} 1 megaraid_drive_groups{controller="0"} 1 megaraid_virtual_drives_optimal{controller="0"} 1 megaraid_degraded{controller="0"} 0 megaraid_battery_backup_healthy{controller="0"} 1 megaraid_ports{controller="0"} 8 megaraid_failed{controller="0"} 0 megaraid_drive_groups_optimal{controller="0"} 1 megaraid_healthy{controller="0"} 1 megaraid_physical_drives{controller="0"} 24 megaraid_controller_info{controller="0", model="AVAGOMegaRAIDSASPCIExpressROMB"} 1 mbostock@host:~$
Diffstat (limited to 'text_collector_examples')
-rwxr-xr-xtext_collector_examples/storcli.py101
1 files changed, 101 insertions, 0 deletions
diff --git a/text_collector_examples/storcli.py b/text_collector_examples/storcli.py
new file mode 100755
index 0000000..f1a8a60
--- /dev/null
+++ b/text_collector_examples/storcli.py
@@ -0,0 +1,101 @@
1#!/usr/bin/env python
2
3# Script to parse StorCLI's JSON output and expose
4# MegaRAID health as Prometheus metrics.
5#
6# Tested against StorCLI 'Ver 1.14.12 Nov 25, 2014'.
7#
8# StorCLI reference manual:
9# http://docs.avagotech.com/docs/12352476
10#
11# Advanced Software Options (ASO) not exposed as metrics currently.
12#
13# JSON key abbreviations used by StorCLI are documented in the standard command
14# output, i.e. when you omit the trailing 'J' from the command.
15
16import argparse
17import json
18import subprocess
19
20DESCRIPTION = """Parses StorCLI's JSON output and exposes MegaRAID health as
21 Prometheus metrics."""
22VERSION = '0.0.1'
23
24METRIC_PREFIX = 'megaraid_'
25METRIC_CONTROLLER_LABELS = '{{controller="{}", model="{}"}}'
26
27
28def main(args):
29 data = json.loads(get_storcli_json(args.storcli_path))
30
31 # It appears that the data we need will always be present in the first
32 # item in the Controllers array
33 status = data['Controllers'][0]
34
35 metrics = {
36 'status_code': status['Command Status']['Status Code'],
37 'controllers': status['Response Data']['Number of Controllers'],
38 }
39
40 for name, value in metrics.iteritems():
41 print("{}{} {}".format(METRIC_PREFIX, name, value))
42
43 controller_info = []
44 controller_metrics = {}
45 overview = []
46
47 try:
48 overview = status['Response Data']['System Overview']
49 except KeyError:
50 pass
51
52 for controller in overview:
53 controller_index = controller['Ctl']
54 model = controller['Model']
55 controller_info.append(METRIC_CONTROLLER_LABELS.format(controller_index, model))
56
57 controller_metrics = {
58 # FIXME: Parse dimmer switch options
59 # 'dimmer_switch': controller['DS'],
60
61 'battery_backup_healthy': int(controller['BBU'] == 'Opt'),
62 'degraded': int(controller['Hlth'] == 'Dgd'),
63 'drive_groups': controller['DGs'],
64 'emergency_hot_spare': int(controller['EHS'] == 'Y'),
65 'failed': int(controller['Hlth'] == 'Fld'),
66 'healthy': int(controller['Hlth'] == 'Opt'),
67 'physical_drives': controller['PDs'],
68 'ports': controller['Ports'],
69 'scheduled_patrol_read': int(controller['sPR'] == 'On'),
70 'virtual_drives': controller['VDs'],
71
72 # Reverse StorCLI's logic to make metrics consistent
73 'drive_groups_optimal': int(controller['DNOpt'] == 0),
74 'virtual_drives_optimal': int(controller['VNOpt'] == 0),
75 }
76
77 for name, value in controller_metrics.iteritems():
78 print('{}{}{{controller="{}"}} {}'.format(METRIC_PREFIX, name, controller_index, value))
79
80 for labels in controller_info:
81 print('{}{}{} {}'.format(METRIC_PREFIX, 'controller_info', labels, 1))
82
83
84def get_storcli_json(storcli_path):
85 storcli_cmd = [storcli_path, 'show', 'all', 'J']
86 proc = subprocess.Popen(storcli_cmd, stdout=subprocess.PIPE,
87 stderr=subprocess.PIPE)
88 return proc.communicate()[0]
89
90if __name__ == "__main__":
91 parser = argparse.ArgumentParser(description=DESCRIPTION,
92 formatter_class=argparse.ArgumentDefaultsHelpFormatter)
93 parser.add_argument('--storcli_path',
94 default='/opt/MegaRAID/storcli/storcli64',
95 help='path to StorCLi binary')
96 parser.add_argument('--version',
97 action='version',
98 version='%(prog)s {}'.format(VERSION))
99 args = parser.parse_args()
100
101 main(args)