99import protobix
1010import redis
1111
12- class RedisServer (object ):
12+ class RedisServer (protobix . SampleProbe ):
1313
14- __version__ = '0.0.8'
15- ZBX_CONN_ERR = "ERR - unable to send data to Zabbix [%s]"
14+ __version__ = '0.0.9'
1615
1716 REDIS_REPROLE_MAPPING = {'master' :1 ,'slave' :0 }
1817 REDIS_REPSTATE_MAPPING = {'up' :1 ,'down' :0 }
1918
20- def _parse_args (self ):
21- ''' Parse the script arguments
22- '''
23- parser = optparse .OptionParser ()
24-
25- parser .add_option ("-d" , "--dry" , action = "store_true" ,
26- help = "Performs Redis call but do not send "
27- "anything to the Zabbix server. Can be used "
28- "for both Update & Discovery mode" )
29- parser .add_option ("-D" , "--debug" , action = "store_true" ,
30- help = "Enable debug mode. This will prevent bulk send "
31- "operations and force sending items one after the "
32- "other, displaying result for each one" )
33- parser .add_option ("-v" , "--verbose" , action = "store_true" ,
34- help = "When used with debug option, will force value "
35- "display for each items managed. Beware that it "
36- "can be pretty too much verbose, specialy for LLD" )
19+ def _get_data_from_dict (self , result , prefix ):
20+ data = {}
21+ for key , value in result .iteritems ():
22+ if isinstance (value , dict ):
23+ data .update (
24+ self ._get_data_from_dict (value , "%s%s," % (prefix , key ))
25+ )
26+ else :
27+ data .update ({ "%s%s]" % (prefix , key ): value })
28+ return data
3729
38- mode_group = optparse .OptionGroup (parser , "Program Mode" )
39- mode_group .add_option ("--update-items" , action = "store_const" ,
40- dest = "mode" , const = "update_items" ,
41- help = "Get & send items to Zabbix. This is the default "
42- "behaviour even if option is not specified" )
43- mode_group .add_option ("--discovery" , action = "store_const" ,
44- dest = "mode" , const = "discovery" ,
45- help = "If specified, will perform Zabbix Low Level "
46- "Discovery on Redis. "
47- "Default is to get & send items" )
48- parser .add_option_group (mode_group )
49- parser .set_defaults (mode = "update_items" )
30+ def _parse_args (self ):
31+ # Parse the script arguments
32+ # Common part
33+ parser = super ( RedisServer , self )._parse_args ()
5034
5135 general_options = optparse .OptionGroup (parser , "Redis Configuration" )
5236 general_options .add_option ("-H" , "--host" , metavar = "HOST" , default = "localhost" ,
5337 help = "Redis server hostname" )
54- general_options .add_option ("-p " , "--port" , help = "Redis server port" ,
55- default = 6379 )
38+ general_options .add_option ("-P " , "--port" , default = 6379 ,
39+ help = "Redis server port" )
5640 parser .add_option_group (general_options )
5741
58- polling_options = optparse .OptionGroup (parser , "Zabbix configuration" )
59- polling_options .add_option ("--zabbix-server" , metavar = "HOST" ,
60- default = "localhost" ,
61- help = "The hostname of Zabbix server or "
62- "proxy, default is localhost." )
63- polling_options .add_option ("--zabbix-port" , metavar = "PORT" , default = 10051 ,
64- help = "The port on which the Zabbix server or "
65- "proxy is running, default is 10051." )
66- parser .add_option_group (polling_options )
42+ (options , args ) = parser .parse_args ()
43+ return (options , args )
6744
68- return parser .parse_args ()
45+ def _init_probe (self ):
46+ if self .options .host == 'localhost' :
47+ hostname = socket .getfqdn ()
48+ else :
49+ hostname = self .options .host
50+ self .redis = redis .StrictRedis (
51+ host = self .options .host ,
52+ port = self .options .port ,
53+ db = "" ,
54+ password = "" ,
55+ socket_timeout = 1
56+ )
6957
7058 def _get_discovery (self , hostname ):
7159 """ Discover 'dynamic' items like
@@ -75,16 +63,17 @@ def _get_discovery(self, hostname):
7563 keyspace: depends on database number
7664 """
7765 data = {}
78- data [hostname ] = {}
7966 section_list = { 'keyspace' : 'REDISDB' }
80- data [ hostname ] = { "redis.cluster.discovery" :[] }
67+ data = { "redis.cluster.discovery" :[] }
8168 for section , lldvalue in section_list .iteritems ():
82- data [hostname ][ "redis.%s.discovery" % section ] = []
69+ data ["redis.%s.discovery" % section ] = []
8370 result = self .redis .info (section )
71+ print result
72+ if result == {}: result = {}
8473 for key , value in result .iteritems ():
8574 dsc_data = {"{#%s}" % lldvalue : "%s" % key }
86- data [hostname ][ ("redis.%s.discovery" % (section ))].append (dsc_data )
87- return data
75+ data [("redis.%s.discovery" % (section ))].append (dsc_data )
76+ return { hostname : data }
8877
8978 def _get_metrics (self , hostname ):
9079 """ http://redis.io/commands/info
@@ -100,99 +89,21 @@ def _get_metrics(self, hostname):
10089 keyspace: Database related statistics
10190 """
10291 data = {}
103- data [hostname ] = {}
10492 section_list = [ 'server' , 'clients' , 'memory' , 'persistence' ,
10593 'stats' , 'replication' , 'cpu' , 'cluster' , 'keyspace' ]
10694 for section in section_list :
10795 result = self .redis .info (section )
108- data [hostname ].update (self ._get_data_from_dict (result , ("redis.%s[" % section )))
109- return data
110-
111- def _get_data_from_dict (self , result , prefix ):
112- data = {}
113- for key , value in result .iteritems ():
114- if isinstance (value , dict ):
115- data .update (self ._get_data_from_dict (value , "%s%s," % (prefix , key )))
116- else :
117- data .update ({ "%s%s]" % (prefix , key ): value })
118- return data
119-
120- def _init_container (self ):
121- zbx_container = protobix .DataContainer (
122- data_type = 'items' ,
123- zbx_host = self .options .zabbix_server ,
124- zbx_port = int (self .options .zabbix_port ),
125- debug = self .options .debug ,
126- dryrun = self .options .dry
127- )
128- return zbx_container
129-
130- def run (self ):
131- (self .options , args ) = self ._parse_args ()
132- if self .options .host == 'localhost' :
133- hostname = socket .getfqdn ()
134- else :
135- hostname = self .options .host
136-
137- # Step 1: init container
138- try :
139- zbx_container = self ._init_container ()
140- except :
141- return 1
142-
143- # Step 2: get data
144- try :
145- self .redis = redis .StrictRedis (
146- host = self .options .host ,
147- port = self .options .port ,
148- db = "" ,
149- password = "" ,
150- socket_timeout = 1
96+ data .update (
97+ self ._get_data_from_dict (result , ("redis.%s[" % section ))
15198 )
152- if self .options .mode == "update_items" :
153- zbx_container .set_type ("items" )
154- data = self ._get_metrics (hostname )
155- '''
156- do value mapping to avoid text itms
157- '''
158- #key = 'redis.replication[role]'
159- #data[hostname][key] = \
160- # self.REDIS_REPROLE_MAPPING[data[hostname][key]]
161- #key = 'redis.replication[master_link_status]'
162- #data[hostname][key] = \
163- # self.REDIS_REPSTATE_MAPPING[data[hostname][key]]
164- '''
165- provide fake data for master
166- to avoid NOT SUPPORTED items
167- '''
168- if data [hostname ]['redis.replication[role]' ] == 'master' :
169- data [hostname ]['redis.replication[master_last_io_seconds_ago]' ] = 0
170- data [hostname ]['redis.replication[master_link_status]' ] = 'up'
171- data [hostname ]['redis.replication[master_sync_in_progress]' ] = 0
172- zbx_container .add_item (hostname , "redis.zbx_version" , self .__version__ )
173- elif self .options .mode == "discovery" :
174- zbx_container .set_type ("lld" )
175- data = self ._get_discovery (hostname )
176- except :
177- return 2
178-
179- # Step 3: format & load data into container
180- try :
181- zbx_container .add (data )
182- except :
183- return 3
184-
185- # Step 4: send container data to Zabbix server
186- try :
187- zbx_container .send (zbx_container )
188- except protobix .SenderException as zbx_e :
189- if self .options .debug :
190- print self .ZBX_CONN_ERR % zbx_e .err_text
191- return 4
192- # Everything went fine. Let's return 0 and exit
193- return 0
99+ if data ['redis.replication[role]' ] == 'master' :
100+ data ['redis.replication[master_last_io_seconds_ago]' ] = 0
101+ data ['redis.replication[master_link_status]' ] = 'up'
102+ data ['redis.replication[master_sync_in_progress]' ] = 0
103+ data ['redis.zbx_version' ] = self .__version__
104+ return { hostname : data }
194105
195106if __name__ == '__main__' :
196107 ret = RedisServer ().run ()
197108 print ret
198- sys .exit (ret )
109+ sys .exit (ret )
0 commit comments