def __init__(self, argv=(), env=None, debug=False):
        MuninPlugin.__init__(self, argv, env, debug)

        graphs = [
            ('supervisord_processes_memory_usage', 'Memory usage',
             'Memory usage', 'Memory usage (MiB)', 'LINE2', 'GAUGE', None),
            ('supervisord_processes_cpu_percent',
             'CPU utilization as a percentage',
             'CPU utilization as a percentage', 'CPU percentage', 'LINE2',
             'GAUGE', None),
            ('supervisord_processes_num_fds', 'File descriptors used',
             'File descriptors used', None, 'LINE2', 'GAUGE',
             '--lower-limit 0'),
            ('supervisord_processes_num_threads', 'Threads currently used',
             'Threads currently used', None, 'LINE2', 'GAUGE',
             '--lower-limit 0'),
            ('supervisord_processes_num_connections',
             'Socket connections opened', 'Socket connections opened', None,
             'LINE2', 'GAUGE', '--lower-limit 0')
        ]

        self._category = 'supervisord'
        transport = supervisor.xmlrpc.SupervisorTransport(
            None, None, serverurl=self.envGet('url'))
        proxy = xmlrpclib.ServerProxy('http://127.0.0.1', transport=transport)
        # print proxy.supervisor.getState()
        self.identity = '{0}_{1}'.format(proxy.supervisor.getIdentification(),
                                         proxy.supervisor.getPID())
        self.entries = proxy.supervisor.getAllProcessInfo()
        self._stats = defaultdict(dict)

        for (graph_name, graph_title, graph_info, graph_vlabel, graph_draw,
             graph_type, graph_args) in graphs:
            if self.graphEnabled(graph_name):
                graph = MuninGraph('Supervisord - {0}'.format(graph_title),
                                   self._category,
                                   info=graph_info,
                                   vlabel=graph_vlabel,
                                   args=graph_args)

                for entry in self.entries:
                    if entry['statename'] not in ('RUNNING', ):
                        continue

                    label_fmt = entry['group'] == entry[
                        'name'] and '{name}.{pid}' or '{group}:{name}'
                    graph.addField(
                        entry['name'],
                        label_fmt.format(**entry),
                        draw=graph_draw,
                        type=graph_type,
                        info=graph_info,
                        min=graph_name.startswith('supervisord_processes_num_')
                        and 0 or None)

                if graph.getFieldCount() > 0:
                    self.appendGraph(graph_name, graph)
示例#2
0
    def __init__(self, argv=(), env=None, debug=False):
        MuninPlugin.__init__(self, argv, env, debug)

        graphs = [
            ('supervisord_processes_memory_usage', 'Memory usage', 'Memory usage', 'Memory usage (MiB)', 'LINE2', 'GAUGE', None),
            ('supervisord_processes_cpu_percent_avg', 'CPU utilization as a percentage (avg)', 'CPU utilization as a percentage (avg)', 'Avg CPU percentage', 'LINE2', 'GAUGE', None),
            ('supervisord_processes_cpu_percent_max', 'CPU utilization as a percentage (max)', 'CPU utilization as a percentage (max)', 'Max CPU percentage', 'LINE2', 'GAUGE', None),
            ('supervisord_processes_num_context_switches_involuntary', 'Context switches (involuntary)', 'Context switches (involuntary)', 'Involuntary context switches', 'LINE2', 'GAUGE', None),
            ('supervisord_processes_num_context_switches_voluntary', 'Context switches (voluntary)', 'Context switches (voluntary)', 'Voluntary context switches', 'LINE2', 'GAUGE', None),
            ('supervisord_processes_num_fds', 'File descriptors used', 'File descriptors used', None, 'LINE2', 'GAUGE', '--lower-limit 0'),
            ('supervisord_processes_num_threads', 'Threads currently used', 'Threads currently used', None, 'LINE2', 'GAUGE', '--lower-limit 0'),
            ('supervisord_processes_num_connections', 'Socket connections opened', 'Socket connections opened', None, 'LINE2', 'GAUGE', '--lower-limit 0')
        ]

        self._category = 'supervisord'
        transport = supervisor.xmlrpc.SupervisorTransport(None, None, serverurl=self.envGet('url'))
        proxy = xmlrpclib.ServerProxy('http://127.0.0.1', transport=transport)
        # print proxy.supervisor.getState()
        self.identity = '{0}_{1}'.format(proxy.supervisor.getIdentification(), proxy.supervisor.getPID())
        self.entries = proxy.supervisor.getAllProcessInfo()
        self._stats = defaultdict(dict)

        for (graph_name, graph_title, graph_info, graph_vlabel, graph_draw, graph_type, graph_args) in graphs:
            if self.graphEnabled(graph_name):
                graph = MuninGraph('Supervisord - {0}'.format(graph_title),
                                   self._category, info=graph_info, vlabel=graph_vlabel, args=graph_args)

                for entry in self.entries:
                    if entry['statename'] not in ('RUNNING',):
                        continue

                    label_fmt = entry['group'] == entry['name'] and '{name}.{pid}' or '{group}:{name}'
                    graph.addField(entry['name'],
                                   label_fmt.format(**entry), draw=graph_draw,
                                   type=graph_type, info=graph_info,
                                   min=graph_name.startswith('supervisord_processes_num_') and 0 or None)

                if graph.getFieldCount() > 0:
                    self.appendGraph(graph_name, graph)
