1<?php
2
3use App\Models\Mempool;
4
5require 'includes/html/graphs/common.inc.php';
6
7$rrd_options .= ' -E -b 1024 ';
8
9// order mempools properly
10$mempool_classes = [
11    'system' => 0,
12    'buffers' => 1,
13    'cached' => 2,
14    'available' => 3,
15    'shared' => 4,
16    'swap' => 5,
17    'virtual' => 6,
18];
19$mempools = DeviceCache::get($device['device_id'])->mempools->sort(function (Mempool $a_weight, Mempool $b_weight) use ($mempool_classes) {
20    $a_weight = $mempool_classes[$a_weight->mempool_class] ?? 99;
21    $b_weight = $mempool_classes[$b_weight->mempool_class] ?? 99;
22    if ($a_weight == $b_weight) {
23        return 0;
24    }
25
26    return $a_weight < $b_weight ? -1 : 1;
27})->values();
28
29// find available
30$available = null;
31$swap_present = false;
32foreach ($mempools as $index => $mempool) {
33    if ($mempool->mempool_class == 'available') {
34        $available = $mempool;
35        $mempools->forget($index);
36    } elseif ($mempool->mempool_class == 'swap') {
37        $swap_present = true;
38    }
39}
40
41if (! $swap_present) {
42    $rrd_options .= '-l 0 '; // swap is negative axis
43}
44
45$colors = \LibreNMS\Config::get('graph_colours.varied');
46$legend_sections = [0 => '', 1 => ''];
47$section = 0;
48$free_indexes = [];
49$rrd_options .= " COMMENT:'                            Min   Max    Cur      \\n'";
50
51/** @var \App\Models\Mempool $mempool */
52foreach ($mempools as $index => $mempool) {
53    $color = $colors[$index % 8];
54
55    $descr = \LibreNMS\Data\Store\Rrd::fixedSafeDescr($mempool->mempool_descr, 22);
56    $rrd_filename = Rrd::name($device['hostname'], ['mempool', $mempool->mempool_type, $mempool->mempool_class, $mempool->mempool_index]);
57
58    if (Rrd::checkRrdExists($rrd_filename)) {
59        $rrd_options .= " DEF:mempoolfree$index=$rrd_filename:free:AVERAGE ";
60        $rrd_options .= " DEF:mempoolused$index=$rrd_filename:used:AVERAGE ";
61        $rrd_options .= " CDEF:mempooltotal$index=mempoolused$index,mempoolfree$index,+ ";
62        $rrd_options .= " CDEF:mempoolpercent$index=mempoolused$index,mempooltotal$index,/,100,* ";
63
64        $system_pools = in_array($mempool->mempool_class, ['system', 'cached', 'buffers']);
65        $stack = $system_pools && $index > 0 ? ':STACK' : '';
66        if ($system_pools) {
67            $free_indexes[] = $index;
68            $rrd_options .= " AREA:mempoolused$index#{$color}70:$stack";
69        }
70
71        if ($mempool->mempool_class == 'system') {
72            // add system
73            $legend_sections[1] .= " LINE1:mempooltotal$index#AAAAAA:'Total                                     '";
74            $legend_sections[1] .= " GPRINT:mempooltotal$index:LAST:%6.2lf%siB\\l ";
75        }
76        if ($mempool->mempool_class == 'swap') {
77            $section = 2;
78            $rrd_options .= " CDEF:mempoolswap$index=mempoolused$index,-1,* ";
79            $rrd_options .= " AREA:mempoolswap$index#{$color}70:$stack";
80            $legend_sections[$section] .= " LINE1.5:mempoolswap$index#$color:'$descr'$stack";
81        } elseif ($mempool->mempool_class == 'virtual') {
82            $section = 2;
83            $legend_sections[$section] .= " COMMENT:'  $descr'";
84        } else {
85            $legend_sections[$section] .= " LINE1.5:mempoolused$index#$color:'$descr'$stack";
86        }
87
88        $legend_sections[$section] .= " GPRINT:mempoolpercent$index:MIN:%3.0lf%%";
89        $legend_sections[$section] .= " GPRINT:mempoolpercent$index:MAX:%3.0lf%%";
90        $legend_sections[$section] .= " GPRINT:mempoolpercent$index:LAST:%3.0lf%%";
91        $legend_sections[$section] .= " GPRINT:mempoolused$index:LAST:%6.2lf%siB\\l ";
92    }
93}
94
95// add free/availability calculations if we have buffers/cached
96if (! empty($free_indexes)) {
97    $mempool_classes = $mempools->pluck('mempool_class');
98    if ($mempool_classes->contains('buffers') || $mempool_classes->contains('cached')) {
99        $rrd_options .= ' CDEF:mempoolfree=100,mempoolpercent' . implode(',mempoolpercent', $free_indexes) . str_repeat(',-', count($free_indexes));
100        $rrd_options .= " CDEF:mempoolfreebytes=mempoolfree{$free_indexes[0]},mempoolused{$free_indexes[0]},+,mempoolfree,100,/,*";
101        $legend_sections[1] .= " COMMENT:'  Free memory            '";
102        $legend_sections[1] .= ' GPRINT:mempoolfree:MIN:%3.0lf%%';
103        $legend_sections[1] .= ' GPRINT:mempoolfree:LAST:%3.0lf%%';
104        $legend_sections[1] .= ' GPRINT:mempoolfree:MAX:%3.0lf%%';
105        $legend_sections[1] .= ' GPRINT:mempoolfreebytes:LAST:%6.2lf%siB\l';
106
107        if ($available === null) {
108            $rrd_options .= " CDEF:mempoolavailablebytes=mempoolfree{$free_indexes[0]}";
109        } else {
110            $available_filename = Rrd::name($device['hostname'], ['mempool', $available->mempool_type, $available->mempool_class, $available->mempool_index]);
111            $rrd_options .= " DEF:mempoolavailablebytes=$available_filename:free:AVERAGE";
112        }
113
114        $rrd_options .= " CDEF:mempoolavailable=100,mempoolpercent{$free_indexes[0]},-";
115        $legend_sections[1] .= " COMMENT:'  Available memory       '";
116        $legend_sections[1] .= ' GPRINT:mempoolavailable:MIN:%3.0lf%%';
117        $legend_sections[1] .= ' GPRINT:mempoolavailable:LAST:%3.0lf%%';
118        $legend_sections[1] .= ' GPRINT:mempoolavailable:MAX:%3.0lf%%';
119        $legend_sections[1] .= ' GPRINT:mempoolavailablebytes:LAST:%6.2lf%siB\l';
120    }
121}
122
123$rrd_options .= implode(" COMMENT:' \\l'", $legend_sections);
124
125$rrd_options .= ' HRULE:0#999999';
126