Is there even such a thing? I know we have one on server level, but I need it per user level. Is there some resources or examples I could read if I would like to make a PR for this or is there any other consideration for not including this feature? Thank you.
Pritunl doesn’t log bandwidth usage.
Is it planned to add this feature? We have an enterprise license, and this feature is essential to understand and monitor whether a user is consuming bandwidth excessively.
This data is sent to InfluxDB if that is configured.
The handler user_bandwidth has been added to also send this data to the plugin system. This is called every 15 seconds with the users bandwidth for that period. The rate can be adjusted with sudo pritunl set vpn.bandwidth_update_rate 15. The new plugin handler won’t be available until the next release.
If InfluxDB is not used, but we’d like to have logs written by the plugin system, can we increase the interval to for example, 1 hour, or is there a limit above which the bandwidth is not properly tracked anymore?
It shouldn’t be increased past 60 seconds. The hour interval should instead be handled by the plugin, below is an example on how this can be done.
from pritunl import logger
import threading
_lock = threading.Lock()
_period_start = None
_period_totals = {}
def _flush_period(period_start, period_totals):
for totals in period_totals.values():
logger.info('User bandwidth hourly', 'plugin',
period_start=period_start,
host_id=totals['host_id'],
host_name=totals['host_name'],
server_id=totals['server_id'],
server_name=totals['server_name'],
org_id=totals['org_id'],
org_name=totals['org_name'],
user_id=totals['user_id'],
user_name=totals['user_name'],
device_id=totals['device_id'],
device_name=totals['device_name'],
remote_ip=totals['remote_ip'],
virtual_ip=totals['virtual_ip'],
virtual_ip6=totals['virtual_ip6'],
bytes_sent=totals['bytes_sent'],
bytes_recv=totals['bytes_recv'],
samples=totals['samples'],
)
def user_bandwidth(host_id, server_id, org_id, user_id, device_id,
host_name, server_name, org_name, user_name, device_name,
remote_ip, virtual_ip, virtual_ip6, timestamp,
bytes_sent, bytes_recv, **kwargs):
global _period_start
global _period_totals
period_start = timestamp.replace(minute=0, second=0, microsecond=0)
key = (server_id, org_id, user_id, device_id)
flush_start = None
flush_totals = None
with _lock:
if _period_start is None:
_period_start = period_start
elif period_start > _period_start:
flush_start = _period_start
flush_totals = _period_totals
_period_start = period_start
_period_totals = {}
elif period_start < _period_start:
period_start = _period_start
totals = _period_totals.get(key)
if totals is None:
totals = {
'host_id': host_id,
'host_name': host_name,
'server_id': server_id,
'server_name': server_name,
'org_id': org_id,
'org_name': org_name,
'user_id': user_id,
'user_name': user_name,
'device_id': device_id,
'device_name': device_name,
'remote_ip': remote_ip,
'virtual_ip': virtual_ip,
'virtual_ip6': virtual_ip6,
'bytes_sent': 0,
'bytes_recv': 0,
'samples': 0,
}
_period_totals[key] = totals
else:
totals['remote_ip'] = remote_ip
totals['virtual_ip'] = virtual_ip
totals['virtual_ip6'] = virtual_ip6
totals['bytes_sent'] += bytes_sent or 0
totals['bytes_recv'] += bytes_recv or 0
totals['samples'] += 1
if flush_totals:
_flush_period(flush_start, flush_totals)