示例#3
0
    def __init__(self, argv=(), env=None, debug=False):
        """Populate Munin Plugin with MuninGraph instances.
        
        @param argv:  List of command line arguments.
        @param env:   Dictionary of environment variables.
        @param debug: Print debugging messages if True. (Default: False)
        
        """
        MuninPlugin.__init__(self, argv, env, debug)

        self._host = self.envGet('host')
        self._port = self.envGet('port')
        self._db = self.envGet('db')
        self._password = self.envGet('password')
        self._socket_timeout = self.envGet('socket_timeout', None, float)
        self._unix_socket_path = self.envGet('unix_socket_path')
        self._category = 'Redis'

        self._serverInfo = RedisInfo(self._host, self._port, self._db,
                                     self._password, self._socket_timeout,
                                     self._unix_socket_path)
        self._stats = self._serverInfo.getStats()
        self._stats['rtt'] = self._serverInfo.ping()

        cmd_list = []
        db_list = []
        for k in self._stats.keys():
            if k.startswith('cmdstat_'):
                cmd_list.append(k[len('cmdstat_'):])
            elif k.startswith('db'):
                db_list.append(k)
        db_list.sort()
        cmd_list.sort()
        graphs = [
            ('redis_ping', 'Ping Latency (secs)',
             'Round Trip Time in seconds for Redis Ping.',
             (('rtt', 'rtt', 'LINE2', 'GAUGE', 'Round trip time.'), )),
            ('redis_conn_client', 'Active Client Connections',
             'Number of connections to Redis Server.', (
                 ('connected_clients', 'clients', 'AREA', 'GAUGE',
                  'Number of clients connected to server.'),
                 ('blocked_clients', 'blocked', 'LINE2', 'GAUGE',
                  'Number of clients pending on a blocking call.'),
             )),
            ('redis_conn_rate', 'Client Connections per Sec',
             'Connections accepted / rejected per second by the Redis Server.',
             (
                 ('rejected_connections', 'reject', 'AREASTACK', 'DERIVE',
                  'Number of connections rejected by the server.'),
                 ('total_connections_received', 'accept', 'AREASTACK',
                  'DERIVE', 'Number of connections accepted by the server.'),
             )),
            ('redis_cmd_rate', 'Commands Processed per Sec',
             'Number of commands processed per second by the Redis Server.',
             (('total_commands_processed', 'cmds', 'LINE2', 'DERIVE',
               'Number of commands processed by the Redis Server.'), )),
            ('redis_memory', 'Memory Usage (bytes)',
             'Memory usage of Redis Server.', (
                 ('used_memory_rss', 'rss', 'AREASTACK', 'GAUGE',
                  'Resident Memory space (bytes) allocated to Redis by the OS for '
                  'storing data.'),
                 ('used_memory_lua', 'lua', 'AREASTACK', 'GAUGE',
                  'Memory space (bytes) used by the Lua Engine.'),
                 ('used_memory', 'mem', 'LINE2', 'GAUGE',
                  'Memory space (bytes) allocated by Redis Allocator for storing data.'
                  ),
             )),
            ('redis_memory_fragmentation', 'Memory Fragmentation Ratio',
             'Ratio between RSS and virtual memory use for Redis Server. '
             'Values much higher than 1 imply fragmentation. Values less '
             'than 1 imply that memory has been swapped out by OS.',
             (('mem_fragmentation_ratio', 'ratio', 'LINE2', 'GAUGE',
               'Ratio between RSS and virtual memory use.'), )),
            ('redis_cpu_util', 'CPU Utilization',
             'Processor time utilized by Redis Server.', (
                 ('used_cpu_sys', 'srv_sys', 'AREASTACK', 'DERIVE',
                  'System CPU Time consumed by the server.'),
                 ('used_cpu_user', 'srv_user', 'AREASTACK', 'DERIVE',
                  'User CPU Time consumed by the server.'),
                 ('used_cpu_sys_children', 'child_sys', 'AREASTACK', 'DERIVE',
                  'System CPU Time consumed by the background processes.'),
                 ('used_cpu_user_children', 'child_user', 'AREASTACK',
                  'DERIVE',
                  'User CPU Time consumed by the background processes.'),
             )),
            ('redis_hits_misses', 'Hits/Misses per Sec',
             'Hits vs. misses in main dictionary lookup by Redis Server.', (
                 ('keyspace_hits', 'hit', 'AREASTACK', 'DERIVE',
                  'Number of hits in main dictionary lookup.'),
                 ('keyspace_misses', 'miss', 'AREASTACK', 'DERIVE',
                  'Number of misses in main dictionary lookup.'),
             )),
            ('redis_keys_expired', 'Expired Keys per Sec',
             'Number of keys expired by the Redis Server.',
             (('expired_keys', 'keys', 'LINE2', 'DERIVE',
               'Number of keys expired.'), )),
            ('redis_keys_evicted', 'Evicted Keys per Sec',
             'Number of keys evicted by the Redis Server due to memory limits.',
             (('evicted_keys', 'keys', 'LINE2', 'DERIVE',
               'Number of keys evicted.'), )),
            ('redis_subscriptions', 'Subscriptions',
             'Channels or patterns with subscribed clients.', (
                 ('pubsub_patterns', 'patterns', 'AREASTACK', 'GAUGE',
                  'Global number of pub/sub patterns with client subscriptions.'
                  ),
                 ('pubsub_channels', 'channels', 'AREASTACK', 'GAUGE',
                  'Global number of pub/sub channels with client subscriptions.'
                  ),
             )),
            ('redis_rdb_changes', 'RDB Pending Changes',
             'Number of pending changes since last RDB Dump of Redis Server.',
             (('rdb_changes_since_last_save', 'changes', 'LINE2', 'GAUGE',
               'Number of changes since last RDB Dump.'), )),
            ('redis_rdb_dumptime', 'RDB Dump Duration (sec)',
             'Duration of the last RDB Dump of Redis Server in seconds.',
             (('rdb_last_bgsave_time_sec', 'duration', 'LINE2', 'GAUGE',
               'Duration of the last RDB Dump in seconds.'), )),
        ]

        if self._stats.get('aof_enabled', 0) > 0:
            graphs.extend((
                ('redis_aof_filesize', 'AOF File Size (bytes)',
                 'Redis Server AOF File Size in bytes.',
                 (('aof_current_size', 'size', 'LINE2', 'GAUGE',
                   'AOF File Size in bytes.'), )),
                ('redis_aof_bufflen', 'AOF Buffer Length (bytes)',
                 'Redis Server AOF Buffer Length in bytes.',
                 (('aof_buffer_length', 'len', 'LINE2', 'GAUGE',
                   'AOF Buffer Length in bytes.'), )),
                ('redis_aof_rewrite_bufflen',
                 'AOF Rewrite Buffer Length (bytes)',
                 'Redis Server AOF Rewrite Buffer Length in bytes.',
                 (('aof_rewrite_buffer_length', 'len', 'LINE2', 'GAUGE',
                   'AOF Rewrite Buffer Length in bytes.'), )),
                ('redis_aof_rewritetime', 'AOF Rewrite Duration (sec)',
                 'Duration of the last AOF Rewrite of Redis Server in seconds.',
                 (('aof_last_rewrite_time_sec', 'duration', 'AREA', 'GAUGE',
                   'Duration of the last AOF Rewrite in seconds.'), )),
            ))

        for graph_name, graph_title, graph_info, graph_fields in graphs:
            if self.graphEnabled(graph_name):
                graph = MuninGraph("Redis - %s" % graph_title,
                                   self._category,
                                   info=graph_info,
                                   args='--base 1000 --lower-limit 0')
                for fname, flabel, fdraw, ftype, finfo in graph_fields:
                    if self._stats.has_key(fname):
                        graph.addField(fname,
                                       flabel,
                                       draw=fdraw,
                                       type=ftype,
                                       min=0,
                                       info=finfo)
                if graph.getFieldCount() > 0:
                    self.appendGraph(graph_name, graph)

        self._stats['db_total_keys'] = 0
        self._stats['db_total_expires'] = 0
        if self.graphEnabled('redis_db_totals'):
            for db in db_list:
                fname_keys = "%s_keys" % db
                fname_expires = "%s_expires" % db
                num_keys = self._stats[db].get('keys', 0)
                num_expires = self._stats[db].get('expires', 0)
                self._stats[fname_keys] = num_keys
                self._stats[fname_expires] = num_expires
                self._stats['db_total_keys'] += num_keys
                self._stats['db_total_expires'] += num_expires
            self._stats['db_total_persists'] = (
                self._stats['db_total_keys'] - self._stats['db_total_expires'])

        graph_name = 'redis_db_totals'
        if self.graphEnabled(graph_name) and len(db_list) > 0:
            graph = MuninGraph("Redis - Number of Keys",
                               self._category,
                               info="Number of keys stored by Redis Server",
                               args='--base 1000 --lower-limit 0')
            graph.addField('db_total_expires',
                           'expire',
                           'GAUGE',
                           'AREASTACK',
                           min=0,
                           info="Total number of keys with expiration.")
            graph.addField('db_total_persists',
                           'persist',
                           'GAUGE',
                           'AREASTACK',
                           min=0,
                           info="Total number of keys without expiration.")
            graph.addField('db_total_keys',
                           'total',
                           'GAUGE',
                           'LINE2',
                           min=0,
                           info="Total number of keys.",
                           colour='000000')
            self.appendGraph(graph_name, graph)

        graph_name = 'redis_db_keys'
        if self.graphEnabled(graph_name) and len(db_list) > 0:
            graph = MuninGraph(
                "Redis - Number of Keys per DB",
                self._category,
                info="Number of keys stored in each DB by Redis Server",
                args='--base 1000 --lower-limit 0')
            for db in db_list:
                fname = "%s_keys" % db
                graph.addField(fname,
                               db,
                               'GAUGE',
                               'AREASTACK',
                               min=0,
                               info="Number of keys stored in %s." % db)
            self.appendGraph(graph_name, graph)

        graph_name = 'redis_db_expires'
        if self.graphEnabled(graph_name) and len(db_list) > 0:
            graph = MuninGraph(
                "Redis - Number of Keys with Expiration per DB",
                self._category,
                info="Number of keys stored in each DB by Redis Server",
                args='--base 1000 --lower-limit 0')
            for db in db_list:
                fname = "%s_expires" % db
                graph.addField(
                    fname,
                    db,
                    'GAUGE',
                    'AREASTACK',
                    min=0,
                    info="Number of keys with expiration stored in %s." % db)
            self.appendGraph(graph_name, graph)
