summaryrefslogtreecommitdiffstats
path: root/python.d/ovpn_status_log.chart.py
diff options
context:
space:
mode:
Diffstat (limited to 'python.d/ovpn_status_log.chart.py')
-rw-r--r--python.d/ovpn_status_log.chart.py94
1 files changed, 65 insertions, 29 deletions
diff --git a/python.d/ovpn_status_log.chart.py b/python.d/ovpn_status_log.chart.py
index c5fca002a..3a7e8200d 100644
--- a/python.d/ovpn_status_log.chart.py
+++ b/python.d/ovpn_status_log.chart.py
@@ -2,8 +2,10 @@
# Description: openvpn status log netdata python.d module
# Author: l2isbad
+from re import compile as r_compile
+from collections import defaultdict
from base import SimpleService
-from re import compile, findall, search, subn
+
priority = 60000
retries = 60
update_every = 10
@@ -11,67 +13,101 @@ update_every = 10
ORDER = ['users', 'traffic']
CHARTS = {
'users': {
- 'options': [None, 'OpenVPN active users', 'active users', 'Users', 'openvpn_status.users', 'line'],
+ 'options': [None, 'OpenVPN Active Users', 'active users', 'users', 'openvpn_status.users', 'line'],
'lines': [
- ["users", None, "absolute"],
+ ['users', None, 'absolute'],
]},
'traffic': {
- 'options': [None, 'OpenVPN traffic', 'kilobit/s', 'Traffic', 'openvpn_status.traffic', 'area'],
+ 'options': [None, 'OpenVPN Traffic', 'KB/s', 'traffic', 'openvpn_status.traffic', 'area'],
'lines': [
- ["in", None, "incremental", 8, 1000], ["out", None, "incremental", 8, -1000]
+ ['bytes_in', 'in', 'incremental', 1, 1 << 10], ['bytes_out', 'out', 'incremental', 1, -1 << 10]
]},
}
+
class Service(SimpleService):
def __init__(self, configuration=None, name=None):
SimpleService.__init__(self, configuration=configuration, name=name)
self.order = ORDER
self.definitions = CHARTS
self.log_path = self.configuration.get('log_path')
- self.regex_data_inter = compile(r'(?<=Since ).*?(?=.ROUTING)')
- self.regex_data_final = compile(r'\d{1,3}(?:\.\d{1,3}){3}[:0-9,. ]*')
- self.regex_users = compile(r'\d{1,3}(?:\.\d{1,3}){3}:\d+')
- self.regex_traffic = compile(r'(?<=(?:,| ))\d+(?=(?:,| ))')
+ self.regex = dict(tls=r_compile(r'\d{1,3}(?:\.\d{1,3}){3}(?::\d+)? (?P<bytes_in>\d+) (?P<bytes_out>\d+)'),
+ static_key=r_compile(r'TCP/[A-Z]+ (?P<direction>(?:read|write)) bytes,(?P<bytes>\d+)'))
+ self.to_netdata = dict(bytes_in=0, bytes_out=0)
def check(self):
- if not self._get_raw_data():
- self.error('Make sure that the openvpn status log file exists and netdata has permission to read it')
+ if not (self.log_path and isinstance(self.log_path, str)):
+ self.error('\'log_path\' is not defined')
return False
- else:
- self.info('Plugin was started succesfully')
+
+ data = False
+ for method in (self._get_data_tls, self._get_data_static_key):
+ data = method()
+ if data:
+ self._get_data = method
+ self._data_from_check = data
+ break
+
+ if data:
return True
+ self.error('Make sure that the openvpn status log file exists and netdata has permission to read it')
+ return False
def _get_raw_data(self):
"""
Open log file
:return: str
"""
+
try:
- with open(self.log_path, 'rt') as log:
- result = log.read()
- except Exception:
+ with open(self.log_path) as log:
+ raw_data = log.readlines() or None
+ except OSError:
return None
else:
- return result
+ return raw_data
- def _get_data(self):
+ def _get_data_static_key(self):
"""
Parse openvpn-status log file.
- Current regex version is ok for status-version 1, 2 and 3. Both users and bytes in/out are collecting.
"""
raw_data = self._get_raw_data()
- try:
- data_inter = self.regex_data_inter.search(' '.join(raw_data.splitlines())).group()
- except AttributeError:
- data_inter = ''
+ if not raw_data:
+ return None
+
+ data = defaultdict(lambda: 0)
+
+ for row in raw_data:
+ match = self.regex['static_key'].search(row)
+ if match:
+ match = match.groupdict()
+ if match['direction'] == 'read':
+ data['bytes_in'] += int(match['bytes'])
+ else:
+ data['bytes_out'] += int(match['bytes'])
+
+ return data or None
+
+ def _get_data_tls(self):
+ """
+ Parse openvpn-status log file.
+ """
+
+ raw_data = self._get_raw_data()
+ if not raw_data:
+ return None
- data_final = ' '.join(self.regex_data_final.findall(data_inter))
- users = self.regex_users.subn('', data_final)[1]
- traffic = self.regex_traffic.findall(data_final)
+ data = defaultdict(lambda: 0)
+ for row in raw_data:
+ row = ' '.join(row.split(',')) if ',' in row else ' '.join(row.split())
+ match = self.regex['tls'].search(row)
+ if match:
+ match = match.groupdict()
+ data['users'] += 1
+ data['bytes_in'] += int(match['bytes_in'])
+ data['bytes_out'] += int(match['bytes_out'])
- bytes_in = sum([int(traffic[i]) for i in range(len(traffic)) if (i + 1) % 2 is 1])
- bytes_out = sum([int(traffic[i]) for i in range(len(traffic)) if (i + 1) % 2 is 0])
+ return data or None
- return {'users': users, 'in': bytes_in, 'out': bytes_out}