mirror of
https://github.com/netdata/netdata.git
synced 2025-05-21 16:27:14 +00:00

* collectors/python.d/adaptec_raid: format code * collectors/python.d/am2320: format code * collectors/python.d/apache: format code * collectors/python.d/beanstalk: format code * collectors/python.d/bind_rndc: format code * collectors/python.d/boinc: format code * collectors/python.d/ceph: format code * collectors/python.d/couchdb: format code * collectors/python.d/dns_query_time: format code * collectors/python.d/dnsdist: format code * collectors/python.d/dockerd: format code * collectors/python.d/dovecot: format code * collectors/python.d/energid: format code * collectors/python.d/example: format code * collectors/python.d/exim: format code * collectors/python.d/fail2ban: format code * collectors/python.d/freeradius: format code * collectors/python.d/gearman: format code * collectors/python.d/go_expvar: format code * collectors/python.d/haproxy: format code * collectors/python.d/hddtemp: format code * collectors/python.d/hpssa: format code * collectors/python.d/httpcheck: format code * collectors/python.d/icecast: format code * collectors/python.d/ipfs: format code * collectors/python.d/isc_dhcpd: format code * collectors/python.d/litespeed: format code * collectors/python.d/megacli: format code * collectors/python.d/memcached: format code * collectors/python.d/mongodb: format code * collectors/python.d/mysql: format code * collectors/python.d/nginx: format code * collectors/python.d/nginx_plus: format code * collectors/python.d/nsd: format code * collectors/python.d/ntpd: format code * collectors/python.d/openldap: format code * collectors/python.d/oracledb: format code * collectors/python.d/ovpn_status_log: format code * collectors/python.d/phpfpm: format code * collectors/python.d/portcheck: format code * collectors/python.d/powerdns: format code * collectors/python.d/proxysql: format code * collectors/python.d/puppet: format code * collectors/python.d/redis: format code * collectors/python.d/rethinkdbs: format code * collectors/python.d/retroshare: format code * collectors/python.d/riakkv: format code * collectors/python.d/samba: format code * collectors/python.d/sensors: format code * collectors/python.d/smartd_log: format code * collectors/python.d/spigotmc: format code * collectors/python.d/springboot: format code * collectors/python.d/squid: format code * collectors/python.d/tomcat: format code * collectors/python.d/tor: format code * collectors/python.d/traefik: format code * collectors/python.d/unbound: format code * collectors/python.d/uwsgi: format code * collectors/python.d/varnish: format code * collectors/python.d/w1sensor: format code * collectors/python.d/weblog: format code
197 lines
6.1 KiB
Python
197 lines
6.1 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Description: memcached netdata python.d module
|
|
# Author: Pawel Krupa (paulfantom)
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
from bases.FrameworkServices.SocketService import SocketService
|
|
|
|
ORDER = [
|
|
'cache',
|
|
'net',
|
|
'connections',
|
|
'items',
|
|
'evicted_reclaimed',
|
|
'get',
|
|
'get_rate',
|
|
'set_rate',
|
|
'cas',
|
|
'delete',
|
|
'increment',
|
|
'decrement',
|
|
'touch',
|
|
'touch_rate',
|
|
]
|
|
|
|
CHARTS = {
|
|
'cache': {
|
|
'options': [None, 'Cache Size', 'MiB', 'cache', 'memcached.cache', 'stacked'],
|
|
'lines': [
|
|
['avail', 'available', 'absolute', 1, 1 << 20],
|
|
['used', 'used', 'absolute', 1, 1 << 20]
|
|
]
|
|
},
|
|
'net': {
|
|
'options': [None, 'Network', 'kilobits/s', 'network', 'memcached.net', 'area'],
|
|
'lines': [
|
|
['bytes_read', 'in', 'incremental', 8, 1000],
|
|
['bytes_written', 'out', 'incremental', -8, 1000],
|
|
]
|
|
},
|
|
'connections': {
|
|
'options': [None, 'Connections', 'connections/s', 'connections', 'memcached.connections', 'line'],
|
|
'lines': [
|
|
['curr_connections', 'current', 'incremental'],
|
|
['rejected_connections', 'rejected', 'incremental'],
|
|
['total_connections', 'total', 'incremental']
|
|
]
|
|
},
|
|
'items': {
|
|
'options': [None, 'Items', 'items', 'items', 'memcached.items', 'line'],
|
|
'lines': [
|
|
['curr_items', 'current', 'absolute'],
|
|
['total_items', 'total', 'absolute']
|
|
]
|
|
},
|
|
'evicted_reclaimed': {
|
|
'options': [None, 'Items', 'items', 'items', 'memcached.evicted_reclaimed', 'line'],
|
|
'lines': [
|
|
['reclaimed', 'reclaimed', 'absolute'],
|
|
['evictions', 'evicted', 'absolute']
|
|
]
|
|
},
|
|
'get': {
|
|
'options': [None, 'Requests', 'requests', 'get ops', 'memcached.get', 'stacked'],
|
|
'lines': [
|
|
['get_hits', 'hits', 'percent-of-absolute-row'],
|
|
['get_misses', 'misses', 'percent-of-absolute-row']
|
|
]
|
|
},
|
|
'get_rate': {
|
|
'options': [None, 'Rate', 'requests/s', 'get ops', 'memcached.get_rate', 'line'],
|
|
'lines': [
|
|
['cmd_get', 'rate', 'incremental']
|
|
]
|
|
},
|
|
'set_rate': {
|
|
'options': [None, 'Rate', 'requests/s', 'set ops', 'memcached.set_rate', 'line'],
|
|
'lines': [
|
|
['cmd_set', 'rate', 'incremental']
|
|
]
|
|
},
|
|
'delete': {
|
|
'options': [None, 'Requests', 'requests', 'delete ops', 'memcached.delete', 'stacked'],
|
|
'lines': [
|
|
['delete_hits', 'hits', 'percent-of-absolute-row'],
|
|
['delete_misses', 'misses', 'percent-of-absolute-row'],
|
|
]
|
|
},
|
|
'cas': {
|
|
'options': [None, 'Requests', 'requests', 'check and set ops', 'memcached.cas', 'stacked'],
|
|
'lines': [
|
|
['cas_hits', 'hits', 'percent-of-absolute-row'],
|
|
['cas_misses', 'misses', 'percent-of-absolute-row'],
|
|
['cas_badval', 'bad value', 'percent-of-absolute-row']
|
|
]
|
|
},
|
|
'increment': {
|
|
'options': [None, 'Requests', 'requests', 'increment ops', 'memcached.increment', 'stacked'],
|
|
'lines': [
|
|
['incr_hits', 'hits', 'percent-of-absolute-row'],
|
|
['incr_misses', 'misses', 'percent-of-absolute-row']
|
|
]
|
|
},
|
|
'decrement': {
|
|
'options': [None, 'Requests', 'requests', 'decrement ops', 'memcached.decrement', 'stacked'],
|
|
'lines': [
|
|
['decr_hits', 'hits', 'percent-of-absolute-row'],
|
|
['decr_misses', 'misses', 'percent-of-absolute-row']
|
|
]
|
|
},
|
|
'touch': {
|
|
'options': [None, 'Requests', 'requests', 'touch ops', 'memcached.touch', 'stacked'],
|
|
'lines': [
|
|
['touch_hits', 'hits', 'percent-of-absolute-row'],
|
|
['touch_misses', 'misses', 'percent-of-absolute-row']
|
|
]
|
|
},
|
|
'touch_rate': {
|
|
'options': [None, 'Rate', 'requests/s', 'touch ops', 'memcached.touch_rate', 'line'],
|
|
'lines': [
|
|
['cmd_touch', 'rate', 'incremental']
|
|
]
|
|
}
|
|
}
|
|
|
|
|
|
class Service(SocketService):
|
|
def __init__(self, configuration=None, name=None):
|
|
SocketService.__init__(self, configuration=configuration, name=name)
|
|
self.order = ORDER
|
|
self.definitions = CHARTS
|
|
self.request = 'stats\r\n'
|
|
self.host = 'localhost'
|
|
self.port = 11211
|
|
self._keep_alive = True
|
|
self.unix_socket = None
|
|
|
|
def _get_data(self):
|
|
"""
|
|
Get data from socket
|
|
:return: dict
|
|
"""
|
|
response = self._get_raw_data()
|
|
if response is None:
|
|
# error has already been logged
|
|
return None
|
|
|
|
if response.startswith('ERROR'):
|
|
self.error('received ERROR')
|
|
return None
|
|
|
|
try:
|
|
parsed = response.split('\n')
|
|
except AttributeError:
|
|
self.error('response is invalid/empty')
|
|
return None
|
|
|
|
# split the response
|
|
data = {}
|
|
for line in parsed:
|
|
if line.startswith('STAT'):
|
|
try:
|
|
t = line[5:].split(' ')
|
|
data[t[0]] = t[1]
|
|
except (IndexError, ValueError):
|
|
self.debug('invalid line received: ' + str(line))
|
|
|
|
if not data:
|
|
self.error("received data doesn't have any records")
|
|
return None
|
|
|
|
# custom calculations
|
|
try:
|
|
data['avail'] = int(data['limit_maxbytes']) - int(data['bytes'])
|
|
data['used'] = int(data['bytes'])
|
|
except (KeyError, ValueError, TypeError):
|
|
pass
|
|
|
|
return data
|
|
|
|
def _check_raw_data(self, data):
|
|
if data.endswith('END\r\n'):
|
|
self.debug('received full response from memcached')
|
|
return True
|
|
|
|
self.debug('waiting more data from memcached')
|
|
return False
|
|
|
|
def check(self):
|
|
"""
|
|
Parse configuration, check if memcached is available
|
|
:return: boolean
|
|
"""
|
|
self._parse_config()
|
|
data = self._get_data()
|
|
if data is None:
|
|
return False
|
|
return True
|