示例#4
0
 def __init__(self, argv=(), env=None, debug=False):
     """Populate Munin Plugin with MuninGraph instances.
     
     @param argv:  List of command line arguments.
     @param env:   Dictionary of environment variables.
     @param debug: Print debugging messages if True. (Default: False)
     
     """
     MuninPlugin.__init__(self, argv, env, debug)
     
     self._host = self.envGet('host')
     self._port = self.envGet('port')
     self._db = self.envGet('db')
     self._password = self.envGet('password')
     self._socket_timeout = self.envGet('socket_timeout', None, float)
     self._unix_socket_path = self.envGet('unix_socket_path')
     self._category = 'Redis'
     
     self._serverInfo = RedisInfo(self._host, self._port, self._db, 
                                  self._password, self._socket_timeout,
                                  self._unix_socket_path)
     self._stats = self._serverInfo.getStats()
     self._stats['rtt'] = self._serverInfo.ping()
     
     cmd_list = []
     db_list = []
     for k in self._stats.keys():
         if k.startswith('cmdstat_'):
             cmd_list.append(k[len('cmdstat_'):])
         elif k.startswith('db'):
             db_list.append(k)
     db_list.sort()
     cmd_list.sort()
     graphs = [
         ('redis_ping', 'Ping Latency (secs)',
          'Round Trip Time in seconds for Redis Ping.',
          (('rtt', 'rtt', 'LINE2', 'GAUGE', 'Round trip time.'),)
         ),
         ('redis_conn_client', 'Active Client Connections',
          'Number of connections to Redis Server.',
          (('connected_clients', 'clients', 'AREA', 'GAUGE',
            'Number of clients connected to server.'),
           ('blocked_clients', 'blocked', 'LINE2', 'GAUGE',
            'Number of clients pending on a blocking call.'),)
         ),
         ('redis_conn_rate', 'Client Connections per Sec',
          'Connections accepted / rejected per second by the Redis Server.',
          (('rejected_connections', 'reject', 'AREASTACK', 'DERIVE',
            'Number of connections rejected by the server.'),
           ('total_connections_received', 'accept', 'AREASTACK', 'DERIVE',
            'Number of connections accepted by the server.'),)
         ),
         ('redis_cmd_rate', 'Commands Processed per Sec',
          'Number of commands processed per second by the Redis Server.',
          (('total_commands_processed', 'cmds', 'LINE2', 'DERIVE',
            'Number of commands processed by the Redis Server.'),)
         ),
         ('redis_memory', 'Memory Usage (bytes)', 'Memory usage of Redis Server.',
          (('used_memory_rss', 'rss', 'AREASTACK', 'GAUGE',
            'Resident Memory space (bytes) allocated to Redis by the OS for '
            'storing data.'),
           ('used_memory_lua', 'lua', 'AREASTACK', 'GAUGE',
            'Memory space (bytes) used by the Lua Engine.'),
           ('used_memory', 'mem', 'LINE2', 'GAUGE',
            'Memory space (bytes) allocated by Redis Allocator for storing data.'),)
         ),
         ('redis_memory_fragmentation', 'Memory Fragmentation Ratio',
          'Ratio between RSS and virtual memory use for Redis Server. '
          'Values much higher than 1 imply fragmentation. Values less '
          'than 1 imply that memory has been swapped out by OS.',
          (('mem_fragmentation_ratio', 'ratio', 'LINE2', 'GAUGE',
            'Ratio between RSS and virtual memory use.'),)
         ),
         ('redis_cpu_util', 'CPU Utilization',
          'Processor time utilized by Redis Server.',
          (('used_cpu_sys', 'srv_sys', 'AREASTACK', 'DERIVE',
            'System CPU Time consumed by the server.'),
           ('used_cpu_user', 'srv_user', 'AREASTACK', 'DERIVE',
            'User CPU Time consumed by the server.'),
           ('used_cpu_sys_children', 'child_sys', 'AREASTACK', 'DERIVE',
            'System CPU Time consumed by the background processes.'),
           ('used_cpu_user_children', 'child_user', 'AREASTACK', 'DERIVE',
            'User CPU Time consumed by the background processes.'),)
         ),
         ('redis_hits_misses', 'Hits/Misses per Sec',
          'Hits vs. misses in main dictionary lookup by Redis Server.',
          (('keyspace_hits', 'hit', 'AREASTACK', 'DERIVE',
            'Number of hits in main dictionary lookup.'),
           ('keyspace_misses', 'miss', 'AREASTACK', 'DERIVE',
            'Number of misses in main dictionary lookup.'),)
         ),
         ('redis_keys_expired', 'Expired Keys per Sec',
          'Number of keys expired by the Redis Server.',
          (('expired_keys', 'keys', 'LINE2', 'DERIVE',
            'Number of keys expired.'),)
         ),
         ('redis_keys_evicted', 'Evicted Keys per Sec',
          'Number of keys evicted by the Redis Server due to memory limits.',
          (('evicted_keys', 'keys', 'LINE2', 'DERIVE',
            'Number of keys evicted.'),)
         ),
         ('redis_subscriptions', 'Subscriptions',
          'Channels or patterns with subscribed clients.',
          (('pubsub_patterns', 'patterns', 'AREASTACK', 'GAUGE',
            'Global number of pub/sub patterns with client subscriptions.'),
           ('pubsub_channels', 'channels', 'AREASTACK', 'GAUGE',
            'Global number of pub/sub channels with client subscriptions.'),)
         ),
         ('redis_rdb_changes', 'RDB Pending Changes', 
          'Number of pending changes since last RDB Dump of Redis Server.',
          (('rdb_changes_since_last_save', 'changes', 'LINE2', 'GAUGE',
            'Number of changes since last RDB Dump.'),)
         ),
         ('redis_rdb_dumptime', 'RDB Dump Duration (sec)', 
          'Duration of the last RDB Dump of Redis Server in seconds.',
          (('rdb_last_bgsave_time_sec', 'duration', 'LINE2', 'GAUGE',
            'Duration of the last RDB Dump in seconds.'),)
         ),
     ]
     
     if self._stats.get('aof_enabled', 0) > 0:
         graphs.extend((
             ('redis_aof_filesize', 'AOF File Size (bytes)', 
              'Redis Server AOF File Size in bytes.',
              (('aof_current_size', 'size', 'LINE2', 'GAUGE',
                'AOF File Size in bytes.'),)
             ),
             ('redis_aof_bufflen', 'AOF Buffer Length (bytes)', 
              'Redis Server AOF Buffer Length in bytes.',
              (('aof_buffer_length', 'len', 'LINE2', 'GAUGE',
                'AOF Buffer Length in bytes.'),)
             ),
             ('redis_aof_rewrite_bufflen', 'AOF Rewrite Buffer Length (bytes)', 
              'Redis Server AOF Rewrite Buffer Length in bytes.',
              (('aof_rewrite_buffer_length', 'len', 'LINE2', 'GAUGE',
                'AOF Rewrite Buffer Length in bytes.'),)
             ),
             ('redis_aof_rewritetime', 'AOF Rewrite Duration (sec)', 
              'Duration of the last AOF Rewrite of Redis Server in seconds.',
              (('aof_last_rewrite_time_sec', 'duration', 'AREA', 'GAUGE',
                'Duration of the last AOF Rewrite in seconds.'),)
             ),             
         ))
     
     for graph_name, graph_title, graph_info, graph_fields in graphs:
         if self.graphEnabled(graph_name):
             graph = MuninGraph("Redis - %s" % graph_title, self._category, 
                                info=graph_info, 
                                args='--base 1000 --lower-limit 0')
             for fname, flabel, fdraw, ftype, finfo in graph_fields:
                 if self._stats.has_key(fname):
                     graph.addField(fname, flabel, draw=fdraw, type=ftype, 
                                    min=0, info=finfo)
             if graph.getFieldCount() > 0:
                 self.appendGraph(graph_name, graph)
     
     self._stats['db_total_keys'] = 0
     self._stats['db_total_expires'] = 0
     if self.graphEnabled('redis_db_totals'):
         for db in db_list:
             fname_keys = "%s_keys" % db
             fname_expires = "%s_expires" % db
             num_keys = self._stats[db].get('keys', 0)
             num_expires = self._stats[db].get('expires', 0)
             self._stats[fname_keys] = num_keys
             self._stats[fname_expires] = num_expires
             self._stats['db_total_keys'] += num_keys
             self._stats['db_total_expires'] += num_expires
         self._stats['db_total_persists'] = (self._stats['db_total_keys']
                                             - self._stats['db_total_expires'])
     
     graph_name = 'redis_db_totals'
     if self.graphEnabled(graph_name) and len(db_list) > 0:
         graph = MuninGraph("Redis - Number of Keys", self._category,
                            info="Number of keys stored by Redis Server",
                            args='--base 1000 --lower-limit 0')
         graph.addField('db_total_expires', 'expire', 'GAUGE', 'AREASTACK', 
                        min=0, info="Total number of keys with expiration.")
         graph.addField('db_total_persists', 'persist', 'GAUGE', 'AREASTACK', 
                        min=0, info="Total number of keys without expiration.")
         graph.addField('db_total_keys', 'total', 'GAUGE', 'LINE2', 
                        min=0, info="Total number of keys.", colour='000000')
         self.appendGraph(graph_name, graph)
             
     graph_name = 'redis_db_keys'
     if self.graphEnabled(graph_name) and len(db_list) > 0:
         graph = MuninGraph("Redis - Number of Keys per DB", self._category,
                            info="Number of keys stored in each DB by Redis Server",
                            args='--base 1000 --lower-limit 0')
         for db in db_list:
             fname = "%s_keys" % db
             graph.addField(fname, db, 'GAUGE', 'AREASTACK', min=0, 
                            info="Number of keys stored in %s." % db)
         self.appendGraph(graph_name, graph)
     
     graph_name = 'redis_db_expires'
     if self.graphEnabled(graph_name) and len(db_list) > 0:
         graph = MuninGraph("Redis - Number of Keys with Expiration per DB", 
                            self._category,
                            info="Number of keys stored in each DB by Redis Server",
                            args='--base 1000 --lower-limit 0')
         for db in db_list:
             fname = "%s_expires" % db
             graph.addField(fname, db, 'GAUGE', 'AREASTACK', min=0, 
                            info="Number of keys with expiration stored in %s." % db)
         self.appendGraph(graph_name, graph)