Python and Shell fixes + apache and nginx python modules.
END
BEGIN apache.conns_async $1
SET keepalive = $((apache_connsasynckeepalive))
-SET closing = $((apache_connsasyncwriting))
+SET closing = $((apache_connsasyncclosing))
SET writing = $((apache_connsasyncwriting))
END
VALUESEOF2
dist_pythonconfig_DATA = \
python.d/example.conf \
python.d/mysql.conf \
+ python.d/phpfpm.conf \
$(NULL)
example: yes
mysql: yes
phpfpm: yes
+apache: yes
+nginx: yes
# scan directory specified in path and load all modules from there
names = os.listdir(path)
for mod in names:
- if mod.strip(MODULE_EXTENSION) in disabled:
- error(mod + ": disabled module ", mod.strip(MODULE_EXTENSION))
+ if mod.replace(MODULE_EXTENSION, "") in disabled:
+ error(mod + ": disabled module ", mod.replace(MODULE_EXTENSION, ""))
continue
m = self._import_module(path + mod)
if m is not None:
if os.path.isfile(configfile):
debug(mod.__name__ + ": loading module configuration: '" + configfile + "'")
try:
+ if not hasattr(mod, 'config'):
+ mod.config = {}
setattr(mod,
'config',
self._parse_config(mod, read_config(configfile)))
try:
# get defaults from module source code
defaults[key] = getattr(module, key)
- except (KeyError, ValueError):
+ except (KeyError, ValueError, AttributeError):
# if above failed, get defaults from global dict
defaults[key] = BASE_CONFIG[key]
i += 1
if len(next_runs) == 0:
fatal('no python.d modules loaded.')
- time.sleep(min(next_runs) - time.time())
+ try:
+ time.sleep(min(next_runs) - time.time())
+ except IOError:
+ pass
def read_config(path):
pass
if changed_update and DEBUG_FLAG:
OVERRIDE_UPDATE_EVERY = True
- debug(PROGRAM, "overriding update interval to", str(int(cmd)))
+ debug(PROGRAM, "overriding update interval to", str(BASE_CONFIG['update_every']))
debug("started from", commands[0], "with options:", *commands[1:])
dist_python_SCRIPTS = \
example.chart.py \
mysql.chart.py \
+ phpfpm.chart.py \
+ apache.chart.py \
+ nginx.chart.py \
python-modules-installer.sh \
$(NULL)
--- /dev/null
+# -*- coding: utf-8 -*-
+# Description: apache netdata python.d plugin
+# Author: Pawel Krupa (paulfantom)
+
+from base import UrlService
+
+# default module values (can be overridden per job in `config`)
+# update_every = 2
+priority = 60000
+retries = 5
+
+# default job configuration (overridden by python.d.plugin)
+# config = {'local': {
+# 'update_every': update_every,
+# 'retries': retries,
+# 'priority': priority,
+# 'url': 'http://www.apache.org/server-status?auto'
+# }}
+
+# charts order (can be overridden if you want less charts, or different order)
+ORDER = ['requests', 'connections', 'conns_async', 'net', 'workers', 'reqpersec', 'bytespersec', 'bytesperreq']
+
+CHARTS = {
+ 'bytesperreq': {
+ 'options': "'' 'apache Lifetime Avg. Response Size' 'bytes/request' statistics apache.bytesperreq area",
+ 'lines': [
+ {"name": "size_req",
+ "options": "'' absolute 1 1"}
+ ]},
+ 'workers': {
+ 'options': "'' 'apache Workers' 'workers' workers apache.workers stacked",
+ 'lines': [
+ {"name": "idle",
+ "options": "'' absolute 1 1"},
+ {"name": "busy",
+ "options": "'' absolute 1 1"}
+ ]},
+ 'reqpersec': {
+ 'options': "'' 'apache Lifetime Avg. Requests/s' 'requests/s' statistics apache.reqpersec area",
+ 'lines': [
+ {"name": "requests_sec",
+ "options": "'' absolute 1 1"}
+ ]},
+ 'bytespersec': {
+ 'options': "'' 'apache Lifetime Avg. Bandwidth/s' 'kilobytes/s' statistics apache.bytesperreq area",
+ 'lines': [
+ {"name": "size_sec",
+ "options": "'' absolute 1 1000"}
+ ]},
+ 'requests': {
+ 'options': "'' 'apache Requests' 'requests/s' requests apache.requests line",
+ 'lines': [
+ {"name": "requests",
+ "options": "'' incremental 1 1"}
+ ]},
+ 'net': {
+ 'options': "'' 'apache Bandwidth' 'kilobytes/s' bandwidth apache.net area",
+ 'lines': [
+ {"name": "sent",
+ "options": "'' incremental 1 1"}
+ ]},
+ 'connections': {
+ 'options': "'' 'apache Connections' 'connections' connections apache.connections line",
+ 'lines': [
+ {"name": "connections",
+ "options": "'' absolute 1 1"}
+ ]},
+ 'conns_async': {
+ 'options': "'' 'apache Async Connections' 'connections' connections apache.conns_async stacked",
+ 'lines': [
+ {"name": "keepalive",
+ "options": "'' absolute 1 1"},
+ {"name": "closing",
+ "options": "'' absolute 1 1"},
+ {"name": "writing",
+ "options": "'' absolute 1 1"}
+ ]}
+}
+
+
+class Service(UrlService):
+ def __init__(self, configuration=None, name=None):
+ UrlService.__init__(self, configuration=configuration, name=name)
+ if len(self.url) == 0:
+ self.url = "http://localhost/server-status?auto"
+ self.order = ORDER
+ self.charts = CHARTS
+ self.assignment = {"BytesPerReq": 'size_req',
+ "IdleWorkers": 'idle',
+ "BusyWorkers": 'busy',
+ "ReqPerSec": 'requests_sec',
+ "BytesPerSec": 'size_sec',
+ "Total Accesses": 'requests',
+ "Total kBytes": 'sent',
+ "ConnsTotal": 'connections',
+ "ConnsAsyncKeepAlive": 'keepalive',
+ "ConnsAsyncClosing": 'closing',
+ "ConnsAsyncWriting": 'writing'}
+
+ def _formatted_data(self):
+ """
+ Format data received from http request
+ :return: dict
+ """
+ try:
+ raw = self._get_data().split("\n")
+ except AttributeError:
+ return None
+ data = {}
+ for row in raw:
+ tmp = row.split(":")
+ if str(tmp[0]) in self.assignment:
+ try:
+ data[self.assignment[tmp[0]]] = int(float(tmp[1]))
+ except (IndexError, ValueError) as a:
+ print(a)
+ pass
+ if len(data) == 0:
+ return None
+ return data
--- /dev/null
+# -*- coding: utf-8 -*-
+# Description: nginx netdata python.d plugin
+# Author: Pawel Krupa (paulfantom)
+
+from base import UrlService
+
+# default module values (can be overridden per job in `config`)
+# update_every = 2
+priority = 60000
+retries = 5
+
+# default job configuration (overridden by python.d.plugin)
+# config = {'local': {
+# 'update_every': update_every,
+# 'retries': retries,
+# 'priority': priority,
+# 'url': 'http://localhost/stub_status'
+# }}
+
+# charts order (can be overridden if you want less charts, or different order)
+ORDER = ['connections', 'requests', 'connection_status', 'connect_rate']
+
+CHARTS = {
+ 'connections': {
+ 'options': "'' 'nginx Active Connections' 'connections' nginx nginx.connections line",
+ 'lines': [
+ {"name": "active",
+ "options": "'' absolute 1 1"}
+ ]},
+ 'requests': {
+ 'options': "'' 'nginx Requests' 'requests/s' nginx nginx.requests line",
+ 'lines': [
+ {"name": "requests",
+ "options": "'' incremental 1 1"}
+ ]},
+ 'connection_status': {
+ 'options': "'' 'nginx Active Connections by Status' 'connections' nginx nginx.connection.status line",
+ 'lines': [
+ {"name": "reading",
+ "options": "'' absolute 1 1"},
+ {"name": "writing",
+ "options": "'' absolute 1 1"},
+ {"name": "waiting",
+ "options": "idle absolute 1 1"}
+ ]},
+ 'connect_rate': {
+ 'options': "'' 'nginx Connections Rate' 'connections/s' nginx nginx.performance line",
+ 'lines': [
+ {"name": "accepts",
+ "options": "accepted incremental 1 1"},
+ {"name": "handled",
+ "options": "'' incremental 1 1"}
+ ]}
+}
+
+
+class Service(UrlService):
+ def __init__(self, configuration=None, name=None):
+ UrlService.__init__(self, configuration=configuration, name=name)
+ if len(self.url) == 0:
+ self.url = "http://localhost/stub_status"
+ self.order = ORDER
+ self.charts = CHARTS
+
+ def _formatted_data(self):
+ """
+ Format data received from http request
+ :return: dict
+ """
+ try:
+ raw = self._get_data().split(" ")
+ return {'active': int(raw[2]),
+ 'requests': int(raw[7]),
+ 'reading': int(raw[11]),
+ 'writing': int(raw[13]),
+ 'waiting': int(raw[15]),
+ 'accepts': int(raw[8]),
+ 'handled': int(raw[9])}
+ except (ValueError, AttributeError):
+ return None
# default module values (can be overridden per job in `config`)
# update_every = 2
-# priority = 60000
-# retries = 5
+priority = 60000
+retries = 5
# default job configuration (overridden by python.d.plugin)
# config = {'local': {
class Service(UrlService):
- url = "http://localhost/status"
- order = ORDER
- charts = CHARTS
- assignment = {"active processes": 'active',
- "max active processes": 'maxActive',
- "idle processes": 'idle',
- "accepted conn": 'requests',
- "max children reached": 'reached',
- "slow requests": 'slow'}
+ def __init__(self, configuration=None, name=None):
+ UrlService.__init__(self, configuration=configuration, name=name)
+ if len(self.url) == 0:
+ self.url = "http://localhost/status"
+ self.order = ORDER
+ self.charts = CHARTS
+ self.assignment = {"active processes": 'active',
+ "max active processes": 'maxActive',
+ "idle processes": 'idle',
+ "accepted conn": 'requests',
+ "max children reached": 'reached',
+ "slow requests": 'slow'}
def _formatted_data(self):
"""
Format data received from http request
:return: dict
"""
- raw = self._get_data().split('\n')
+ try:
+ raw = self._get_data().split('\n')
+ except AttributeError:
+ return None
data = {}
for row in raw:
tmp = row.split(":")
if str(tmp[0]) in self.assignment:
try:
data[self.assignment[tmp[0]]] = int(tmp[1])
- except (IndexError, ValueError) as a:
+ except (IndexError, ValueError):
pass
+ if len(data) == 0:
+ return None
return data
class UrlService(BaseService):
- charts = {}
- # charts definitions in format:
- # charts = {
- # 'chart_name_in_netdata': {
- # 'options': "parameters defining chart (passed to CHART statement)",
- # 'lines': [
- # { 'name': 'dimension_name',
- # 'options': 'dimension parameters (passed to DIMENSION statement)"
- # }
- # ]}
- # }
- order = []
- definitions = {}
- # definitions are created dynamically in create() method based on 'charts' dictionary. format:
- # definitions = {
- # 'chart_name_in_netdata' : [ charts['chart_name_in_netdata']['lines']['name'] ]
- # }
- url = ""
+ def __init__(self, configuration=None, name=None):
+ self.charts = {}
+ # charts definitions in format:
+ # charts = {
+ # 'chart_name_in_netdata': {
+ # 'options': "parameters defining chart (passed to CHART statement)",
+ # 'lines': [
+ # { 'name': 'dimension_name',
+ # 'options': 'dimension parameters (passed to DIMENSION statement)"
+ # }
+ # ]}
+ # }
+ self.order = []
+ self.definitions = {}
+ # definitions are created dynamically in create() method based on 'charts' dictionary. format:
+ # definitions = {
+ # 'chart_name_in_netdata' : [ charts['chart_name_in_netdata']['lines']['name'] ]
+ # }
+ self.url = ""
+ BaseService.__init__(self, configuration=configuration, name=name)
def _get_data(self):
"""
Get raw data from http request
:return: str
"""
+ raw = None
try:
- f = urlopen(self.url)
+ f = urlopen(self.url, timeout=self.update_every)
raw = f.read().decode('utf-8')
- f.close()
except Exception as e:
self.error(self.__module__, str(e))
- return None
+ finally:
+ try:
+ f.close()
+ except:
+ pass
return raw
def _formatted_data(self):
info: undefined,
},
+/* 'nginx': {
+ title: 'nginx',
+ info: undefined,
+ },
+
+ 'apache': {
+ title: 'Apache',
+ info: undefined,
+ },*/
+
'named': {
title: 'named',
info: undefined
case 'mysql':
case 'phpfpm':
+/* case 'nginx':
+ case 'apache':*/
case 'named':
case 'cgroup':
chart.menu = chart.type;