Monitoring or Logs for Bandwidth Usage Per User

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)