diff --git a/zabbix-agent-scripts/zabbix-redis.py b/zabbix-agent-scripts/zabbix-redis.py new file mode 100644 index 0000000..c9c3f36 --- /dev/null +++ b/zabbix-agent-scripts/zabbix-redis.py @@ -0,0 +1,535 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +''' +Note from RCA Systems + +This script is developed by Allenta Consulting and available in Github: + +https://github.com/allenta/zabbix-template-for-redis + +This is taken from release v14.0 + +https://github.com/allenta/zabbix-template-for-redis/releases/tag/v14.0 +''' + +''' +:url: https://github.com/allenta/zabbix-template-for-redis +:copyright: (c) Allenta Consulting S.L. . +:license: BSD, see LICENSE.txt for more details. +''' + +from __future__ import absolute_import, division, print_function, unicode_literals +import json +import re +import subprocess +import sys +from argparse import ArgumentParser + +TYPE_COUNTER = 1 +TYPE_GAUGE = 2 +TYPE_OTHER = 3 +TYPES = (TYPE_COUNTER, TYPE_GAUGE, TYPE_OTHER) + +ITEMS = { + 'server': ( + (r'server:uptime_in_seconds', TYPE_GAUGE), + (r'clients:connected_clients', TYPE_GAUGE), + (r'clients:blocked_clients', TYPE_GAUGE), + (r'memory:used_memory', TYPE_GAUGE), + (r'memory:used_memory_rss', TYPE_GAUGE), + (r'memory:used_memory_lua', TYPE_GAUGE), + (r'memory:mem_fragmentation_ratio', TYPE_GAUGE), + (r'persistence:rdb_changes_since_last_save', TYPE_GAUGE), + (r'persistence:rdb_last_save_time', TYPE_GAUGE), + (r'persistence:rdb_last_bgsave_status', TYPE_OTHER), + (r'persistence:rdb_last_bgsave_time_sec', TYPE_GAUGE), + (r'persistence:aof_last_rewrite_time_sec', TYPE_GAUGE), + (r'persistence:aof_last_bgrewrite_status', TYPE_OTHER), + (r'persistence:aof_last_write_status', TYPE_OTHER), + (r'stats:total_connections_received', TYPE_COUNTER), + (r'stats:total_commands_processed', TYPE_COUNTER), + (r'stats:total_net_input_bytes', TYPE_COUNTER), + (r'stats:total_net_output_bytes', TYPE_COUNTER), + (r'stats:rejected_connections', TYPE_COUNTER), + (r'stats:sync_full', TYPE_COUNTER), + (r'stats:sync_partial_ok', TYPE_COUNTER), + (r'stats:sync_partial_err', TYPE_COUNTER), + (r'stats:expired_keys', TYPE_COUNTER), + (r'stats:evicted_keys', TYPE_COUNTER), + (r'stats:keyspace_hits', TYPE_COUNTER), + (r'stats:keyspace_misses', TYPE_COUNTER), + (r'stats:pubsub_channels', TYPE_GAUGE), + (r'stats:pubsub_patterns', TYPE_GAUGE), + (r'replication:role', TYPE_GAUGE), + (r'replication:connected_slaves', TYPE_GAUGE), + (r'cpu:used_cpu_sys', TYPE_COUNTER), + (r'cpu:used_cpu_user', TYPE_COUNTER), + (r'cpu:used_cpu_sys_children', TYPE_COUNTER), + (r'cpu:used_cpu_user_children', TYPE_COUNTER), + (r'commandstats:[^:]+:calls', TYPE_COUNTER), + (r'commandstats:[^:]+:usec_per_call', TYPE_GAUGE), + (r'keyspace:[^:]+:(?:keys|expires|avg_ttl)', TYPE_GAUGE), + (r'cluster:cluster_state', TYPE_GAUGE), + (r'cluster:cluster_slots_assigned', TYPE_GAUGE), + (r'cluster:cluster_slots_ok', TYPE_GAUGE), + (r'cluster:cluster_slots_pfail', TYPE_GAUGE), + (r'cluster:cluster_slots_fail', TYPE_GAUGE), + (r'cluster:cluster_known_nodes', TYPE_GAUGE), + (r'cluster:cluster_size', TYPE_GAUGE), + ), + 'sentinel': ( + (r'server:uptime_in_seconds', TYPE_GAUGE), + (r'sentinel:sentinel_masters', TYPE_GAUGE), + (r'sentinel:sentinel_running_scripts', TYPE_GAUGE), + (r'sentinel:sentinel_scripts_queue_length', TYPE_GAUGE), + (r'masters:[^:]+:(?:status|slaves|sentinels|ckquorum|usable_sentinels)', TYPE_GAUGE), + ), +} + +SUBJECTS = { + 'server': { + 'items': None, + 'commandstats': re.compile(r'^commandstats:([^:]+):.+$'), + 'keyspace': re.compile(r'^keyspace:([^:]+):.+$'), + }, + 'sentinel': { + 'items': None, + 'masters': re.compile(r'^masters:([^:]+):.+$'), + }, +} + + +############################################################################### +## 'stats' COMMAND +############################################################################### + +def stats(options): + # Initializations. + result = {} + + # Build master item contents. + for instance in options.redis_instances.split(','): + instance = instance.strip() + stats = _stats( + instance, + options.redis_type, + options.redis_user, + options.redis_password) + for item in stats.items: + result['%(instance)s.%(name)s' % { + 'instance': _safe_zabbix_string(instance), + 'name': _safe_zabbix_string(item.name), + }] = item.value + + # Render output. + sys.stdout.write(json.dumps(result, separators=(',', ':'))) + + +############################################################################### +## 'discover' COMMAND +############################################################################### + +def discover(options): + # Initializations. + discovery = { + 'data': [], + } + + # Build Zabbix discovery input. + for instance in options.redis_instances.split(','): + instance = instance.strip() + if options.subject == 'items': + discovery['data'].append({ + '{#LOCATION}': instance, + '{#LOCATION_ID}': _safe_zabbix_string(instance), + }) + else: + stats = _stats( + instance, + options.redis_type, + options.redis_user, + options.redis_password) + for subject in stats.subjects(options.subject): + discovery['data'].append({ + '{#LOCATION}': instance, + '{#LOCATION_ID}': _safe_zabbix_string(instance), + '{#SUBJECT}': subject, + '{#SUBJECT_ID}': _safe_zabbix_string(subject), + }) + + # Render output. + sys.stdout.write(json.dumps(discovery, sort_keys=True, indent=2)) + + +############################################################################### +## HELPERS +############################################################################### + +class Item(object): + ''' + A class to hold all relevant information about an item in the stats: name, + value, type and subject (type & value). + ''' + + def __init__( + self, name, value, type, subject_type=None, subject_value=None): + # Set name and value. + self._name = name + self._value = value + self._type = type + self._subject_type = subject_type or 'items' + self._subject_value = subject_value + + @property + def name(self): + return self._name + + @property + def value(self): + return self._value + + @property + def type(self): + return self._type + + @property + def subject_type(self): + return self._subject_type + + @property + def subject_value(self): + return self._subject_value + + def aggregate(self, value): + # Aggregate another value. Only counter and gauges can be aggregated. + # In any other case, mark this item's value as discarded. + if self.type in (TYPE_COUNTER, TYPE_GAUGE): + self._value += value + else: + self._value = None + + +class Stats(object): + ''' + A class to hold results for a call to _stats: keeps all processed items and + all subjects seen per subject type and provides helper methods to build and + process those items. + ''' + + def __init__(self, items_definitions, subjects_patterns, log_handler=None): + # Build items regular expression that will be used to match item names + # and discover item types. + items_re = dict((type, []) for type in TYPES) + for item_re, item_type in items_definitions: + items_re[item_type].append(item_re) + self._items_patterns = dict( + (type, re.compile(r'^(?:' + '|'.join(res) + r')$')) + for type, res in items_re.items()) + + # Set subject patterns that will be used to assign subject type and + # subject values to items. + self._subjects_patterns = subjects_patterns + + # Other initializations. + self._log_handler = log_handler or sys.stderr.write + self._items = {} + self._subjects = {} + + @property + def items(self): + # Return all items that haven't had their value discarded because an + # invalid aggregation. + return (item for item in self._items.values() if item.value is not None) + + def add(self, name, value, type=None, subject_type=None, + subject_value=None): + # Add a new item to the internal state or simply aggregate it's value + # if an item with the same name has already been added. + if name in self._items: + self._items[name].aggregate(value) + else: + # Build item. + item = self._build_item( + name, value, type, subject_type, subject_value) + + if item is not None: + # Add new item to the internal state. + self._items[item.name] = item + + # Also, register this item's subject in the corresponding set. + if item.subject_type != None and item.subject_value != None: + if item.subject_type not in self._subjects: + self._subjects[item.subject_type] = set() + self._subjects[item.subject_type].add(item.subject_value) + + def get(self, name, default=None): + # Return current value for a particular item or the given default value + # if that item is not available or has had it's value discarded. + if name in self._items and self._items[name].value is not None: + return self._items[name].value + else: + return default + + def subjects(self, subject_type): + # Return the set of registered subjects for a given subject type. + return self._subjects.get(subject_type, set()) + + def log(self, message): + self._log_handler(message) + + def _build_item( + self, name, value, type=None, subject_type=None, + subject_value=None): + # Initialize type if none was provided. + if type is None: + type = next(( + type for type in TYPES + if self._items_patterns[type].match(name) is not None), None) + + # Filter invalid items. + if type not in TYPES: + return None + + # Initialize subject_type and subject_value if none were provided. + if subject_type is None and subject_value is None: + for subject, subject_re in self._subjects_patterns.items(): + if subject_re is not None: + match = subject_re.match(name) + if match is not None: + subject_type = subject + subject_value = match.group(1) + break + + # Return item instance. + return Item( + name=name, + value=value, + type=type, + subject_type=subject_type, + subject_value=subject_value + ) + + +def _stats(location, type, user, password): + # Initializations. + stats = Stats(ITEMS[type], SUBJECTS[type]) + clustered = False + + # Parse location of the Redis instance. + prefix = 'unix://' + if location.startswith(prefix): + opts = '-s "%s"' % location[len(prefix):] + else: + if ':' in location: + opts = '-h "%s" -p "%s"' % tuple(location.split(':', 1)) + else: + opts = '-p "%s"' % location + + # Authenticate as an user other than default? + if user is not None: + opts += ' --user "%s"' % user + + # Use password? + if password is not None: + opts += ' -a "%s"' % password + + # Fetch general stats through redis-cli. + rc, output = _execute('redis-cli %(opts)s INFO %(section)s' % { + 'opts': opts, + 'section': 'all' if type == 'server' else 'default', + }) + if rc == 0: + section = None + for line in output.splitlines(): + # Start of section. Keep it's name. + if line.startswith('#'): + section = line[1:].strip().lower() + + # Item. Process it. + elif section is not None and ':' in line: + # Extract item name and item value. + key, value = (v.strip() for v in line.split(':', 1)) + if section == 'commandstats' and \ + key.startswith('cmdstat_'): + key = key[8:].upper() + name = '%s:%s' % (section, key) + + # If this item enables cluster mode set the corresponding flag + # to later check for cluster stats. + if name == 'cluster:cluster_enabled' and value == '1': + clustered = True + + # Special keys with subvalues. + if ((type == 'server' and + section in ('keyspace', 'commandstats')) or \ + (type == 'sentinel' and + section == 'sentinel' and + key.startswith('master'))): + # Extract subvalues. + subvalues = {} + for item in value.split(','): + if '=' in item: + subkey, subvalue = item.split('=', 1) + subvalues[subkey.strip()] = subvalue.strip() + + # Process subvalues. + for subkey, subvalue in subvalues.items(): + if type == 'sentinel' and subkey == 'name': + _stats_sentinel( + stats, + opts, + subvalue, + 'masters:%s(%s)' % (key, subvalue)) + else: + subname = None + if type != 'sentinel': + subname = '%s:%s' % (name, subkey) + elif subkey != 'name' and 'name' in subvalues: + subname = 'masters:%s(%s):%s' % ( + key, subvalues['name'], subkey) + if subname is not None: + # Add item to the result. + stats.add(subname, subvalue) + + # Simple keys with no subvalues. + else: + # Add item to the result. + stats.add(name, value) + + # Error recovering information from redis-cli. + else: + stats.log(output) + + # Fetch cluster stats through redis-cli. + if type == 'server' and clustered: + _stats_cluster(stats, opts) + + # Done! + return stats + + +def _stats_sentinel(stats, opts, master_name, prefix): + # Fetch sentinel stats through redis-cli. + rc, output = _execute('redis-cli %(opts)s SENTINEL ckquorum %(name)s' % { + 'opts': opts, + 'name': master_name, + }) + if rc == 0: + # Examples: + # - OK 3 usable Sentinels. Quorum and failover authorization can be + # reached. + # - NOQUORUM 1 usable Sentinels. Not enough available Sentinels to + # reach the majority and authorize a failover. + stats.add( + name='%s:ckquorum' % prefix, + value='1' if output.startswith('OK') else '0') + items = output.split(' ', 2) + if len(items) >= 2 and items[1].isdigit(): + stats.add( + name='%s:usable_sentinels' % prefix, + value=items[1]) + + # Error recovering information from redis-cli. + else: + stats.log(output) + + +def _stats_cluster(stats, opts): + # Fetch cluster stats through redis-cli. + rc, output = _execute('redis-cli %(opts)s CLUSTER INFO' % { + 'opts': opts, + }) + if rc == 0: + for line in output.splitlines(): + if ':' in line: + key, value = line.split(':', 1) + stats.add( + name='cluster:%s' % key.strip(), + value=value.strip()) + + # Error recovering information from redis-cli. + else: + stats.log(output) + + +def _safe_zabbix_string(value): + # Return a modified version of 'value' safe to be used as part of: + # - A quoted key parameter (see https://www.zabbix.com/documentation/5.0/manual/config/items/item/key). + # - A JSON string. + return value.replace('"', '\\"') + + +def _execute(command, stdin=None): + child = subprocess.Popen( + command, + shell=True, + stdout=subprocess.PIPE, + stdin=subprocess.PIPE, + stderr=subprocess.STDOUT) + output = child.communicate( + input=stdin.encode('utf-8') if stdin is not None else None)[0].decode('utf-8') + return child.returncode, output + + +############################################################################### +## MAIN +############################################################################### + +def main(): + # Set up the base command line parser. + parser = ArgumentParser() + parser.add_argument( + '-i', '--redis-instances', dest='redis_instances', + type=str, required=True, + help='comma-delimited list of Redis instances to get stats from ' + '(port, host:port and unix:///path/to/socket formats are alowed') + parser.add_argument( + '-t', '--redis-type', dest='redis_type', + type=str, required=True, choices=SUBJECTS.keys(), + help='the type of the Redis instance to get stats from') + parser.add_argument( + '--redis-user', dest='redis_user', + type=str, default=None, + help='user name to be used in Redis instances authentication (redis >= 6.0)') + parser.add_argument( + '--redis-password', dest='redis_password', + type=str, default=None, + help='password required to access to Redis instances') + subparsers = parser.add_subparsers(dest='command') + + # Set up 'stats' command. + subparser = subparsers.add_parser( + 'stats', + help='collect Redis stats') + + # Set up 'discover' command. + subparser = subparsers.add_parser( + 'discover', + help='generate Zabbix discovery schema') + subparser.add_argument( + 'subject', type=str, + help='dynamic resources to be discovered') + + # Parse command line arguments. + options = parser.parse_args() + + # Check subject to be discovered. + if options.command == 'discover': + subjects = SUBJECTS[options.redis_type].keys() + if options.subject not in subjects: + sys.stderr.write('Invalid subject (choose from %(subjects)s)\n' % { + 'subjects': ', '.join("'{0}'".format(s) for s in subjects), + }) + sys.exit(1) + + # Execute command. + if options.command: + globals()[options.command](options) + else: + parser.print_help() + sys.exit(1) + sys.exit(0) + +if __name__ == '__main__': + main() diff --git a/zabbix-templates/redis-zabbix-allenta-consulting-template.json b/zabbix-templates/redis-zabbix-allenta-consulting-template.json new file mode 100644 index 0000000..1a1d595 --- /dev/null +++ b/zabbix-templates/redis-zabbix-allenta-consulting-template.json @@ -0,0 +1,1511 @@ +{ + "zabbix_export": { + "version": "6.4", + "template_groups": [ + { + "uuid": "7df96b18c230490a9a0a9e2307226338", + "name": "Templates" + } + ], + "templates": [ + { + "uuid": "0985c017179b4925a39859b210f8068e", + "template": "Template App Redis Server", + "name": "Template App Redis Server", + "description": "Template App Redis Server v14.0", + "vendor": { + "name": "Allenta Consulting S.L.", + "version": "6.4-14.0" + }, + "groups": [ + { + "name": "Templates" + } + ], + "items": [ + { + "uuid": "0dd210187c7e4086af924495bf3215b9", + "name": "Redis Server - $1 processes", + "key": "proc.num[redis-server]", + "delay": "{$REDIS_SERVER.ITEM_UPDATE_INTERVAL}", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ], + "triggers": [ + { + "uuid": "4a0ea180d9124067be6d1f4e46421773", + "expression": "last(/Template App Redis Server/proc.num[redis-server])<{$REDIS_SERVER.PROCESSES.MIN}", + "name": "Redis Server is not running", + "priority": "DISASTER" + } + ] + }, + { + "uuid": "b4a345736aec44bdbde03ce96b338994", + "name": "Redis Server - stats", + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]", + "delay": "{$REDIS_SERVER.ITEM_UPDATE_INTERVAL}", + "history": "0", + "value_type": "TEXT", + "preprocessing": [ + { + "type": "JAVASCRIPT", + "parameters": [ + "\n var exclusions = '{$REDIS_SERVER.EXCLUDED_STATS}'.trim();\n\n // This check is not just a simple optimization to avoid using never matching\n // regexps like '^(?!)' when filtering is not needed. JavaScript based filtering\n // effectively limits precision of numeric values and it could trigger rendering\n // of values using scientific notation.\n if (exclusions !== '') {\n exclusions = new RegExp(exclusions);\n\n var stats = JSON.parse(value);\n\n Object.keys(stats).forEach(function(key) {\n var name = key.replace(/^[^.]*[.]/, '');\n if (exclusions.test(name)) {\n delete stats[key];\n }\n });\n\n return JSON.stringify(stats);\n } else {\n return value;\n }\n " + ] + } + ], + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + } + ], + "discovery_rules": [ + { + "uuid": "2a82dc028a7e449690f7717e7f89aa3b", + "name": "Commandstats discovery", + "key": "redis_server.discovery[\"{$REDIS_SERVER.LOCATIONS}\",\"commandstats\"]", + "delay": "{$REDIS_SERVER.LLD_UPDATE_INTERVAL:\"commandstats\"}", + "filter": { + "conditions": [ + { + "macro": "{#SUBJECT}", + "value": "{$REDIS_SERVER.LLD_EXCLUDED_SUBJECTS:\"commandstats\"}", + "operator": "NOT_MATCHES_REGEX", + "formulaid": "A" + } + ] + }, + "lifetime": "{$REDIS_SERVER.LLD_KEEP_LOST_RESOURCES_PERIOD:\"commandstats\"}", + "item_prototypes": [ + { + "uuid": "bcd9f65b5a5b452189b7ccf0adbd78c8", + "name": "Redis Server[{#LOCATION}] - commandstats:{#SUBJECT}:calls", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"commandstats:{#SUBJECT}:calls\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "value_type": "FLOAT", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "units": "eps", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.commandstats:{#SUBJECT}:calls']" + ], + "error_handler": "DISCARD_VALUE" + }, + { + "type": "CHANGE_PER_SECOND" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "7b6c45697ba14f10bd7164dc27c01090", + "name": "Redis Server[{#LOCATION}] - commandstats:{#SUBJECT}:usec_per_call", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"commandstats:{#SUBJECT}:usec_per_call\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "value_type": "FLOAT", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.commandstats:{#SUBJECT}:usec_per_call']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + } + ] + }, + { + "uuid": "e8dd71a33888412dbbd3ff3f3307b9c6", + "name": "Items discovery", + "key": "redis_server.discovery[\"{$REDIS_SERVER.LOCATIONS}\",\"items\"]", + "delay": "{$REDIS_SERVER.LLD_UPDATE_INTERVAL:\"items\"}", + "lifetime": "{$REDIS_SERVER.LLD_KEEP_LOST_RESOURCES_PERIOD:\"items\"}", + "item_prototypes": [ + { + "uuid": "39475ca0c1464d3e9cbe7b85d3d81085", + "name": "Redis Server[{#LOCATION}] - clients:blocked_clients", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"clients:blocked_clients\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.clients:blocked_clients']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "327f368c4eff4b68bd1b8e1f6d5e6934", + "name": "Redis Server[{#LOCATION}] - clients:connected_clients", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"clients:connected_clients\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.clients:connected_clients']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "42093af8dbca40ae8eaf342b4307e4ae", + "name": "Redis Server[{#LOCATION}] - cluster:cluster_known_nodes", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"cluster:cluster_known_nodes\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.cluster:cluster_known_nodes']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "b2cd47874a774d3c9bd8b0b071a39b38", + "name": "Redis Server[{#LOCATION}] - cluster:cluster_size", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"cluster:cluster_size\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.cluster:cluster_size']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "581ecf808c544e28a9f070c3bf74d5e4", + "name": "Redis Server[{#LOCATION}] - cluster:cluster_slots_assigned", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"cluster:cluster_slots_assigned\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.cluster:cluster_slots_assigned']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "0671752af70d4ec89e755497d7017ae1", + "name": "Redis Server[{#LOCATION}] - cluster:cluster_slots_fail", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"cluster:cluster_slots_fail\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.cluster:cluster_slots_fail']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "e08e2f608ff2439da9093a9d42fb6aea", + "name": "Redis Server[{#LOCATION}] - cluster:cluster_slots_ok", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"cluster:cluster_slots_ok\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.cluster:cluster_slots_ok']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "37457455be4f49d888ff64118a2fe5ab", + "name": "Redis Server[{#LOCATION}] - cluster:cluster_slots_pfail", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"cluster:cluster_slots_pfail\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.cluster:cluster_slots_pfail']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "5ed9c084254c487bb86ba5fefb96d4f5", + "name": "Redis Server[{#LOCATION}] - cluster:cluster_state", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"cluster:cluster_state\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "value_type": "TEXT", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.cluster:cluster_state']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "5921de15169a43a6952552c795c3a3af", + "name": "Redis Server[{#LOCATION}] - cpu:used_cpu_sys", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"cpu:used_cpu_sys\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "value_type": "FLOAT", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "units": "eps", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.cpu:used_cpu_sys']" + ], + "error_handler": "DISCARD_VALUE" + }, + { + "type": "CHANGE_PER_SECOND" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "84307066f3f04a758c94e5ee01c7938e", + "name": "Redis Server[{#LOCATION}] - cpu:used_cpu_sys_children", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"cpu:used_cpu_sys_children\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "value_type": "FLOAT", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "units": "eps", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.cpu:used_cpu_sys_children']" + ], + "error_handler": "DISCARD_VALUE" + }, + { + "type": "CHANGE_PER_SECOND" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "6c410ba56ead40858decab4c84e9b998", + "name": "Redis Server[{#LOCATION}] - cpu:used_cpu_user", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"cpu:used_cpu_user\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "value_type": "FLOAT", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "units": "eps", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.cpu:used_cpu_user']" + ], + "error_handler": "DISCARD_VALUE" + }, + { + "type": "CHANGE_PER_SECOND" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "21254c91ddb74bfe9eee9d82607328cd", + "name": "Redis Server[{#LOCATION}] - cpu:used_cpu_user_children", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"cpu:used_cpu_user_children\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "value_type": "FLOAT", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "units": "eps", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.cpu:used_cpu_user_children']" + ], + "error_handler": "DISCARD_VALUE" + }, + { + "type": "CHANGE_PER_SECOND" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "fac4af3cc8f1441389d386c62447af18", + "name": "Redis Server[{#LOCATION}] - hit_ratio", + "type": "CALCULATED", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"hit_ratio\"]", + "delay": "{$REDIS_SERVER.ITEM_UPDATE_INTERVAL}", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "value_type": "FLOAT", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "units": "%", + "params": "100*last(//redis_server.info[\"{#LOCATION_ID}\",\"stats:keyspace_hits\"])/(last(//redis_server.info[\"{#LOCATION_ID}\",\"stats:keyspace_hits\"])+last(//redis_server.info[\"{#LOCATION_ID}\",\"stats:keyspace_misses\"])+(count(//redis_server.info[\"{#LOCATION_ID}\",\"stats:keyspace_hits\"],#1,\"eq\",0)*count(//redis_server.info[\"{#LOCATION_ID}\",\"stats:keyspace_misses\"],#1,\"eq\",0)))", + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "2328c03f4b444f82a9a19e7246d883ad", + "name": "Redis Server[{#LOCATION}] - memory:mem_fragmentation_ratio", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"memory:mem_fragmentation_ratio\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "value_type": "FLOAT", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.memory:mem_fragmentation_ratio']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "421ae72f90fe46b4929112df5de1222c", + "name": "Redis Server[{#LOCATION}] - memory:used_memory", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"memory:used_memory\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "units": "B", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.memory:used_memory']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "bfa68004441b4705a18ef68c7a6f8bb6", + "name": "Redis Server[{#LOCATION}] - memory:used_memory_lua", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"memory:used_memory_lua\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "units": "B", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.memory:used_memory_lua']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "9edf931c27e94de1a0f029a9d5833b36", + "name": "Redis Server[{#LOCATION}] - memory:used_memory_rss", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"memory:used_memory_rss\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "units": "B", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.memory:used_memory_rss']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "2f2b46643e504baeab282528fbc155cf", + "name": "Redis Server[{#LOCATION}] - persistence:aof_last_bgrewrite_status", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"persistence:aof_last_bgrewrite_status\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "value_type": "TEXT", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.persistence:aof_last_bgrewrite_status']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "91978c3c77ef489fa65c75f1a22548a6", + "name": "Redis Server[{#LOCATION}] - persistence:aof_last_rewrite_time_sec", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"persistence:aof_last_rewrite_time_sec\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.persistence:aof_last_rewrite_time_sec']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "2a55fc618e294ce3a305a8e5271d6154", + "name": "Redis Server[{#LOCATION}] - persistence:aof_last_write_status", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"persistence:aof_last_write_status\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "value_type": "TEXT", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.persistence:aof_last_write_status']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "a7dd0f15e8f9483e8a41d4eaeeaff532", + "name": "Redis Server[{#LOCATION}] - persistence:rdb_changes_since_last_save", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"persistence:rdb_changes_since_last_save\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.persistence:rdb_changes_since_last_save']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "488ada8c369a474da74dce54d6d85493", + "name": "Redis Server[{#LOCATION}] - persistence:rdb_last_bgsave_status", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"persistence:rdb_last_bgsave_status\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "value_type": "TEXT", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.persistence:rdb_last_bgsave_status']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "9968741069d74a62a2efcce2025957e5", + "name": "Redis Server[{#LOCATION}] - persistence:rdb_last_bgsave_time_sec", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"persistence:rdb_last_bgsave_time_sec\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.persistence:rdb_last_bgsave_time_sec']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "5fbca013a8ca4051b49d4f2be670dd04", + "name": "Redis Server[{#LOCATION}] - persistence:rdb_last_save_time", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"persistence:rdb_last_save_time\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "units": "unixtime", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.persistence:rdb_last_save_time']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "64186f3afffe4c0c90fd81b56b4c58e1", + "name": "Redis Server[{#LOCATION}] - replication:connected_slaves", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"replication:connected_slaves\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.replication:connected_slaves']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "dfaa1031d4e641c9aac23efc1c2b3e84", + "name": "Redis Server[{#LOCATION}] - replication:role", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"replication:role\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "value_type": "TEXT", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.replication:role']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "eaaab8c393c34910930c20b1957dfd81", + "name": "Redis Server[{#LOCATION}] - server:uptime_in_seconds", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"server:uptime_in_seconds\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "units": "uptime", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.server:uptime_in_seconds']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ], + "trigger_prototypes": [ + { + "uuid": "e0e532c83c8b4a78aaa620a80358085d", + "expression": "last(/Template App Redis Server/redis_server.info[\"{#LOCATION_ID}\",\"server:uptime_in_seconds\"])<{$REDIS_SERVER.UPTIME.MIN:\"{#LOCATION_ID}\"}", + "name": "Redis Server[{#LOCATION}] has been restarted", + "priority": "HIGH" + } + ] + }, + { + "uuid": "ac8c032105934030a2ae11ba8a4fb1f5", + "name": "Redis Server[{#LOCATION}] - stats:evicted_keys", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"stats:evicted_keys\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "value_type": "FLOAT", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "units": "eps", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.stats:evicted_keys']" + ], + "error_handler": "DISCARD_VALUE" + }, + { + "type": "CHANGE_PER_SECOND" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ], + "trigger_prototypes": [ + { + "uuid": "ee545f84145049b0acef45ce5868ca5e", + "expression": "{$REDIS_SERVER.EVICTED_KEYS.ENABLED:\"{#LOCATION_ID}\"} and last(/Template App Redis Server/redis_server.info[\"{#LOCATION_ID}\",\"stats:evicted_keys\"])>{$REDIS_SERVER.EVICTED_KEYS.MAX:\"{#LOCATION_ID}\"}", + "name": "Redis Server[{#LOCATION}] is evicting keys", + "priority": "HIGH" + } + ] + }, + { + "uuid": "33c508f4f12d4396a257259a642fe06f", + "name": "Redis Server[{#LOCATION}] - stats:expired_keys", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"stats:expired_keys\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "value_type": "FLOAT", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "units": "eps", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.stats:expired_keys']" + ], + "error_handler": "DISCARD_VALUE" + }, + { + "type": "CHANGE_PER_SECOND" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "fe11dd3f19c04aae885a5e65be84ac44", + "name": "Redis Server[{#LOCATION}] - stats:keyspace_hits", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"stats:keyspace_hits\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "value_type": "FLOAT", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "units": "eps", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.stats:keyspace_hits']" + ], + "error_handler": "DISCARD_VALUE" + }, + { + "type": "CHANGE_PER_SECOND" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "2ca4880622a84537afb2e152e90d9b0e", + "name": "Redis Server[{#LOCATION}] - stats:keyspace_misses", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"stats:keyspace_misses\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "value_type": "FLOAT", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "units": "eps", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.stats:keyspace_misses']" + ], + "error_handler": "DISCARD_VALUE" + }, + { + "type": "CHANGE_PER_SECOND" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "d3c74496265344908c67fc707c5574a0", + "name": "Redis Server[{#LOCATION}] - stats:pubsub_channels", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"stats:pubsub_channels\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.stats:pubsub_channels']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "1da281315beb42cdb47a46bd04705279", + "name": "Redis Server[{#LOCATION}] - stats:pubsub_patterns", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"stats:pubsub_patterns\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.stats:pubsub_patterns']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "b30b5ebbba5a4fb283d8555e4f31e6db", + "name": "Redis Server[{#LOCATION}] - stats:rejected_connections", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"stats:rejected_connections\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "value_type": "FLOAT", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "units": "eps", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.stats:rejected_connections']" + ], + "error_handler": "DISCARD_VALUE" + }, + { + "type": "CHANGE_PER_SECOND" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "72a93e5d77da499da6fa35a449f8bdab", + "name": "Redis Server[{#LOCATION}] - stats:sync_full", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"stats:sync_full\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "value_type": "FLOAT", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "units": "eps", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.stats:sync_full']" + ], + "error_handler": "DISCARD_VALUE" + }, + { + "type": "CHANGE_PER_SECOND" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "de56a2ed709442f38c7ee2b1062e71f7", + "name": "Redis Server[{#LOCATION}] - stats:sync_partial_err", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"stats:sync_partial_err\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "value_type": "FLOAT", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "units": "eps", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.stats:sync_partial_err']" + ], + "error_handler": "DISCARD_VALUE" + }, + { + "type": "CHANGE_PER_SECOND" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "694a8e6cbf1046908889b5f01f2fe833", + "name": "Redis Server[{#LOCATION}] - stats:sync_partial_ok", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"stats:sync_partial_ok\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "value_type": "FLOAT", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "units": "eps", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.stats:sync_partial_ok']" + ], + "error_handler": "DISCARD_VALUE" + }, + { + "type": "CHANGE_PER_SECOND" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "41e203934ce34e1d9c60e944f71cd157", + "name": "Redis Server[{#LOCATION}] - stats:total_commands_processed", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"stats:total_commands_processed\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "value_type": "FLOAT", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "units": "eps", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.stats:total_commands_processed']" + ], + "error_handler": "DISCARD_VALUE" + }, + { + "type": "CHANGE_PER_SECOND" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "6d3bbd28afea4972b04d21e2514d630a", + "name": "Redis Server[{#LOCATION}] - stats:total_connections_received", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"stats:total_connections_received\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "value_type": "FLOAT", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "units": "eps", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.stats:total_connections_received']" + ], + "error_handler": "DISCARD_VALUE" + }, + { + "type": "CHANGE_PER_SECOND" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "0363d2b2013e4b1e9128f4aef5ee98f9", + "name": "Redis Server[{#LOCATION}] - stats:total_net_input_bytes", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"stats:total_net_input_bytes\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "value_type": "FLOAT", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "units": "Bps", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.stats:total_net_input_bytes']" + ], + "error_handler": "DISCARD_VALUE" + }, + { + "type": "CHANGE_PER_SECOND" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "3353518069404f049df2323c464e827c", + "name": "Redis Server[{#LOCATION}] - stats:total_net_output_bytes", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"stats:total_net_output_bytes\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "value_type": "FLOAT", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "units": "Bps", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.stats:total_net_output_bytes']" + ], + "error_handler": "DISCARD_VALUE" + }, + { + "type": "CHANGE_PER_SECOND" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + } + ], + "trigger_prototypes": [ + { + "uuid": "9f2a6de254b143a0abf7e7e0d7a8f672", + "expression": "{$REDIS_SERVER.CONNECTED_SLAVES.ENABLED:\"{#LOCATION_ID}\"} and find(/Template App Redis Server/redis_server.info[\"{#LOCATION_ID}\",\"replication:role\"],,\"eq\",\"master\")=1 and last(/Template App Redis Server/redis_server.info[\"{#LOCATION_ID}\",\"replication:connected_slaves\"])=0", + "name": "Redis Server[{#LOCATION}] is a master without slaves", + "priority": "HIGH" + } + ] + }, + { + "uuid": "0ab4e802e3f74f45a5e07cc7cdba333b", + "name": "Keyspace discovery", + "key": "redis_server.discovery[\"{$REDIS_SERVER.LOCATIONS}\",\"keyspace\"]", + "delay": "{$REDIS_SERVER.LLD_UPDATE_INTERVAL:\"keyspace\"}", + "filter": { + "conditions": [ + { + "macro": "{#SUBJECT}", + "value": "{$REDIS_SERVER.LLD_EXCLUDED_SUBJECTS:\"keyspace\"}", + "operator": "NOT_MATCHES_REGEX", + "formulaid": "A" + } + ] + }, + "lifetime": "{$REDIS_SERVER.LLD_KEEP_LOST_RESOURCES_PERIOD:\"keyspace\"}", + "item_prototypes": [ + { + "uuid": "d0ce35df09b2476b86ca8fc486a3b0e8", + "name": "Redis Server[{#LOCATION}] - keyspace:{#SUBJECT}:avg_ttl", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"keyspace:{#SUBJECT_ID}:avg_ttl\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.keyspace:{#SUBJECT_ID}:avg_ttl']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "390d42e974e044e4bc0069b87588e6e8", + "name": "Redis Server[{#LOCATION}] - keyspace:{#SUBJECT}:expires", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"keyspace:{#SUBJECT_ID}:expires\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.keyspace:{#SUBJECT_ID}:expires']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + }, + { + "uuid": "9d67ee3b117b479ca89876103ffddbeb", + "name": "Redis Server[{#LOCATION}] - keyspace:{#SUBJECT}:keys", + "type": "DEPENDENT", + "key": "redis_server.info[\"{#LOCATION_ID}\",\"keyspace:{#SUBJECT_ID}:keys\"]", + "history": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "trends": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "preprocessing": [ + { + "type": "JSONPATH", + "parameters": [ + "$['{#LOCATION_ID}.keyspace:{#SUBJECT_ID}:keys']" + ], + "error_handler": "DISCARD_VALUE" + } + ], + "master_item": { + "key": "redis_server.stats[\"{$REDIS_SERVER.LOCATIONS}\"]" + }, + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ] + } + ] + } + ], + "tags": [ + { + "tag": "Application", + "value": "Redis Server" + } + ], + "macros": [ + { + "macro": "{$REDIS_SERVER.CONNECTED_SLAVES.ENABLED}", + "value": "1" + }, + { + "macro": "{$REDIS_SERVER.EVICTED_KEYS.ENABLED}", + "value": "1" + }, + { + "macro": "{$REDIS_SERVER.EVICTED_KEYS.MAX}", + "value": "0.0" + }, + { + "macro": "{$REDIS_SERVER.EXCLUDED_STATS}" + }, + { + "macro": "{$REDIS_SERVER.ITEM_HISTORY_STORAGE_PERIOD}", + "value": "30d" + }, + { + "macro": "{$REDIS_SERVER.ITEM_TREND_STORAGE_PERIOD}", + "value": "365d" + }, + { + "macro": "{$REDIS_SERVER.ITEM_UPDATE_INTERVAL}", + "value": "1m" + }, + { + "macro": "{$REDIS_SERVER.LLD_EXCLUDED_SUBJECTS}", + "value": "^(?!)" + }, + { + "macro": "{$REDIS_SERVER.LLD_KEEP_LOST_RESOURCES_PERIOD}", + "value": "30d" + }, + { + "macro": "{$REDIS_SERVER.LLD_UPDATE_INTERVAL}", + "value": "1h" + }, + { + "macro": "{$REDIS_SERVER.LOCATIONS}" + }, + { + "macro": "{$REDIS_SERVER.PROCESSES.MIN}", + "value": "1" + }, + { + "macro": "{$REDIS_SERVER.UPTIME.MIN}", + "value": "10m" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/zabbix_agentd.conf.d/zabbix-agent-redis.conf b/zabbix_agentd.conf.d/zabbix-agent-redis.conf new file mode 100644 index 0000000..fd74238 --- /dev/null +++ b/zabbix_agentd.conf.d/zabbix-agent-redis.conf @@ -0,0 +1,3 @@ +# See https://github.com/allenta/zabbix-template-for-redis +UserParameter=redis_server.discovery[*],/usr/local/bin/zabbix-redis.py -i '$1' -t server --redis-password discover $2 2> /dev/null +UserParameter=redis_server.stats[*],/usr/local/bin/zabbix-redis.py -i '$1' -t server --redis-password stats 2> /dev/null