improve rrd graph display

This commit is contained in:
Eduardo Silva 2025-02-21 21:59:30 -03:00
parent 3afae967d7
commit 60a43070d8
2 changed files with 49 additions and 8 deletions

View File

@ -49,9 +49,35 @@
<div class="col-lg-6"> <div class="col-lg-6">
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<img src="/rrd/graph/?peer={{ current_peer.uuid }}"> <label>
<i class="fas fa-chart-area"></i>
Peer Traffic History
</label>
</div> </div>
</div> </div>
<div class="row">
<div class="col-lg-12">
<center>
<img id="graphImg" src="/rrd/graph/?peer={{ current_peer.uuid }}{% if request.GET.period %}&period={{ request.GET.period }}{% endif %}" class="img-fluid" alt="No traffic history, please wait a few minutes">
</center>
</div>
</div>
<div class="row mt-3">
<div class="col-lg-12 text-center">
<div class="btn-group" role="group" aria-label="Graph interval">
<a href="#" data-period="1h" class="btn btn-outline-primary btn-xs">1h</a>
<a href="#" data-period="3h" class="btn btn-outline-primary btn-xs">3h</a>
<a href="#" data-period="6h" class="btn btn-outline-primary btn-xs">6h</a>
<a href="#" data-period="7d" class="btn btn-outline-primary btn-xs">7d</a>
<a href="#" data-period="30d" class="btn btn-outline-primary btn-xs">30d</a>
<a href="#" data-period="90d" class="btn btn-outline-primary btn-xs">3m</a>
<a href="#" data-period="180d" class="btn btn-outline-primary btn-xs">6m</a>
<a href="#" data-period="365d" class="btn btn-outline-primary btn-xs">1y</a>
</div>
</div>
</div>
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div class="d-flex justify-content-between align-items-center"> <div class="d-flex justify-content-between align-items-center">
@ -208,4 +234,22 @@
</script> </script>
<script>
document.addEventListener('DOMContentLoaded', function(){
var buttons = document.querySelectorAll('.btn-group a');
buttons.forEach(function(button){
button.addEventListener('click', function(e){
e.preventDefault();
var period = this.getAttribute('data-period');
var newSrc = '/rrd/graph/?peer={{ current_peer.uuid }}&period=' + period;
var imgElement = document.getElementById('graphImg');
if(imgElement){
imgElement.setAttribute('src', newSrc);
}
});
});
});
</script>
{% endblock %} {% endblock %}

View File

@ -26,10 +26,12 @@ def view_rrd_graph(request):
graph_type = 'peer' graph_type = 'peer'
rrd_filename = base64.urlsafe_b64encode(peer.public_key.encode()).decode().replace('=', '') rrd_filename = base64.urlsafe_b64encode(peer.public_key.encode()).decode().replace('=', '')
rrd_file_path = f'/rrd_data/peers/{rrd_filename}.rrd' rrd_file_path = f'/rrd_data/peers/{rrd_filename}.rrd'
graph_title = f'Peer {peer}'
elif request.GET.get('instance'): elif request.GET.get('instance'):
wireguard_instance = get_object_or_404(WireGuardInstance, uuid=request.GET.get('instance')) wireguard_instance = get_object_or_404(WireGuardInstance, uuid=request.GET.get('instance'))
graph_type = 'instance' graph_type = 'instance'
rrd_file_path = f'/rrd_data/wginstances/wg{wireguard_instance.instance_id}.rrd' rrd_file_path = f'/rrd_data/wginstances/wg{wireguard_instance.instance_id}.rrd'
graph_title = f'WG{wireguard_instance.instance_id}'
else: else:
raise Http404 raise Http404
@ -42,10 +44,11 @@ def view_rrd_graph(request):
period = request.GET.get('period', '6h') period = request.GET.get('period', '6h')
if not (period[:-1].isdigit() and period[-1] in ['h', 'd']): if not (period[:-1].isdigit() and period[-1] in ['h', 'd']):
period = '6h' period = '6h'
command = [ command = [
"rrdtool", "graph", graph_file, "rrdtool", "graph", graph_file,
"--start", f"-{period}", "--start", f"-{period}",
"--title", "RRD Data Graph", "--title", f"{graph_title} - traffic",
"--vertical-label", "Value", "--vertical-label", "Value",
f"DEF:txdata={rrd_file_path}:tx:AVERAGE", f"DEF:txdata={rrd_file_path}:tx:AVERAGE",
f"DEF:rxdata={rrd_file_path}:rx:AVERAGE", f"DEF:rxdata={rrd_file_path}:rx:AVERAGE",
@ -62,17 +65,11 @@ def view_rrd_graph(request):
] ]
try: try:
# Execute the command using subprocess
subprocess.run(command, check=True, stdout=subprocess.PIPE) subprocess.run(command, check=True, stdout=subprocess.PIPE)
# Open and read the generated image file
with open(graph_file, 'rb') as f: with open(graph_file, 'rb') as f:
image_data = f.read() image_data = f.read()
finally: finally:
# Clean up the temporary file
os.remove(graph_file) os.remove(graph_file)
# Return the image data as an HTTP response with PNG content type
return HttpResponse(image_data, content_type="image/png") return HttpResponse(image_data, content_type="image/png")