update
This commit is contained in:
parent
ed39ebe568
commit
f5f7f8c017
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
.*
|
||||
src
|
||||
test
|
||||
rrd/*.rrd
|
21
cgi-bin/details.pl
Executable file
21
cgi-bin/details.pl
Executable file
@ -0,0 +1,21 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Template;
|
||||
use CGI;
|
||||
use CGI::Carp qw(fatalsToBrowser);
|
||||
|
||||
my $cgi = new CGI;
|
||||
my $var = {
|
||||
GRAPH => $cgi->param('graph')
|
||||
};
|
||||
|
||||
my $template = Template->new({
|
||||
INCLUDE_PATH => '/var/www/mrtg/tmpl',
|
||||
INTERPOLATE => 1,
|
||||
});
|
||||
|
||||
$|++;
|
||||
print $cgi->header();
|
||||
$template->process('details.tmpl',$var);
|
@ -16,9 +16,25 @@ print $cgi->header(-type => "image/png");# unless($ARGV[0]);
|
||||
|
||||
if($graph) {
|
||||
if(open(RRD,"<$TMPLpath/$graph.tmpl")) {
|
||||
my @opts = <RRD>;
|
||||
my @rrd = <RRD>;
|
||||
close(RRD);
|
||||
chomp(@opts);
|
||||
chomp(@rrd);
|
||||
my @opts;
|
||||
|
||||
if($cgi->param('start')) {
|
||||
push @opts,"--start=" . $cgi->param('start');
|
||||
}
|
||||
if($cgi->param('end')) {
|
||||
push @opts,"--end=" . $cgi->param('end');
|
||||
}
|
||||
if($cgi->param('width')) {
|
||||
push @opts,"-w ".$cgi->param('width');
|
||||
}
|
||||
if($cgi->param('height')) {
|
||||
push @opts,"-h ".$cgi->param('height');
|
||||
}
|
||||
|
||||
push @opts,@rrd;
|
||||
RRDs::graph("-",@opts) or die(RRDs::error);
|
||||
}
|
||||
}
|
||||
|
41
config/br0tkasten.cfg
Normal file
41
config/br0tkasten.cfg
Normal file
@ -0,0 +1,41 @@
|
||||
LoadMIBs: /usr/share/snmp/mibs/UCD-SNMP-MIB.txt
|
||||
WorkDir: /var/www/mrtg/rrd
|
||||
LogFormat: rrdtool
|
||||
|
||||
Target[br0tkasten.eth0]: #eth0:oom6faayaTosh0nizoepoonahCohhahy@localhost:
|
||||
Title[br0tkasten.eth0]: [br0tkasten.de] eth0
|
||||
MaxBytes[br0tkasten.eth0]: 429496729500
|
||||
|
||||
Target[br0tkasten.tap0]: #tap0:oom6faayaTosh0nizoepoonahCohhahy@localhost:
|
||||
Title[br0tkasten.tap0]: [br0tkasten.de] tap0
|
||||
MaxBytes[br0tkasten.tap0]: 429496729500
|
||||
|
||||
Target[br0tkasten.cpu]:ssCpuRawUser.0&ssCpuRawUser.0:oom6faayaTosh0nizoepoonahCohhahy@127.0.0.1 + ssCpuRawSystem.0&ssCpuRawSystem.0:oom6faayaTosh0nizoepoonahCohhahy@127.0.0.1 + ssCpuRawNice.0&ssCpuRawNice.0:oom6faayaTosh0nizoepoonahCohhahy@127.0.0.1
|
||||
Title[br0tkasten.cpu]: [br0tkasten.de] CPU Load
|
||||
Options[br0tkasten.cpu]: gauge
|
||||
MaxBytes[br0tkasten.cpu]: 100
|
||||
|
||||
Target[br0tkasten.memtotal]: ( .1.3.6.1.4.1.2021.4.5.0&.1.3.6.1.4.1.2021.4.5.0:oom6faayaTosh0nizoepoonahCohhahy@localhost ) - ( .1.3.6.1.4.1.2021.4.6.0&.1.3.6.1.4.1.2021.4.6.0:oom6faayaTosh0nizoepoonahCohhahy@localhost )
|
||||
Title[br0tkasten.memtotal]: [br0tkasten.de] Memory Usage
|
||||
MaxBytes[br0tkasten.memtotal]: 819200
|
||||
Options[br0tkasten.memtotal]: gauge
|
||||
|
||||
Target[br0tkasten.swap]:( .1.3.6.1.4.1.2021.4.3.0&.1.3.6.1.4.1.2021.4.3.0:oom6faayaTosh0nizoepoonahCohhahy@localhost ) - ( .1.3.6.1.4.1.2021.4.4.0&.1.3.6.1.4.1.2021.4.4.0:oom6faayaTosh0nizoepoonahCohhahy@localhost)
|
||||
Title[br0tkasten.swap]: [br0tkasten.de] Swap Usage
|
||||
MaxBytes[br0tkasten.swap]: 409600
|
||||
Options[br0tkasten.swap]: gauge
|
||||
|
||||
Target[br0tkasten.procs]: `/opt/sbin/linux_proc.pl`
|
||||
Title[br0tkasten.procs]: [br0tkasten.de] Process Statistics
|
||||
MaxBytes[br0tkasten.procs]: 65000
|
||||
Options[br0tkasten.procs]: gauge
|
||||
|
||||
Target[br0tkasten.estconn]: `/opt/sbin/linux_estconn.pl`
|
||||
Title[br0tkasten.estconn]: [br0tkasten.de] Established connections
|
||||
MaxBytes[br0tkasten.estconn]: 65000
|
||||
Options[br0tkasten.estconn]: gauge
|
||||
|
||||
Target[br0tkasten.users]: `/opt/sbin/linux_users.pl`
|
||||
Title[br0tkasten.users]: [br0tkasten.de] Logged in users
|
||||
MaxBytes[br0tkasten.users]: 1000
|
||||
Options[br0tkasten.users]: gauge
|
29
config/br0tkasten.ok
Normal file
29
config/br0tkasten.ok
Normal file
@ -0,0 +1,29 @@
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Descr Red Hat, Inc Device 0001 2
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Descr br0 3
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Descr lo 1
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Descr tap0 4
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Descr veth7S2NK2 8
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Descr veth9VE6E6 12
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Descr vethJ7G7IT 6
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Descr vethPTF3KR 10
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Eth 1
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Eth 52-54-ce-25-60-1b 2
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Eth 5a-91-96-8a-8c-0a 4
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Eth fe-3b-6f-48-83-9d Dup
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Eth fe-47-71-5f-47-9d 12
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Eth fe-82-f2-c9-82-9d 10
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Eth fe-94-5e-a6-23-44 8
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Ip 10.0.0.1 4
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Ip 10.3.0.1 3
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Ip 127.0.0.1 1
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Ip 37.221.196.144 2
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Name br0 3
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Name eth0 2
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Name lo 1
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Name tap0 4
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Name veth7S2NK2 8
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Name veth9VE6E6 12
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Name vethJ7G7IT 6
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Name vethPTF3KR 10
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Type 24 1
|
||||
oom6faayaTosh0nizoepoonahCohhahy@localhost_ Type 6 Dup
|
36
config/kodi.cfg
Normal file
36
config/kodi.cfg
Normal file
@ -0,0 +1,36 @@
|
||||
LoadMIBs: /usr/share/snmp/mibs/UCD-SNMP-MIB.txt
|
||||
WorkDir: /var/www/mrtg/rrd
|
||||
LogFormat: rrdtool
|
||||
|
||||
Target[kodi.eth0]: #eth0:diengei5wohG9fiephohmiuZ8ooj9oda@kodi.vpn:
|
||||
Title[kodi.eth0]: [kodi] eth0
|
||||
MaxBytes[kodi.eth0]: 4294967295
|
||||
|
||||
Target[kodi.tap0]: #tap0:diengei5wohG9fiephohmiuZ8ooj9oda@kodi.vpn:
|
||||
Title[kodi.tap0]: [kodi] tap0
|
||||
MaxBytes[kodi.tap0]: 4294967295
|
||||
|
||||
Target[kodi.cpu]:ssCpuRawUser.0&ssCpuRawUser.0:diengei5wohG9fiephohmiuZ8ooj9oda@kodi.vpn + ssCpuRawSystem.0&ssCpuRawSystem.0:diengei5wohG9fiephohmiuZ8ooj9oda@kodi.vpn + ssCpuRawNice.0&ssCpuRawNice.0:diengei5wohG9fiephohmiuZ8ooj9oda@kodi.vpn
|
||||
Title[kodi.cpu]: [kodi] CPU Load
|
||||
MaxBytes[kodi.cpu]: 100000
|
||||
Options[kodi.cpu]: gauge
|
||||
|
||||
Target[kodi.memtotal]: ( .1.3.6.1.4.1.2021.4.5.0&.1.3.6.1.4.1.2021.4.5.0:diengei5wohG9fiephohmiuZ8ooj9oda@kodi.vpn ) - ( .1.3.6.1.4.1.2021.4.6.0&.1.3.6.1.4.1.2021.4.6.0:diengei5wohG9fiephohmiuZ8ooj9oda@kodi.vpn )
|
||||
Title[kodi.memtotal]: [kodi] Memory Usage
|
||||
MaxBytes[kodi.memtotal]: 409600
|
||||
Options[kodi.memtotal]: gauge
|
||||
|
||||
Target[kodi.swap]:( .1.3.6.1.4.1.2021.4.3.0&.1.3.6.1.4.1.2021.4.3.0:diengei5wohG9fiephohmiuZ8ooj9oda@kodi.vpn ) - ( .1.3.6.1.4.1.2021.4.4.0&.1.3.6.1.4.1.2021.4.4.0:diengei5wohG9fiephohmiuZ8ooj9oda@kodi.vpn)
|
||||
Title[kodi.swap]: [kodi] Swap Usage
|
||||
MaxBytes[kodi.swap]: 409600
|
||||
Options[kodi.swap]: gauge
|
||||
|
||||
#Target[kodi.tv]: .1.3.6.1.2.1.25.1.9&.1.3.6.1.2.1.25.1.9:diengei5wohG9fiephohmiuZ8ooj9oda@kodi.vpn
|
||||
#Title[kodi.tv]: [kodi] TV on
|
||||
#MaxBytes[kodi.tv]: 1
|
||||
#Options[kodi.tv]: gauge
|
||||
|
||||
Target[kodi.temp]: .1.3.6.1.2.1.25.1.8&.1.3.6.1.2.1.25.1.8:diengei5wohG9fiephohmiuZ8ooj9oda@kodi.vpn / 1000
|
||||
Title[kodi.temp]: [kodi] CPU Temperature
|
||||
MaxBytes[kodi.temp]: 20000
|
||||
Options[kodi.temp]: gauge
|
14
config/kodi.ok
Normal file
14
config/kodi.ok
Normal file
@ -0,0 +1,14 @@
|
||||
diengei5wohG9fiephohmiuZ8ooj9oda@kodi.vpn_ Descr eth0 2
|
||||
diengei5wohG9fiephohmiuZ8ooj9oda@kodi.vpn_ Descr lo 1
|
||||
diengei5wohG9fiephohmiuZ8ooj9oda@kodi.vpn_ Descr tap0 3
|
||||
diengei5wohG9fiephohmiuZ8ooj9oda@kodi.vpn_ Eth 1
|
||||
diengei5wohG9fiephohmiuZ8ooj9oda@kodi.vpn_ Eth 76-e7-fa-d0-ee-e9 3
|
||||
diengei5wohG9fiephohmiuZ8ooj9oda@kodi.vpn_ Eth b8-27-eb-6c-27-e6 2
|
||||
diengei5wohG9fiephohmiuZ8ooj9oda@kodi.vpn_ Ip 10.0.0.102 3
|
||||
diengei5wohG9fiephohmiuZ8ooj9oda@kodi.vpn_ Ip 127.0.0.1 1
|
||||
diengei5wohG9fiephohmiuZ8ooj9oda@kodi.vpn_ Ip 192.168.1.102 2
|
||||
diengei5wohG9fiephohmiuZ8ooj9oda@kodi.vpn_ Name eth0 2
|
||||
diengei5wohG9fiephohmiuZ8ooj9oda@kodi.vpn_ Name lo 1
|
||||
diengei5wohG9fiephohmiuZ8ooj9oda@kodi.vpn_ Name tap0 3
|
||||
diengei5wohG9fiephohmiuZ8ooj9oda@kodi.vpn_ Type 24 1
|
||||
diengei5wohG9fiephohmiuZ8ooj9oda@kodi.vpn_ Type 6 Dup
|
@ -29,3 +29,12 @@ Target[nas.temp]: .1.3.6.1.2.1.25.1.8&.1.3.6.1.2.1.25.1.8:jai3hoiv6aiNg5eikaezie
|
||||
Title[nas.temp]: [nas] CPU Temperature
|
||||
MaxBytes[nas.temp]: 20000
|
||||
Options[nas.temp]: gauge
|
||||
|
||||
Target[ddwrt.numclients]: CnTWaLK1.4.6.1.4.1.2021.255.3.54.1.3.32.1.4&CnTWaLK1.4.6.1.4.1.2021.255.3.54.1.3.32.1.4:jai3hoiv6aiNg5eikaezie1aengeen7o@nas.vpn
|
||||
Title[ddwrt.numclients]: [DD-WRT] Number of Clients
|
||||
MaxBytes[ddwrt.numclients]: 200
|
||||
Options[ddwrt.numclients]: gauge
|
||||
|
||||
Target[ddwrt.vlan2]: .1.4.6.1.2.1.2.2.1.10.9&.1.4.6.1.2.1.2.2.1.16.9:jai3hoiv6aiNg5eikaezie1aengeen7o@nas.vpn
|
||||
Title[ddwrt.vlan2]: [DD-WRT] Internet Bandwidth
|
||||
MaxBytes[ddwrt.vlan2]: 12500000
|
||||
|
@ -2,8 +2,8 @@ jai3hoiv6aiNg5eikaezie1aengeen7o@nas.vpn_ Descr eth0 2
|
||||
jai3hoiv6aiNg5eikaezie1aengeen7o@nas.vpn_ Descr lo 1
|
||||
jai3hoiv6aiNg5eikaezie1aengeen7o@nas.vpn_ Descr tap0 3
|
||||
jai3hoiv6aiNg5eikaezie1aengeen7o@nas.vpn_ Eth 1
|
||||
jai3hoiv6aiNg5eikaezie1aengeen7o@nas.vpn_ Eth a6-a0-59-07-8f-bd 3
|
||||
jai3hoiv6aiNg5eikaezie1aengeen7o@nas.vpn_ Eth b8-27-eb-8b-a7-b3 2
|
||||
jai3hoiv6aiNg5eikaezie1aengeen7o@nas.vpn_ Eth ba-0f-a1-41-fa-ed 3
|
||||
jai3hoiv6aiNg5eikaezie1aengeen7o@nas.vpn_ Ip 10.0.0.100 3
|
||||
jai3hoiv6aiNg5eikaezie1aengeen7o@nas.vpn_ Ip 127.0.0.1 1
|
||||
jai3hoiv6aiNg5eikaezie1aengeen7o@nas.vpn_ Ip 192.168.178.100 2
|
||||
|
@ -7,81 +7,80 @@
|
||||
<META HTTP-EQUIV="Cache-Control" content="no-cache" >
|
||||
<META HTTP-EQUIV="Pragma" CONTENT="no-cache" >
|
||||
<META HTTP-EQUIV="Expires" CONTENT="Thu, 24 Sep 2015 06:08:12 GMT" >
|
||||
<LINK HREF="favicon.ico" rel="shortcut icon" >
|
||||
<LINK HREF="/cgi-bin/details.pl?graph=favicon.ico" rel="shortcut icon" >
|
||||
<link rel="stylesheet" type="text/css" href="style.css"/>
|
||||
</HEAD>
|
||||
|
||||
<BODY>
|
||||
<H1>MRTG Index Page</H1>
|
||||
<h1>Monitoring</h1>
|
||||
|
||||
<h2>br0tkasten.de</h2>
|
||||
<div>
|
||||
<div>
|
||||
<B>[br0tkasten.de] eth0</B><br/>
|
||||
<div><A HREF="br0tkasten.eth0.html"><IMG ALT="br0tkasten.eth0 Traffic Graph" SRC="/cgi-bin/graph.pl?graph=br0tkasten.eth0"></A></DIV>
|
||||
<A HREF="/cgi-bin/details.pl?graph=br0tkasten.eth0"><IMG ALT="br0tkasten.eth0 Traffic Graph" SRC="/cgi-bin/graph.pl?width=680&height=200&graph=br0tkasten.eth0"></A>
|
||||
</div>
|
||||
<div>
|
||||
<B>[br0tkasten.de] tap0</B><br/>
|
||||
<div><A HREF="br0tkasten.tap0.html"><IMG ALT="br0tkasten.tap0 Traffic Graph" SRC="/cgi-bin/graph.pl?graph=br0tkasten.tap0"></A></DIV>
|
||||
<A HREF="/cgi-bin/details.pl?graph=br0tkasten.tap0"><IMG ALT="br0tkasten.tap0 Traffic Graph" SRC="/cgi-bin/graph.pl?width=680&height=200&graph=br0tkasten.tap0"></A>
|
||||
</div>
|
||||
<div>
|
||||
<B>[br0tkasten.de] Active CPU Load %</B><br/>
|
||||
<div><A HREF="br0tkasten.cpu.html"><IMG ALT="br0tkasten.cpu Traffic Graph" SRC="/cgi-bin/graph.pl?graph=br0tkasten.cpu"></A></DIV>
|
||||
<A HREF="/cgi-bin/details.pl?graph=br0tkasten.cpu"><IMG ALT="br0tkasten.cpu Traffic Graph" SRC="/cgi-bin/graph.pl?width=680&height=200&graph=br0tkasten.cpu"></A>
|
||||
</div>
|
||||
<div>
|
||||
<B>[br0tkasten.de] Memory Usage</B><br/>
|
||||
<div><A HREF="br0tkasten.memtotal.html"><IMG ALT="br0tkasten.memtotal Traffic Graph" SRC="/cgi-bin/graph.pl?graph=br0tkasten.memtotal"></A></DIV>
|
||||
<A HREF="/cgi-bin/details.pl?graph=br0tkasten.memtotal"><IMG ALT="br0tkasten.memtotal Traffic Graph" SRC="/cgi-bin/graph.pl?width=680&height=200&graph=br0tkasten.memtotal"></A>
|
||||
</div>
|
||||
<div>
|
||||
<B>[br0tkasten.de] Swap Usage</B><br/>
|
||||
<div><A HREF="br0tkasten.swap.html"><IMG ALT="br0tkasten.swap Traffic Graph" SRC="/cgi-bin/graph.pl?graph=br0tkasten.swap"></A></DIV>
|
||||
<A HREF="/cgi-bin/details.pl?graph=br0tkasten.swap"><IMG ALT="br0tkasten.swap Traffic Graph" SRC="/cgi-bin/graph.pl?width=680&height=200&graph=br0tkasten.swap"></A>
|
||||
</div>
|
||||
<div>
|
||||
<B>[br0tkasten.de] Process Statistics</B><br/>
|
||||
<div><A HREF="br0tkasten.procs.html"><IMG ALT="br0tkasten.procs Traffic Graph" SRC="/cgi-bin/graph.pl?graph=br0tkasten.procs"></A></DIV>
|
||||
<A HREF="/cgi-bin/details.pl?graph=br0tkasten.procs"><IMG ALT="br0tkasten.procs Traffic Graph" SRC="/cgi-bin/graph.pl?width=680&height=200&graph=br0tkasten.procs"></A>
|
||||
</div>
|
||||
<div>
|
||||
<B>[br0tkasten.de] Established connections</B><br/>
|
||||
<div><A HREF="br0tkasten.estconn.html"><IMG ALT="br0tkasten.estconn Traffic Graph" SRC="/cgi-bin/graph.pl?graph=br0tkasten.estconn"></A></DIV>
|
||||
<A HREF="/cgi-bin/details.pl?graph=br0tkasten.estconn"><IMG ALT="br0tkasten.estconn Traffic Graph" SRC="/cgi-bin/graph.pl?width=680&height=200&graph=br0tkasten.estconn"></A>
|
||||
</div>
|
||||
<div>
|
||||
<B>[br0tkasten.de] number of users</B><br/>
|
||||
<div><A HREF="br0tkasten.users.html"><IMG ALT="br0tkasten.users Traffic Graph" SRC="/cgi-bin/graph.pl?graph=br0tkasten.users"></A></DIV>
|
||||
<A HREF="/cgi-bin/details.pl?graph=br0tkasten.users"><IMG ALT="br0tkasten.users Traffic Graph" SRC="/cgi-bin/graph.pl?width=680&height=200&graph=br0tkasten.users"></A>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
|
||||
<h2>Kodi</h2>
|
||||
<div>
|
||||
<div>
|
||||
<B>[kodi] eth0</B><br/>
|
||||
<div><A HREF="kodi.eth0.html"><IMG ALT="kodi.eth0 Traffic Graph" SRC="/cgi-bin/graph.pl?graph=kodi.eth0"></A></DIV>
|
||||
<A HREF="/cgi-bin/details.pl?graph=kodi.eth0"><IMG ALT="kodi.eth0 Traffic Graph" SRC="/cgi-bin/graph.pl?width=680&height=200&graph=kodi.eth0"></A>
|
||||
</div>
|
||||
<div>
|
||||
<B>[kodi] tap0</B><br/>
|
||||
<div><A HREF="kodi.tap0.html"><IMG ALT="kodi.tap0 Traffic Graph" SRC="/cgi-bin/graph.pl?graph=kodi.tap0"></A></DIV>
|
||||
<A HREF="/cgi-bin/details.pl?graph=kodi.tap0"><IMG ALT="kodi.tap0 Traffic Graph" SRC="/cgi-bin/graph.pl?width=680&height=200&graph=kodi.tap0"></A>
|
||||
</div>
|
||||
<div>
|
||||
<B>[kodi] Active CPU Load %</B><br/>
|
||||
<div><A HREF="kodi.cpu.html"><IMG ALT="kodi.cpu Traffic Graph" SRC="/cgi-bin/graph.pl?graph=kodi.cpu"></A></DIV>
|
||||
<A HREF="/cgi-bin/details.pl?graph=kodi.cpu"><IMG ALT="kodi.cpu Traffic Graph" SRC="/cgi-bin/graph.pl?width=680&height=200&graph=kodi.cpu"></A>
|
||||
</div>
|
||||
<div>
|
||||
<B>[kodi] Memory Usage</B><br/>
|
||||
<div><A HREF="kodi.memtotal.html"><IMG ALT="kodi.memtotal Traffic Graph" SRC="/cgi-bin/graph.pl?graph=kodi.memtotal"></A></DIV>
|
||||
<A HREF="/cgi-bin/details.pl?graph=kodi.memtotal"><IMG ALT="kodi.memtotal Traffic Graph" SRC="/cgi-bin/graph.pl?width=680&height=200&graph=kodi.memtotal"></A>
|
||||
</div>
|
||||
<div>
|
||||
<B>[kodi] Swap Usage</B><br/>
|
||||
<div><A HREF="kodi.swap.html"><IMG ALT="kodi.swap Traffic Graph" SRC="/cgi-bin/graph.pl?graph=kodi.swap"></A></DIV>
|
||||
<A HREF="/cgi-bin/details.pl?graph=kodi.swap"><IMG ALT="kodi.swap Traffic Graph" SRC="/cgi-bin/graph.pl?width=680&height=200&graph=kodi.swap"></A>
|
||||
</div>
|
||||
<div>
|
||||
<B>[kodi] CPU Temperature</B><br/>
|
||||
<div><A HREF="kodi.temp.html"><IMG ALT="kodi.temp Traffic Graph" SRC="/cgi-bin/graph.pl?graph=kodi.temp"></A></DIV>
|
||||
<A HREF="/cgi-bin/details.pl?graph=kodi.temp"><IMG ALT="kodi.temp Traffic Graph" SRC="/cgi-bin/graph.pl?width=680&height=200&graph=kodi.temp"></A>
|
||||
</div>
|
||||
<div>
|
||||
<!--div>
|
||||
<B>[kodi] TV on/off</B><br/>
|
||||
<div><A HREF="kodi.tv.html"><IMG ALT="kodi.tv Traffic Graph" SRC="/cgi-bin/graph.pl?graph=kodi.tv"></A></DIV>
|
||||
</div>
|
||||
<A HREF="/cgi-bin/details.pl?graph=kodi.tv"><IMG ALT="kodi.tv Traffic Graph" SRC="/cgi-bin/graph.pl?width=680&height=200&graph=kodi.tv"></A>
|
||||
</div-->
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
@ -89,30 +88,43 @@
|
||||
<div>
|
||||
<div>
|
||||
<B>[nas] eth0</B><br/>
|
||||
<div><A HREF="nas.eth0.html"><IMG ALT="nas.eth0 Traffic Graph" SRC="/cgi-bin/graph.pl?graph=nas.eth0"></A></DIV>
|
||||
<A HREF="/cgi-bin/details.pl?graph=nas.eth0"><IMG ALT="nas.eth0 Traffic Graph" SRC="/cgi-bin/graph.pl?width=680&height=200&graph=nas.eth0"></A>
|
||||
</div>
|
||||
<div>
|
||||
<B>[nas] tap0</B><br/>
|
||||
<div><A HREF="nas.tap0.html"><IMG ALT="nas.tap0 Traffic Graph" SRC="/cgi-bin/graph.pl?graph=nas.tap0"></A></DIV>
|
||||
<A HREF="/cgi-bin/details.pl?graph=nas.tap0"><IMG ALT="nas.tap0 Traffic Graph" SRC="/cgi-bin/graph.pl?width=680&height=200&graph=nas.tap0"></A>
|
||||
</div>
|
||||
<div>
|
||||
<B>[nas] Active CPU Load %</B><br/>
|
||||
<div><A HREF="nas.cpu.html"><IMG ALT="nas.cpu Traffic Graph" SRC="/cgi-bin/graph.pl?graph=nas.cpu"></A></DIV>
|
||||
<A HREF="/cgi-bin/details.pl?graph=nas.cpu"><IMG ALT="nas.cpu Traffic Graph" SRC="/cgi-bin/graph.pl?width=680&height=200&graph=nas.cpu"></A>
|
||||
</div>
|
||||
<div>
|
||||
<B>[nas] Memory Usage</B><br/>
|
||||
<div><A HREF="nas.memtotal.html"><IMG ALT="nas.memtotal Traffic Graph" SRC="/cgi-bin/graph.pl?graph=nas.memtotal"></A></DIV>
|
||||
<A HREF="/cgi-bin/details.pl?graph=nas.memtotal"><IMG ALT="nas.memtotal Traffic Graph" SRC="/cgi-bin/graph.pl?width=680&height=200&graph=nas.memtotal"></A>
|
||||
</div>
|
||||
<div>
|
||||
<B>[nas] Swap Usage</B><br/>
|
||||
<div><A HREF="nas.swap.html"><IMG ALT="nas.swap Traffic Graph" SRC="/cgi-bin/graph.pl?graph=nas.swap"></A></DIV>
|
||||
<A HREF="/cgi-bin/details.pl?graph=nas.swap"><IMG ALT="nas.swap Traffic Graph" SRC="/cgi-bin/graph.pl?width=680&height=200&graph=nas.swap"></A>
|
||||
</div>
|
||||
<div>
|
||||
<B>[nas] CPU Temperature</B><br/>
|
||||
<div><A HREF="nas.temp.html"><IMG ALT="nas.temp Traffic Graph" SRC="/cgi-bin/graph.pl?graph=nas.temp"></A></DIV>
|
||||
<A HREF="/cgi-bin/details.pl?graph=nas.temp"><IMG ALT="nas.temp Traffic Graph" SRC="/cgi-bin/graph.pl?width=680&height=200&graph=nas.temp"></A>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
|
||||
<h2>DD-WRT</h2>
|
||||
<div>
|
||||
<div>
|
||||
<B>[DD-WRT] vlan2</B><br/>
|
||||
<A HREF="/cgi-bin/details.pl?graph=ddwrt.vlan2"><IMG ALT="ddwrt.vlan2 Internet Bandwidth" SRC="/cgi-bin/graph.pl?width=680&height=200&graph=ddwrt.vlan2"></A>
|
||||
</div>
|
||||
<div>
|
||||
<B>[DD-WRT] Wifi Clients</B><br/>
|
||||
<A HREF="/cgi-bin/details.pl?graph=ddwrt.numclients"><IMG ALT="ddwrt.numclients number of wifi clients" SRC="/cgi-bin/graph.pl?width=680&height=200&graph=ddwrt.numclients"></A>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
5
htdocs/js/d3.min.js
vendored
Normal file
5
htdocs/js/d3.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1007
htdocs/js/moment-timezone-with-data.js
Normal file
1007
htdocs/js/moment-timezone-with-data.js
Normal file
File diff suppressed because it is too large
Load Diff
3083
htdocs/js/moment.js
Normal file
3083
htdocs/js/moment.js
Normal file
File diff suppressed because it is too large
Load Diff
33
htdocs/js/q-4.1.min.js
vendored
Normal file
33
htdocs/js/q-4.1.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
390
htdocs/js/rrdGraphCtrl.js
Normal file
390
htdocs/js/rrdGraphCtrl.js
Normal file
@ -0,0 +1,390 @@
|
||||
/* *********************************************************************
|
||||
rrdGraphCtrl - control panel for rrdGraphPng charts
|
||||
|
||||
Copyright:
|
||||
2015 OETIKER+PARTNER AG http://www.oetiker.ch
|
||||
|
||||
License:
|
||||
Gnu GPL Version 2
|
||||
|
||||
Version: #VERSION#, #DATE#
|
||||
|
||||
Authors:
|
||||
* Tobias Oetiker (oetiker)
|
||||
|
||||
* **********************************************************************/
|
||||
|
||||
/**
|
||||
* The rrdGraphCtrl control turns attaches to a rrdGraphPng object and lets
|
||||
* select start time and range of the graphs.
|
||||
*/
|
||||
|
||||
qxWeb.define('rrdGraphCtrl',{
|
||||
extend: qxWeb.$$qx.ui.website.Widget,
|
||||
statics: {
|
||||
_config : {
|
||||
timeRanges: {
|
||||
"Last 60 Minutes": { order: 0, len: 60, end: 'minute' },
|
||||
"Last 24 Hours": { order: 1, len: 24, end: 'hour' },
|
||||
"Last 7 Days": { order: 2, len: 7, end: 'day' },
|
||||
"Last 31 Days": { order: 3, len: 31, end: 'day' },
|
||||
"Last 12 Months": { order: 4, len: 12, end: 'month' },
|
||||
"Today": { order: 5, len: 1, end: 'day' },
|
||||
"This Week": { order: 6, len: 1, end: 'week' },
|
||||
"This Month": { order: 7, len: 1, end: 'month' },
|
||||
"This Year": { order: 8, len: 1, end: 'year' },
|
||||
"60 Minutes": { order: 9, len: 3600},
|
||||
"12 Hours": { order: 10, len: 12*3600},
|
||||
"24 Hours": { order: 11, len: 24*3600},
|
||||
"7 Days": { order: 12, len: 7*24*3600},
|
||||
"4 Weeks": { order: 13, len: 4*7*24*3600},
|
||||
"12 Months": { order: 13, len: 365*24*3600}
|
||||
},
|
||||
initialTimeRange: 'Today',
|
||||
rangeMatchPrecision: 0.05,
|
||||
showTimeBox: true,
|
||||
resetTimeOnDateChange: false,
|
||||
switchToCustomOnStartChange: true,
|
||||
momentTz: null
|
||||
},
|
||||
rrdGraphCtrl: function(rrdGraphPng,cfg){
|
||||
var ctrl = new rrdGraphCtrl(this);
|
||||
|
||||
ctrl.init(rrdGraphPng,cfg);
|
||||
return ctrl;
|
||||
}
|
||||
},
|
||||
|
||||
construct : function(selector, context) {
|
||||
this.base(arguments, selector, context);
|
||||
},
|
||||
|
||||
members : {
|
||||
init: function(rrdGraphPng,cfg){
|
||||
if (!this.base(arguments)) {
|
||||
return false;
|
||||
};
|
||||
if (cfg){
|
||||
for (var key in cfg){
|
||||
this.setConfig(key,cfg[key])
|
||||
}
|
||||
}
|
||||
this._forEachElementWrapped(function(div,idx) {
|
||||
div.setProperty('rrdGraphPng',rrdGraphPng);
|
||||
div.__addDatePicker();
|
||||
div.__addRangePicker();
|
||||
});
|
||||
return true;
|
||||
},
|
||||
rebind: function(rrdGraphPng){
|
||||
this._forEachElementWrapped(function(div,idx) {
|
||||
div.setProperty('rrdGraphPng',rrdGraphPng);
|
||||
div.emit('rebindRrdGraphPng');
|
||||
rrdGraphPng.setStartRange(div.getProperty('start'),div.getProperty('range'));
|
||||
});
|
||||
},
|
||||
__addDatePicker: function(){
|
||||
var rrdGraphPng = this.getProperty('rrdGraphPng');
|
||||
var start = qxWeb.create('<input type="text"/>');
|
||||
start.appendTo(this);
|
||||
var picker = start.datepicker().setConfig('format', function(date) {
|
||||
return date.toDateString();
|
||||
});
|
||||
var calendar = picker.getCalendar();
|
||||
calendar.setValue(new Date());
|
||||
|
||||
var timeBox = qxWeb.create('<input class="qx-datepicker" size="10" type="text" value="00:00:00" />');
|
||||
if (! this.getConfig('showTimeBox')){
|
||||
timeBox.hide();
|
||||
}
|
||||
timeBox.appendTo(this);
|
||||
var that = this;
|
||||
var propagateDateTime = function(){
|
||||
var time = timeBox.getValue().split(':');
|
||||
[0,1,2].forEach(function(i){
|
||||
time[i] = parseInt(time[i]);
|
||||
if (isNaN(time[i])){
|
||||
time[i] = 0;
|
||||
}
|
||||
});
|
||||
timeBox.setValue([0,1,2].map(function(i){return ('0'+time[i]).slice(-2)}).join(':'));
|
||||
var start;
|
||||
var momentTz = that.getConfig('momentTz');
|
||||
if (momentTz){
|
||||
start = parseInt(moment.tz(moment(calendar.getValue()).format("YYYY-MM-DD"),momentTz).format('X'));
|
||||
}
|
||||
else {
|
||||
start = calendar.getValue().getTime()/1000
|
||||
}
|
||||
start += time[0]*3600+time[1]*60+time[2];
|
||||
rrdGraphPng.setStart(start);
|
||||
that.setProperty('start',start);
|
||||
that.emit('syncRrdGraphCtrlRange',start);
|
||||
};
|
||||
|
||||
var blockDate = false;
|
||||
var onChangeValueCal = function(){
|
||||
if (blockDate){
|
||||
blockDate = false;
|
||||
return;
|
||||
}
|
||||
if (this.getConfig('resetTimeOnDateChange')){
|
||||
timeBox.setValue('00:00:00');
|
||||
}
|
||||
propagateDateTime();
|
||||
};
|
||||
calendar.on('changeValue',onChangeValueCal,this);
|
||||
|
||||
var blockTime = false;
|
||||
timeBox.on('change',propagateDateTime,this);
|
||||
var onKeyPressTbox = function(e){
|
||||
if (e.key == "Enter") {
|
||||
propagateDateTime();
|
||||
}
|
||||
};
|
||||
timeBox.on('keypress',onKeyPressTbox,this);
|
||||
|
||||
var lastDate;
|
||||
var that = this;
|
||||
var onChangeStartRange = function(e){
|
||||
var start = e.start;
|
||||
var range = e.range;
|
||||
if (isNaN(start)) return;
|
||||
var momentTz = this.getConfig('momentTz');
|
||||
var date;
|
||||
|
||||
if (momentTz){
|
||||
date = new Date(moment.tz(start * 1000,momentTz).format("YYYY/MM/DD HH:mm:ss"));
|
||||
}
|
||||
else {
|
||||
date = new Date(start * 1000);
|
||||
}
|
||||
if (date != lastDate){
|
||||
blockDate = true;
|
||||
calendar.setValue(new Date(date.getTime()));
|
||||
var newTime = date.getHours()+':'+('0'+date.getMinutes()).slice(-2)+':'+('0'+date.getSeconds()).slice(-2);
|
||||
timeBox.setValue(newTime);
|
||||
lastDate = date;
|
||||
}
|
||||
that.setProperty('start',start);
|
||||
};
|
||||
rrdGraphPng.eq(0).on('changeStartRange',onChangeStartRange,this);
|
||||
|
||||
var onRebindRrdGraphPng = function(){
|
||||
rrdGraphPng.eq(0).off('changeStartRange',onChangeStartRange,this);
|
||||
rrdGraphPng = this.getProperty('rrdGraphPng');
|
||||
rrdGraphPng.eq(0).on('changeStartRange',onChangeStartRange,this);
|
||||
};
|
||||
this.on('rebindRrdGraphPng',onRebindRrdGraphPng,this);
|
||||
|
||||
this.once('qxRrdDispose',function(){
|
||||
this.off('rebindRrdGraphPng',onRebindRrdGraphPng,this);
|
||||
rrdGraphPng.eq(0).off('changeStartRange',onChangeStartRange,this);
|
||||
timeBox.off('change',propagateDateTime,this);
|
||||
timeBox.off('keypress',onKeyPressTbox,this);
|
||||
timeBox.remove();
|
||||
calendar.off('changeValue',onChangeValueCal,this);
|
||||
picker.dispose();
|
||||
picker.remove();
|
||||
},this);
|
||||
},
|
||||
__getRangeMoment: function(item){
|
||||
var l = item.len;
|
||||
var end = moment().tz(this.getConfig('momentTz'));
|
||||
if (item.end) {
|
||||
end.endOf(item.end).add(1,'second');
|
||||
}
|
||||
var start = end.clone().subtract(item.len,item.end ? item.end : 'second');
|
||||
return {
|
||||
end: end.unix(),
|
||||
range: end.unix() - start.unix()
|
||||
};
|
||||
},
|
||||
__getRange: function(item){
|
||||
if (this.getConfig('momentTz')){
|
||||
return this.__getRangeMoment(item)
|
||||
}
|
||||
var d = item.end;
|
||||
var l = item.len;
|
||||
var now = new Date;
|
||||
var start;
|
||||
now.setMilliseconds(0);
|
||||
now.setSeconds(0);
|
||||
if (d == 'minute'){
|
||||
now.setMinutes(now.getMinutes()+1)
|
||||
start = new Date(now.getTime());
|
||||
start.setMinutes(start.getMinutes()-l);
|
||||
}
|
||||
else {
|
||||
now.setMinutes(0);
|
||||
if (d == 'hour'){
|
||||
now.setHours(now.getHours()+1)
|
||||
start = new Date(now.getTime());
|
||||
start.setHours(start.getHours()-l);
|
||||
}
|
||||
else {
|
||||
now.setHours(0);
|
||||
if (d == 'day'){
|
||||
now.setDate(now.getDate()+1)
|
||||
start = new Date(now.getTime());
|
||||
start.setDate(start.getDate()-l);
|
||||
}
|
||||
else {
|
||||
if (d == 'week'){
|
||||
now.setDate(now.getDate()-now.getDay()+8);
|
||||
start = new Date(now.getTime());
|
||||
start.setDate(start.getDate()-l*7);
|
||||
}
|
||||
else {
|
||||
now.setDate(1);
|
||||
if (d == 'month'){
|
||||
now.setMonth(now.getMonth()+1);
|
||||
start = new Date(now.getTime());
|
||||
start.setMonth(start.getMonth()-l);
|
||||
}
|
||||
else {
|
||||
now.setMonth(0);
|
||||
if (d == 'year'){
|
||||
now.setYear(now.getFullYear()+1);
|
||||
start = new Date(now.getTime());
|
||||
start.setYear(start.getFullYear()-l);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var end = now.getTime()/1000;
|
||||
return {
|
||||
range: Math.round(end-start.getTime()/1000),
|
||||
end: Math.round(end)
|
||||
};
|
||||
},
|
||||
|
||||
__addRangePicker: function(){
|
||||
var rrdGraphPng = this.getProperty('rrdGraphPng');
|
||||
|
||||
var rangeSelector = qxWeb.create('<select class="qx-widget qx-selectbox"/>');
|
||||
this.setProperty('rangeSelector',rangeSelector);
|
||||
rangeSelector.appendTo(this);
|
||||
var keys = [];
|
||||
var tr = this.getConfig('timeRanges');
|
||||
for (var prop in tr){
|
||||
keys.push(prop);
|
||||
}
|
||||
keys.sort(function(a,b){ return tr[a].order - tr[b].order })
|
||||
.forEach(function(x){
|
||||
rangeSelector.append(
|
||||
qxWeb.create('<option/>')
|
||||
.setProperties({
|
||||
value: x,
|
||||
text: x
|
||||
})
|
||||
);
|
||||
});
|
||||
var custom = qxWeb.create('<option value="0">Custom</option>');
|
||||
rangeSelector.append(custom);
|
||||
var blockStart = false;
|
||||
var that = this;
|
||||
var onRangeSelectorChange = function(e){
|
||||
var item = tr[rangeSelector.getValue()];
|
||||
if (item){
|
||||
if (item.end){
|
||||
var info = that.__getRange(item);
|
||||
if (info){
|
||||
var range = info.range;
|
||||
var start = info.end - range;
|
||||
that.setProperty('range',range);
|
||||
rrdGraphPng.setStartRange(start,range);
|
||||
rrdGraphPng.emit('changeStartRange',{start:start,range:null});
|
||||
}
|
||||
else {
|
||||
console.log("unknown end type "+item.end);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
rrdGraphPng.setStartRange(rrdGraphPng.getStart(),item.len);
|
||||
that.setProperty('range',item.len);
|
||||
}
|
||||
}
|
||||
};
|
||||
rangeSelector.setValue(this.getConfig('initialTimeRange'));
|
||||
rangeSelector.on('change',onRangeSelectorChange,this);
|
||||
|
||||
onRangeSelectorChange();
|
||||
|
||||
var precision = this.getConfig('rangeMatchPrecision');
|
||||
var that = this;
|
||||
var onChangeStartRange = function(e){
|
||||
var start = e.start;
|
||||
var range = e.range;
|
||||
if (range == null) return;
|
||||
that.setProperty('range',range);
|
||||
for (var key in tr){
|
||||
var item = tr[key];
|
||||
if (item.end){
|
||||
var info = that.__getRange(item);
|
||||
if (info){
|
||||
var newRange = info.range;
|
||||
var newStart = info.end - range;
|
||||
if (Math.abs(newRange - range) / range <= precision
|
||||
&& Math.abs(newStart - start) / range <= precision ) {
|
||||
rangeSelector.setValue(key);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.log("unknown end type "+item.end);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
var newRange = item.len;
|
||||
if (Math.abs(newRange - range) / range < 0.05){
|
||||
rangeSelector.setValue(key);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
rangeSelector.setValue("0");
|
||||
};
|
||||
|
||||
var onSyncRange = function(start){
|
||||
onChangeStartRange({start:start,range:this.getProperty('range')});
|
||||
};
|
||||
|
||||
this.on('syncRrdGraphCtrlRange',onSyncRange,this);
|
||||
|
||||
|
||||
rrdGraphPng.eq(0).on('changeStartRange',onChangeStartRange,this);
|
||||
|
||||
var onRebindRrdGraphPng = function(){
|
||||
rrdGraphPng.eq(0).off('changeStartRange',onChangeStartRange,this);
|
||||
rrdGraphPng = this.getProperty('rrdGraphPng');
|
||||
rrdGraphPng.eq(0).on('changeStartRange',onChangeStartRange,this);
|
||||
rrdGraphPng.setRange(this.getProperty('range'));
|
||||
};
|
||||
this.on('rebindRrdGraphPng',onRebindRrdGraphPng,this);
|
||||
|
||||
this.once('qxRrdDispose',function(){
|
||||
this.off('rebindRrdGraphPng',onRebindRrdGraphPng,this);
|
||||
this.off('syncRrdGraphCtrlRange',onSyncRange,this);
|
||||
rangeSelector.off('change',onRangeChange,this);
|
||||
rrdGraphPng.eq(0).off('changeStartRange',onChangeStartRange,this);
|
||||
rangeSelector.remove();
|
||||
},this);
|
||||
},
|
||||
dispose: function(){
|
||||
this._forEachElementWrapped(function(ctrl) {
|
||||
ctrl.emit('qxRrdDispose');
|
||||
});
|
||||
return this.base(arguments);
|
||||
}
|
||||
},
|
||||
|
||||
defer : function(statics) {
|
||||
qxWeb.$attach({rrdGraphCtrl : statics.rrdGraphCtrl});
|
||||
},
|
||||
|
||||
});
|
479
htdocs/js/rrdGraphPng.js
Normal file
479
htdocs/js/rrdGraphPng.js
Normal file
@ -0,0 +1,479 @@
|
||||
/* *********************************************************************
|
||||
rrdGraphPng - make rrdcharts interactive
|
||||
|
||||
Copyright:
|
||||
2015 OETIKER+PARTNER AG http://www.oetiker.ch
|
||||
|
||||
License:
|
||||
Gnu GPL Version 2
|
||||
|
||||
Version: #VERSION#, #DATE#
|
||||
|
||||
Authors:
|
||||
* Tobias Oetiker (oetiker)
|
||||
|
||||
* **********************************************************************/
|
||||
|
||||
/**
|
||||
* The rrdGraphPng control turns a static RRD chart into an interactive one
|
||||
* all that is required for this to work, is the ability to configure the
|
||||
* start and end and possible with and height parameters in the chart URL.
|
||||
*
|
||||
* See index.html in this directory for inspiration on how to use this library.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
qxWeb.define('rrdGraphPng',{
|
||||
extend: qxWeb.$$qx.ui.website.Widget,
|
||||
statics: {
|
||||
_config : {
|
||||
canvasPadding: 100,
|
||||
initialStart : (new Date()).getTime() / 1000 - 24*3600,
|
||||
initialRange: 24*3600,
|
||||
moveZoom: 1,
|
||||
autoUpdate: true,
|
||||
gridFillStyleA: 'rgba(0,0,0,0.08)',
|
||||
gridFillStyleB: 'rgba(255,255,255,0.08)'
|
||||
},
|
||||
rrdGraphPng: function(cfg){
|
||||
var png = new rrdGraphPng(this);
|
||||
png.init(cfg);
|
||||
return png;
|
||||
}
|
||||
},
|
||||
|
||||
construct : function(selector, context) {
|
||||
this.base(arguments, selector, context);
|
||||
},
|
||||
|
||||
members : {
|
||||
__start: null,
|
||||
__range: null,
|
||||
__syncJob: null,
|
||||
init: function(cfg){
|
||||
if (!this.base(arguments)) {
|
||||
return false;
|
||||
};
|
||||
var that = this;
|
||||
try {
|
||||
throw new Error('');
|
||||
} catch (e){
|
||||
// this is voodoo, but it does often detect where the javascript file
|
||||
// lives and thus we can hope to find the cursor files there too
|
||||
if (e.stack){
|
||||
that.setConfig('cursorUrl',e.stack.replace(/[^$]*http/,'http').replace(/[^\/]*\.js[^$]*/,''));
|
||||
}
|
||||
};
|
||||
|
||||
// update the grid no more then 30 times a second
|
||||
this.__paintGrid = qxWeb.func.throttle(this.__paintGridReal,32,{trailing: false});
|
||||
|
||||
if (cfg){
|
||||
for (var key in cfg){
|
||||
this.setConfig(key,cfg[key])
|
||||
}
|
||||
}
|
||||
var qxWindow = qxWeb(window);
|
||||
this.__start = parseInt(this.getConfig('initialStart'));
|
||||
this.__range = parseInt(this.getConfig('initialRange'));
|
||||
|
||||
qxWindow.on('resize',this.update,this);
|
||||
this._forEachElementWrapped(function(img,idx) {
|
||||
img.setStyle('display','inline-block');
|
||||
img.setAttributes({
|
||||
unselectable: true,
|
||||
draggable: false
|
||||
});
|
||||
this.__addLoader(img);
|
||||
this.__addCanvas(img);
|
||||
this.__addTrack(img);
|
||||
this.__addRoll(img);
|
||||
img.emit('update');
|
||||
},this);
|
||||
if (this.getConfig('autoUpdate')){
|
||||
this.__addSyncCharts();
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
|
||||
setStart: function(start){
|
||||
this.__start = start;
|
||||
this.update();
|
||||
},
|
||||
getStart: function(){
|
||||
return this.__start;
|
||||
},
|
||||
getRange: function(){
|
||||
return this.__range;
|
||||
},
|
||||
setRange: function(range){
|
||||
this.__range = range;
|
||||
this.update();
|
||||
},
|
||||
|
||||
setStartRange: function(start,range){
|
||||
this.__start = start;
|
||||
this.__range = range;
|
||||
this.update();
|
||||
},
|
||||
|
||||
update: function(){
|
||||
this._forEachElementWrapped(function(img,idx) {
|
||||
img.emit('update');
|
||||
},this);
|
||||
},
|
||||
|
||||
__addSyncCharts: function(){
|
||||
var lastEnd = this.__start + this.__range;
|
||||
var lastNow = false;
|
||||
var that = this;
|
||||
var syncCharts = function(){
|
||||
var currentEnd = that.__start + that.__range;
|
||||
var now = Math.round((new Date).getTime()/1000);
|
||||
if (now < currentEnd && now > that.__start){
|
||||
if (!lastNow) {
|
||||
lastNow = now;
|
||||
lastEnd = currentEnd;
|
||||
return;
|
||||
}
|
||||
var increment = now - lastNow;
|
||||
var go = false;
|
||||
that._forEachElementWrapped(function(img,idx) {
|
||||
if (that.__range / img.getWidth() < increment){
|
||||
go = true;
|
||||
}
|
||||
});
|
||||
if (go){
|
||||
lastNow = now;
|
||||
that.__start += increment;
|
||||
lastEnd = that.__start + that.__range;
|
||||
that.update();
|
||||
that.emit('change',that.__start,that.__range);
|
||||
}
|
||||
}
|
||||
else {
|
||||
lastNow = false;
|
||||
}
|
||||
};
|
||||
if (this.getConfig('autoUpdate')){
|
||||
this.__syncJob = window.setInterval(syncCharts,1000);
|
||||
}
|
||||
},
|
||||
|
||||
__buildUrl: function(img,zoom){
|
||||
var template = img.getData('src-template');
|
||||
var start = this.__start;
|
||||
if (start == null || isNaN(start)) return '';
|
||||
return qxWeb.template.render(template,{
|
||||
width: img.getWidth(),
|
||||
height: img.getHeight(),
|
||||
start: start,
|
||||
end: start + this.__range,
|
||||
zoom: zoom ? zoom : 1,
|
||||
random: Math.round(Math.random()*1000000000).toString(36)
|
||||
});
|
||||
},
|
||||
|
||||
__addCanvas: function(img){
|
||||
var offset = img.getOffset();
|
||||
var pos = img.getPosition();
|
||||
// console.log(img,offset,pos);
|
||||
var canvas = qxWeb.create('<canvas></canvas>');
|
||||
canvas.setStyles({
|
||||
position: 'absolute'
|
||||
})
|
||||
.setAttributes({
|
||||
draggable: "false",
|
||||
unselectable: "true"
|
||||
})
|
||||
.insertBefore(img);
|
||||
|
||||
canvas.setStyle('cursor','url(' + this.getConfig('cursorUrl') + '/MoveCursor.cur), move');
|
||||
|
||||
var resize = function(){
|
||||
var width = img.getWidth();
|
||||
var height = img.getHeight();
|
||||
canvas.setStyles({width: width+'px', height: height+'px'});
|
||||
canvas.setProperties({width: width.toString(), height: height.toString()});
|
||||
//canvas.width = width;
|
||||
//canvas.height = height;
|
||||
};
|
||||
qxWeb(window).on('resize',resize);
|
||||
img.__canvas = canvas;
|
||||
if (canvas[0].getContext){
|
||||
img.__ctx = canvas[0].getContext("2d");
|
||||
}
|
||||
resize();
|
||||
},
|
||||
|
||||
__rangeCap: function(range){
|
||||
return Math.round(Math.min(Math.max(10,range),24*3600*366*20));
|
||||
},
|
||||
|
||||
__addLoader: function(img){
|
||||
var loading = false;
|
||||
var skipped = false;
|
||||
var lastSrc = null;
|
||||
var start;
|
||||
var retry = 0;
|
||||
var onError = function(){
|
||||
loading = false;
|
||||
//if (retry < 3){
|
||||
// retry++;
|
||||
// img.emit('update');
|
||||
//}
|
||||
};
|
||||
img.on('error',onError,this);
|
||||
var onLoad = function(){
|
||||
loading = false;
|
||||
if (skipped){
|
||||
skipped = false;
|
||||
img.emit('update');
|
||||
}
|
||||
retry = 0;
|
||||
};
|
||||
img.on('load',onLoad,this);
|
||||
var onUpdate = function(zoom){
|
||||
var url = this.__buildUrl(img,zoom);
|
||||
if (!url) return;
|
||||
if (! loading){
|
||||
loading = true;
|
||||
img.setProperty('src',url);
|
||||
}
|
||||
else {
|
||||
skipped = true;
|
||||
}
|
||||
};
|
||||
|
||||
var onUpdateThrottled = qxWeb.func.throttle(onUpdate,120);
|
||||
img.on('update',onUpdateThrottled,this);
|
||||
|
||||
img.once('qxRrdDispose',function(){
|
||||
img.off('load',onLoad,this);
|
||||
img.off('update',onUpdateThrottled,this);
|
||||
img.off('error',onError,this);
|
||||
},this);
|
||||
|
||||
},
|
||||
|
||||
__addRoll: function(img){
|
||||
var that = this;
|
||||
var syncUp = qxWeb.func.debounce(function(){
|
||||
that.update();
|
||||
that.emit('changeStartRange',{start:that.__start,range:that._range});
|
||||
},200);
|
||||
var xPos = img.getWidth()/2;
|
||||
var onMove = function(e){
|
||||
var newXPos = e.pageX - img.getOffset().left;
|
||||
if (! isNaN(newXPos)){
|
||||
xPos = newXPos;
|
||||
}
|
||||
};
|
||||
|
||||
var initialDotRange;
|
||||
var initialDotStart;
|
||||
var dotOff = true;
|
||||
var killerId;
|
||||
var onRoll = function(e){
|
||||
if (e.pointerType != "wheel" || !e._original.ctrlKey ) return;
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
var delta = e.delta.y;
|
||||
var initialRange = this.__range;
|
||||
var xOrigin = xPos / img.getWidth();
|
||||
if (dotOff){
|
||||
initialDotRange = this.__range;
|
||||
initialDotStart = this.__start;
|
||||
dotOff = false;
|
||||
}
|
||||
this.__paintGrid(img,initialDotRange,initialDotStart);
|
||||
this.__range = this.__rangeCap(this.__range*(1+(delta/10000)));
|
||||
this.__start = Math.round(this.__start + (initialRange - this.__range)*xOrigin);
|
||||
var that = this;
|
||||
killerId = window.setTimeout(function(){
|
||||
window.clearTimeout(killerId);
|
||||
that.__clearGrid(img);
|
||||
dotOff=true
|
||||
},1000);
|
||||
img.emit('update',this.getConfig('moveZoom'));
|
||||
syncUp();
|
||||
};
|
||||
img.__canvas.on('pointermove',onMove,this);
|
||||
img.__canvas.on('roll',onRoll,this);
|
||||
|
||||
//img.once('qxRrdDispose',function(){
|
||||
// img.__canvas.off('pointermove',onMove,this);
|
||||
// img.__canvas.off('roll',onRoll,this);
|
||||
//},this);
|
||||
},
|
||||
__paintGridReal: function(img,initialRange,initialStart){
|
||||
var ctx = img.__ctx;
|
||||
if (!ctx){
|
||||
return;
|
||||
}
|
||||
var width = img.getWidth();
|
||||
var height = img.getHeight();
|
||||
var skip = 100;
|
||||
var xIncr = Math.round(initialRange / this.__range * skip);
|
||||
var xOff = Math.round((width / this.__range * (initialStart - this.__start)) % xIncr);
|
||||
var xWidth = Math.round(xIncr/2);
|
||||
var gridStyleA = this.getConfig('gridFillStyleA');
|
||||
var gridStyleB = this.getConfig('gridFillStyleB');
|
||||
ctx.clearRect(0,0,width,height);
|
||||
for (var x=-xIncr+xOff;x<width;x+=xIncr){
|
||||
ctx.fillStyle = gridStyleA,
|
||||
ctx.fillRect(x,0,xWidth,height);
|
||||
ctx.fillStyle = gridStyleB,
|
||||
ctx.fillRect(x+xWidth,0,xWidth,height);
|
||||
};
|
||||
},
|
||||
__clearGrid: function(img){
|
||||
var ctx = img.__ctx;
|
||||
if (!ctx){
|
||||
return;
|
||||
}
|
||||
var width = img.getWidth();
|
||||
var height = img.getHeight();
|
||||
ctx.clearRect(0,0,width,height);
|
||||
},
|
||||
__addTrack: function(img){
|
||||
var qxDocument = q(document);
|
||||
var initialStart = this.__start;
|
||||
var initialRange = this.__range;
|
||||
var xOrigin;
|
||||
var pointerOrigin;
|
||||
var imgWidth = img.getWidth() - this.getConfig('canvasPadding');
|
||||
var active = false;
|
||||
var trackLock = false;
|
||||
var vertical;
|
||||
|
||||
var onPointerMove = function(e){
|
||||
if (!active) return;
|
||||
if (e.pointerType == 'touch' && e._original.touches.length > 1) return;
|
||||
var delta = {
|
||||
x: e.pageX - pointerOrigin.x,
|
||||
y: e.pageY - pointerOrigin.y
|
||||
};
|
||||
if (!trackLock){
|
||||
if (Math.abs(delta.x) > 10 || Math.abs(delta.y) > 10){
|
||||
vertical = Math.abs(delta.x) < Math.abs(delta.y)
|
||||
trackLock = true;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (vertical){
|
||||
if (e.pointerType == 'touch') return;
|
||||
if (! isNaN(xOrigin)){
|
||||
this.__range = this.__rangeCap(initialRange*Math.pow(1.02,delta.y));
|
||||
this.__start = Math.round(initialStart + (initialRange - this.__range)*xOrigin);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.__start = initialStart-Math.round(this.__range/imgWidth*delta.x);
|
||||
}
|
||||
this.__paintGrid(img,initialRange,initialStart);
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
img.emit('update',this.getConfig('moveZoom'));
|
||||
};
|
||||
|
||||
var onPinch = function(e){
|
||||
if (!active) return;
|
||||
var scale = e.getScale();
|
||||
if (!scale) return;
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
this.__range = this.__rangeCap(initialRange/scale);
|
||||
this.__start = Math.round(initialStart + (initialRange - this.__range)/2);
|
||||
this.__paintGrid(img,initialRange,initialStart);
|
||||
img.emit('update',this.getConfig('moveZoom'));
|
||||
};
|
||||
|
||||
var canvas = img.__canvas;
|
||||
|
||||
var qxDoc = qxWeb(window);
|
||||
var onPointerUp = function(e){
|
||||
if (!active) return;
|
||||
//e.stopPropagation();
|
||||
//e.preventDefault();
|
||||
active = false;
|
||||
this.__clearGrid(img);
|
||||
this.update();
|
||||
if (initialRange != this.__range || initialStart != this.__start){
|
||||
this.emit('changeStartRange',{start:this.__start,range:this.__range});
|
||||
}
|
||||
trackLock = false;
|
||||
canvas.setStyle('cursor','url(' + this.getConfig('cursorUrl') + '/MoveCursor.cur), move');
|
||||
qxDoc.off("pointermove",onPointerMove,this);
|
||||
};
|
||||
|
||||
var onPointerDown = function(e){
|
||||
//e.preventDefault();
|
||||
//e.stopPropagation();
|
||||
if (active) return;
|
||||
active = true;
|
||||
initialStart = this.__start;
|
||||
initialRange = this.__range;
|
||||
imgWidth = img.getWidth() - this.getConfig('canvasPadding');
|
||||
canvas.setStyle('cursor','url(' + this.getConfig('cursorUrl') + '/DragCursor.cur), move');
|
||||
var newXPos = e.pageX - img.getOffset().left;
|
||||
pointerOrigin = {
|
||||
x: e.pageX, y: e.pageY
|
||||
};
|
||||
if (! isNaN(newXPos)){
|
||||
xOrigin = newXPos / img.getWidth();
|
||||
}
|
||||
qxDoc.on("pointermove",onPointerMove,this);
|
||||
// on mobile devices we do not kill 'touch' because this could
|
||||
// spell the start of a vertical scroll
|
||||
if (e.pointerType != 'touch') {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
};
|
||||
|
||||
var onPointerOut = function(e){
|
||||
if (!active) return;
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
qxDoc.on("pointerup",onPointerUp,this,true);
|
||||
qxDoc.on('pointerout',onPointerOut,this,true);
|
||||
|
||||
canvas.on('pinch',onPinch,this);
|
||||
canvas.on('pointerdown',onPointerDown,this);
|
||||
|
||||
img.once('qxRrdDispose',function(){
|
||||
canvas.allOff();
|
||||
qxDoc.off("pointerup",onPointerUp,this,true);
|
||||
qxDoc.off('pointerout',onPointerOut,this,true);
|
||||
qxDoc.off('pointermove',onPointerMove,this);
|
||||
canvas.remove();
|
||||
});
|
||||
},
|
||||
dispose: function(){
|
||||
if (this.__syncJob){
|
||||
window.clearInterval(this.__syncJob);
|
||||
}
|
||||
this._forEachElementWrapped(function(img) {
|
||||
img.emit('qxRrdDispose');
|
||||
img.removeAttribute('unselectable');
|
||||
img.removeAttribute('draggable');
|
||||
});
|
||||
return this.base(arguments);
|
||||
}
|
||||
},
|
||||
|
||||
defer : function(statics) {
|
||||
qxWeb.$attach({rrdGraphPng : statics.rrdGraphPng});
|
||||
}
|
||||
});
|
||||
|
||||
|
662
htdocs/js/rrdGraphSvg.js
Normal file
662
htdocs/js/rrdGraphSvg.js
Normal file
@ -0,0 +1,662 @@
|
||||
/* ************************************************************************
|
||||
|
||||
Copyrigtht: OETIKER+PARTNER AG
|
||||
License: GPLv3 or later
|
||||
Authors: Tobias Oetiker
|
||||
Utf8Check: äöü
|
||||
|
||||
************************************************************************ */
|
||||
|
||||
/**
|
||||
* Create a D3.js based, interactive chart.
|
||||
*
|
||||
*/
|
||||
|
||||
var ID;
|
||||
|
||||
qx.Class.define("ep.visualizer.chart.BrowserChart", {
|
||||
extend : qx.ui.core.Widget,
|
||||
|
||||
/**
|
||||
* @param instance {String} identifying the visualizer instance
|
||||
* @param recId {Number} stable identifier for the extopus node
|
||||
* @param chartDef {Array} chart description array
|
||||
*
|
||||
* <pre code='javascript'>
|
||||
* { [
|
||||
* { cmd: 'LINE', width: 1, color, '#ff00ff', legend: 'text' },
|
||||
* { cmd: 'AREA', stack: 1, color, '#df33ff', legend: 'more text' },
|
||||
* ...
|
||||
* ]
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
construct : function(instance,recId,chartDef) {
|
||||
this.base(arguments);
|
||||
this._setLayout(new qx.ui.layout.VBox(10));
|
||||
this.set({
|
||||
instance: instance,
|
||||
recId: recId
|
||||
});
|
||||
// the chart
|
||||
var d3Obj = this.__d3Obj = new qxd3.Svg();
|
||||
var margin = this.self(arguments).MARGIN;
|
||||
this.__chart = d3Obj.getD3SvgNode()
|
||||
.append("g")
|
||||
.attr("transform", "translate("+margin.left+","+margin.top+")");
|
||||
|
||||
this.__d3 = d3Obj.getD3();
|
||||
|
||||
// add the svg object into the LoadingBox
|
||||
this._add(d3Obj,{flex: 1});
|
||||
|
||||
if (chartDef){
|
||||
this.setChartDef(chartDef);
|
||||
}
|
||||
|
||||
// insert our global CSS once only
|
||||
var CSS = this.self(arguments).BASECSS;
|
||||
var selector;
|
||||
for (selector in CSS){
|
||||
d3Obj.addCssRule(selector, CSS[selector]);
|
||||
}
|
||||
|
||||
this.__dataNode = [];
|
||||
|
||||
|
||||
d3Obj.addListener('appear',this.setSize,this);
|
||||
|
||||
d3Obj.addListener('resize',this.setSize,this);
|
||||
|
||||
var timer = this.__timer = new qx.event.Timer(5 * 1000);
|
||||
|
||||
d3Obj.addListener('disappear', function() {
|
||||
timer.stop()
|
||||
}, this);
|
||||
|
||||
d3Obj.addListener('appear', function() {
|
||||
timer.start()
|
||||
}, this);
|
||||
|
||||
timer.addListener('interval', function() {
|
||||
this.trackingRedraw();
|
||||
}, this);
|
||||
|
||||
timer.start();
|
||||
},
|
||||
|
||||
statics : {
|
||||
/**
|
||||
* Some basic css for the D3 chart <code>browserchart</code>
|
||||
*/
|
||||
BASECSS: {
|
||||
'svg': {
|
||||
"font": "10px sans-serif"
|
||||
},
|
||||
'.axis': {
|
||||
"shape-rendering": 'crispEdges'
|
||||
},
|
||||
'.axis path, .axis line': {
|
||||
'fill': 'none',
|
||||
'stroke-width': '1px'
|
||||
},
|
||||
'.x.axis path': {
|
||||
'stroke': '#000'
|
||||
},
|
||||
'.x.axis line': {
|
||||
'stroke': '#000',
|
||||
'stroke-opacity': '.2',
|
||||
'stroke-dasharray': '1,1'
|
||||
},
|
||||
'.y.axis line': {
|
||||
'stroke': '#000',
|
||||
'stroke-opacity': '.2',
|
||||
'stroke-dasharray': '1,1'
|
||||
}
|
||||
},
|
||||
MARGIN: {
|
||||
left: 50,
|
||||
top: 10,
|
||||
bottom: 15,
|
||||
right: 10
|
||||
}
|
||||
},
|
||||
|
||||
properties : {
|
||||
/**
|
||||
* inbytes, outbytes ...
|
||||
*/
|
||||
view : {
|
||||
init : null,
|
||||
nullable : true
|
||||
},
|
||||
/**
|
||||
* amount of time in the chart (in seconds)
|
||||
*/
|
||||
timeWidth : {
|
||||
init : null,
|
||||
check : 'Integer',
|
||||
nullable : true
|
||||
},
|
||||
/**
|
||||
* at what point in time is the end of the chart, if no time is give the chart will update automatically
|
||||
*/
|
||||
endTime : {
|
||||
init : null,
|
||||
check : 'Integer',
|
||||
nullable : true
|
||||
},
|
||||
/**
|
||||
* track current time
|
||||
*/
|
||||
trackCurrentTime: {
|
||||
init : null,
|
||||
check : 'Boolean',
|
||||
nullable : true
|
||||
},
|
||||
/**
|
||||
* instance name of the table. This lets us identify ourselves when requesting data from the server
|
||||
*/
|
||||
instance : {
|
||||
init : null,
|
||||
nullable : true
|
||||
},
|
||||
/**
|
||||
* extopus Id aka recId ... to identify the chart we are talking about
|
||||
*/
|
||||
recId: {
|
||||
init : null,
|
||||
check : 'Integer',
|
||||
nullable : true
|
||||
},
|
||||
/**
|
||||
* chart defs (chart definitions)
|
||||
*/
|
||||
chartDef: {
|
||||
init : [],
|
||||
check : 'Array',
|
||||
nullable : true
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
members : {
|
||||
__timer : null,
|
||||
__d3: null,
|
||||
__chart: null,
|
||||
__xAxisPainter: null,
|
||||
__yAxisPainter: null,
|
||||
__linePainter: null,
|
||||
__areaPainter: null,
|
||||
__xScale: null,
|
||||
__yScale: null,
|
||||
__zoomRectNode: null,
|
||||
__xAxisNode: null,
|
||||
__yAxisNode: null,
|
||||
__dataNode: null,
|
||||
__clipPath: null,
|
||||
__chartWidth: null,
|
||||
__fetchWait: null,
|
||||
__fetchAgain: null,
|
||||
__legendContainer: null,
|
||||
__d3Obj: null,
|
||||
__data: null,
|
||||
getDataArea: function(){
|
||||
if (this.__dataArea) return this.__dataArea;
|
||||
return this.__dataArea =
|
||||
this.__chart.insert("g",':first-child');
|
||||
},
|
||||
getXAxisPainter: function(){
|
||||
if (this.__xAxisPainter) return this.__xAxisPainter;
|
||||
var customTimeFormat = this.__d3.time.format.multi([
|
||||
[".%L", function(d) { return d.getMilliseconds(); }],
|
||||
[":%S", function(d) { return d.getSeconds(); }],
|
||||
["%H:%M", function(d) { return d.getMinutes(); }],
|
||||
["%H:%M", function(d) { return d.getHours(); }],
|
||||
["%m-%d", function(d) { return d.getDay() && d.getDate() != 1; }],
|
||||
["%Y-%m-%d", function(d) { return true }]
|
||||
]);
|
||||
this.__xAxisPainter = this.__d3.svg.axis()
|
||||
.scale(this.getXScale())
|
||||
.orient("bottom")
|
||||
.tickPadding(6)
|
||||
.tickFormat(customTimeFormat);
|
||||
|
||||
return this.__xAxisPainter;
|
||||
},
|
||||
|
||||
getYAxisPainter: function(){
|
||||
if (this.__yAxisPainter) return this.__yAxisPainter;
|
||||
var si = ['p','n','y','m','','k','M','G','T','P'];
|
||||
var d3 = this.__d3;
|
||||
var commasFormatter = d3.format(",.1f");
|
||||
this.__yAxisPainter = d3.svg.axis()
|
||||
.scale(this.getYScale())
|
||||
.orient("left")
|
||||
.tickPadding(6)
|
||||
.tickFormat(function(d){
|
||||
if (d == 0){
|
||||
return d;
|
||||
}
|
||||
var log = Math.log(d)/Math.LN10;
|
||||
var idx = log < 0 ? Math.ceil(log/3) : Math.floor(log/3);
|
||||
var factor = Math.pow(10,idx*3);
|
||||
return commasFormatter(d/factor) + si[idx+4];
|
||||
});
|
||||
|
||||
return this.__yAxisPainter;
|
||||
},
|
||||
|
||||
getXScale: function(){
|
||||
if (this.__xScale) return this.__xScale;
|
||||
this.__xScale = this.__d3.time.scale();
|
||||
this.__xScale.domain([new Date(new Date().getTime() - 24*3600*1000),new Date()]);
|
||||
return this.__xScale;
|
||||
},
|
||||
|
||||
getYScale: function(){
|
||||
if (this.__yScale) return this.__yScale;
|
||||
this.__yScale = this.__d3.scale.linear();
|
||||
return this.__yScale;
|
||||
},
|
||||
|
||||
getDataPainter: function(id){
|
||||
switch(this.getChartDef()[id].cmd){
|
||||
case 'LINE':
|
||||
return this.getLinePainter();
|
||||
break;
|
||||
case 'AREA':
|
||||
return this.getAreaPainter();
|
||||
break;
|
||||
default:
|
||||
this.debug("invalid cmd");
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
getLinePainter: function(){
|
||||
if (this.__linePainter) return this.__linePainter;
|
||||
var xScale = this.getXScale();
|
||||
var yScale = this.getYScale();
|
||||
this.__linePainter = this.__d3.svg.line()
|
||||
.interpolate("step-before")
|
||||
.x(function(d){ return xScale(d.date); })
|
||||
.y(function(d){ return yScale(d.y); })
|
||||
.defined(function(d){ return d.d });
|
||||
return this.__linePainter;
|
||||
},
|
||||
|
||||
getAreaPainter: function(){
|
||||
if (this.__areaPainter) return this.__areaPainter;
|
||||
var xScale = this.getXScale();
|
||||
var yScale = this.getYScale();
|
||||
this.__areaPainter = this.__d3.svg.area()
|
||||
.interpolate("step-before")
|
||||
.x(function(d){ return xScale(d.date); })
|
||||
.y0(function(d){ return yScale(d.y0);})
|
||||
.y1(function(d){ return yScale(d.y); })
|
||||
.defined(function(d){ return d.d });
|
||||
return this.__areaPainter;
|
||||
},
|
||||
|
||||
getZoomRectNode: function(){
|
||||
if (this.__zoomRectNode) return this.__zoomRectNode;
|
||||
var that = this;
|
||||
var zoomer = this.__zoomer = this.__d3.behavior.zoom()
|
||||
.scaleExtent([0.0001, 1000])
|
||||
.on("zoom", function (){that.redraw()});
|
||||
|
||||
zoomer.x(this.getXScale());
|
||||
|
||||
this.__zoomRectNode = this.__chart.append("rect")
|
||||
.style({
|
||||
cursor: 'move',
|
||||
fill: 'none',
|
||||
'pointer-events': 'all'
|
||||
})
|
||||
.call(zoomer);
|
||||
|
||||
return this.__zoomRectNode;
|
||||
},
|
||||
|
||||
getXAxisNode: function(){
|
||||
if (this.__xAxisNode) return this.__xAxisNode;
|
||||
this.__xAxisNode = this.__chart.append("g")
|
||||
.attr("class", "x axis");
|
||||
return this.__xAxisNode;
|
||||
},
|
||||
|
||||
getYAxisNode: function(){
|
||||
if (this.__yAxisNode) return this.__yAxisNode;
|
||||
this.__yAxisNode = this.__chart.append("g")
|
||||
.attr("class", "y axis");
|
||||
return this.__yAxisNode;
|
||||
},
|
||||
|
||||
getClipPath: function(){
|
||||
if (this.__clipPath) return this.__clipPath;
|
||||
ID++;
|
||||
this.__clipPathID = this.getInstance() + '-clipPath-' + ID;
|
||||
this.__clipPath = this.__chart.append("clipPath")
|
||||
.attr('id',this.__clipPathID)
|
||||
.append("rect");
|
||||
return this.__clipPath;
|
||||
},
|
||||
|
||||
getDataNode: function(id){
|
||||
if (this.__dataNode[id]) return this.__dataNode[id];
|
||||
var chartDef = this.getChartDef()[id];
|
||||
var dataArea = this.getDataArea();
|
||||
switch(chartDef.cmd){
|
||||
case 'LINE':
|
||||
this.__dataNode[id] = dataArea.append("path")
|
||||
.attr("clip-path", "url(#"+this.__clipPathID+")")
|
||||
.attr('stroke', chartDef.color)
|
||||
.attr('stroke-width', 2)
|
||||
.attr("fill", "none")
|
||||
.attr("shape-rendering", 'crispEdges');
|
||||
break;
|
||||
case 'AREA':
|
||||
this.__dataNode[id] = dataArea.append("path")
|
||||
.attr("clip-path", "url(#"+this.__clipPathID+")")
|
||||
.attr("fill",chartDef.color);
|
||||
break;
|
||||
default:
|
||||
this.debug("unsupported cmd:" + chartDef.cmd);
|
||||
break;
|
||||
}
|
||||
return this.__dataNode[id];
|
||||
},
|
||||
|
||||
resetChart: function(newValue, oldValue, propertyName){
|
||||
if (this.__dataNode){
|
||||
for (var i=0;i<this.__dataNode.length;i++){
|
||||
this.__dataNode[i].remove();
|
||||
}
|
||||
}
|
||||
this.__dataNode = [];
|
||||
this.__data = null;
|
||||
this.setupLegend();
|
||||
},
|
||||
setupLegend: function(){
|
||||
var lc;
|
||||
if (! this.__legendContainer ) {
|
||||
var margin = this.self(arguments).MARGIN;
|
||||
lc = this.__legendContainer = new qx.ui.core.Widget().set({
|
||||
paddingLeft: margin.left
|
||||
});
|
||||
lc._setLayout(new qx.ui.layout.Flow(15,5));
|
||||
this._add(lc);
|
||||
}
|
||||
else {
|
||||
lc = this.__legendContainer;
|
||||
lc._removeAll();
|
||||
}
|
||||
this.getChartDef().forEach(function(item){
|
||||
var label = new qx.ui.core.Widget();
|
||||
label._setLayout(new qx.ui.layout.HBox(5).set({alignY: 'middle'}));
|
||||
var cu = qx.util.ColorUtil;
|
||||
var borderColorHsb = cu.rgbToHsb(cu.hex6StringToRgb(item.color));
|
||||
borderColorHsb[2] *= 0.9;
|
||||
var borderColor = cu.rgbToHexString(cu.hsbToRgb(borderColorHsb));
|
||||
var box = new qx.ui.core.Widget().set({
|
||||
width: 12,
|
||||
height: 12,
|
||||
allowGrowX: false,
|
||||
allowGrowY: false,
|
||||
marginBottom: 6,
|
||||
decorator: new qx.ui.decoration.Decorator().set({
|
||||
color: [borderColor],
|
||||
width: [1],
|
||||
style: ['solid'],
|
||||
backgroundColor: item.color
|
||||
})
|
||||
});
|
||||
label._add(box);
|
||||
var legend = new qx.ui.basic.Label().set({
|
||||
value: item.legend
|
||||
});
|
||||
label._add(legend);
|
||||
lc._add(label);
|
||||
});
|
||||
},
|
||||
setSize: function(){
|
||||
var el = this.__d3Obj.getContentElement().getDomElement();
|
||||
if (!el) return;
|
||||
// sync screen before we measure things
|
||||
qx.html.Element.flush();
|
||||
var margin = this.self(arguments).MARGIN;
|
||||
var width = qx.bom.element.Dimension.getWidth(el) - margin.left - margin.right;
|
||||
var height = qx.bom.element.Dimension.getHeight(el) - margin.top - margin.bottom;
|
||||
this.__chartWidth = width;
|
||||
|
||||
var xScale = this.getXScale();
|
||||
var yScale = this.getYScale();
|
||||
|
||||
xScale.range([0,width]);
|
||||
yScale.range([height,0]);
|
||||
|
||||
|
||||
this.getClipPath()
|
||||
.attr("width",width)
|
||||
.attr("height",height);
|
||||
|
||||
this.getYAxisPainter()
|
||||
.tickSize(width)
|
||||
.ticks(Math.round(height/50));
|
||||
|
||||
this.getXAxisPainter().tickSize(-height,0);
|
||||
|
||||
for (var i=0;i<this.getChartDef().length;i++){
|
||||
this.getDataNode(i);
|
||||
}
|
||||
this.getYAxisNode()
|
||||
.attr("transform", "translate(" + width + ",0)");
|
||||
this.getXAxisNode()
|
||||
.attr("transform", "translate(0," + height + ")");
|
||||
|
||||
this.getZoomRectNode()
|
||||
.attr('width',width)
|
||||
.attr('height',height);
|
||||
|
||||
this.__zoomer.size([width,height]);
|
||||
this.redraw();
|
||||
},
|
||||
|
||||
trackingRedraw: function(){
|
||||
if (this.getTrackCurrentTime()){
|
||||
var dates = this.getXScale().domain();
|
||||
var interval = dates[1].getTime() - dates[0].getTime();
|
||||
dates[1] = new Date();
|
||||
dates[0] = new Date(dates[1].getTime() - interval);
|
||||
this.getXScale().domain(dates);
|
||||
this.redraw();
|
||||
}
|
||||
},
|
||||
|
||||
yScaleRedraw: function(){
|
||||
var dates = this.getXScale().domain();
|
||||
if (this.__data){
|
||||
var maxValue = 0;
|
||||
for(var i=0;i<this.getChartDef().length;i++){
|
||||
if (!this.__data.data[i]) continue;
|
||||
this.__data.data[i].forEach(function(item){
|
||||
if (item.y > maxValue && item.date >= dates[0] && item.date <= dates[1]){
|
||||
maxValue = item.y;
|
||||
}
|
||||
})
|
||||
}
|
||||
this.getYScale().domain([0,maxValue]).nice();
|
||||
|
||||
this.getYAxisNode().call(this.getYAxisPainter());
|
||||
|
||||
for(var i=0;i<this.getChartDef().length;i++){
|
||||
var node = this.getDataNode(i);
|
||||
if (node.data().length > 0){
|
||||
node.attr("d",this.getDataPainter(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
redraw: function(){
|
||||
var dates = this.getXScale().domain();
|
||||
var start = Math.round(dates[0].getTime()/1000);
|
||||
var end = Math.round(dates[1].getTime()/1000);
|
||||
var dataStep = Math.round((end-start)/ this.__chartWidth);
|
||||
var extra = Math.round(end - start );
|
||||
var d3 = this.__d3;
|
||||
|
||||
start -= extra;
|
||||
end += extra;
|
||||
|
||||
|
||||
this.yScaleRedraw();
|
||||
|
||||
this.getXAxisNode().call(this.getXAxisPainter());
|
||||
|
||||
|
||||
if (this.__fetchWait){
|
||||
this.__fetchAgain = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
var existingData = this.dataSlicer(start,end,dataStep);
|
||||
if (existingData.missingStart == existingData.missingEnd){
|
||||
return;
|
||||
}
|
||||
|
||||
var needChartDef = this.getChartDef().length == 0;
|
||||
|
||||
var rpc = ep.data.Server.getInstance();
|
||||
var that = this;
|
||||
this.__fetchWait = 1;
|
||||
rpc.callAsyncSmart(function(ret){
|
||||
|
||||
var d3Data = that.__data = that.d3DataTransformer(ret,dataStep);
|
||||
|
||||
var maxValue = 0;
|
||||
|
||||
for(var i=0;i<ret.length;i++){
|
||||
var dataNode = that.getDataNode(i);
|
||||
if (existingData.prepend){
|
||||
d3Data.data[i] = existingData.prepend[i].concat(d3Data.data[i],existingData.append[i]);
|
||||
}
|
||||
dataNode.data([d3Data.data[i]]);
|
||||
}
|
||||
|
||||
that.yScaleRedraw();
|
||||
that.__fetchWait = 0;
|
||||
// if we skipped one, lets redraw again just to be sure we got it all
|
||||
if (this.__fetchAgain == 1){
|
||||
qx.event.Timer.once(that.redraw,that,0);
|
||||
this.__fetchAgain = 0;
|
||||
}
|
||||
},
|
||||
'visualize', this.getInstance(), {
|
||||
recId : this.getRecId(),
|
||||
step : dataStep,
|
||||
start : existingData.missingStart,
|
||||
end : existingData.missingEnd,
|
||||
view : this.getView()
|
||||
});
|
||||
},
|
||||
|
||||
/* figure out what data range we are missing and keep the bits we already have */
|
||||
|
||||
dataSlicer: function(start,end,dataStep){
|
||||
var oldData = this.__data;
|
||||
var missingStart = start;
|
||||
var missingEnd = end;
|
||||
var prepend = [];
|
||||
var append = [];
|
||||
var keepData = oldData != null && typeof(oldData) == 'object' && Math.round(oldData.dataStep) == Math.round(dataStep);
|
||||
if (!keepData) {
|
||||
return { missingStart: missingStart, missingEnd: missingEnd};
|
||||
}
|
||||
var oldStart = oldData.data[0][0].date.getTime()/1000;
|
||||
var oldEnd = oldData.data[0][oldData.data[0].length-1].date.getTime()/1000;
|
||||
// prepend the existing data to the new data
|
||||
var prependMode = oldStart <= start && oldEnd >= start;
|
||||
var appendMode = oldEnd >= end && oldStart <= end;
|
||||
for (var i=0;i<oldData.data.length;i++){
|
||||
append[i] = [];
|
||||
prepend[i] = [];
|
||||
var len = oldData.data[i].length;
|
||||
for (var ii=0;ii<len;ii++){
|
||||
var item = oldData.data[i][ii];
|
||||
var date = item.date.getTime()/1000;
|
||||
if ( prependMode && date >= start ) {
|
||||
prepend[i].push(item);
|
||||
missingStart = date+dataStep;
|
||||
}
|
||||
if (appendMode && date <= end ){
|
||||
append[i].push(item);
|
||||
if ( date < missingEnd ) {
|
||||
missingEnd = date-dataStep;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* lets make sure don't trip over ourselves */
|
||||
if (missingStart > missingEnd){
|
||||
this.debug("missingStart:"+missingStart+" missingEnd:"+missingEnd);
|
||||
missingEnd = missingStart;
|
||||
}
|
||||
|
||||
return {
|
||||
missingStart: missingStart,
|
||||
missingEnd: missingEnd,
|
||||
append: append,
|
||||
prepend: prepend
|
||||
}
|
||||
},
|
||||
|
||||
d3DataTransformer: function(data,dataStep){
|
||||
var d3 = this.__d3;
|
||||
if (data == null || typeof(data) != 'object' || data[0] == null){
|
||||
return null;
|
||||
}
|
||||
var minStep = 24*3600;
|
||||
var minStart = (new Date).getTime()/1000;
|
||||
data.forEach(function(d){
|
||||
if (d.status != 'ok') return;
|
||||
if (minStep == null || minStep > d.step){
|
||||
minStep = d.step;
|
||||
minStart = d.start;
|
||||
}
|
||||
});
|
||||
|
||||
var d3Data = [];
|
||||
for (var i=0; i<data.length;i++){
|
||||
d3Data[i] = [];
|
||||
var chartDef = this.getChartDef()[i];
|
||||
if (data[i].status != 'ok') {
|
||||
data[i].values = [NaN];
|
||||
data[i].step = 3600*24;
|
||||
}
|
||||
var stack = chartDef.stack;
|
||||
var len = data[i].values.length;
|
||||
var st = minStep/data[i].step;
|
||||
for (var ii=0;ii*st < len ; ii++){
|
||||
var y0 = 0;
|
||||
if (stack && i > 0 && d3Data[i-1][ii] != null && typeof(d3Data[i-1][ii]) == 'object'){
|
||||
y0 = d3Data[i-1][ii].y;
|
||||
}
|
||||
var yval = parseFloat(data[i].values[Math.round(ii*st)]);
|
||||
d3Data[i][ii] = {
|
||||
y: (isNaN(yval) ? 0 : yval) +y0,
|
||||
y0: y0,
|
||||
d: !isNaN(yval),
|
||||
date: new Date((minStart+ii*minStep)*1000)
|
||||
}
|
||||
}
|
||||
}
|
||||
return {data:d3Data,dataStep: dataStep}
|
||||
}
|
||||
},
|
||||
|
||||
destruct : function() {
|
||||
this.__timer.stop();
|
||||
}
|
||||
});
|
BIN
htdocs/logo.png
Normal file
BIN
htdocs/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
3
htdocs/oid-mib-cache.txt
Normal file
3
htdocs/oid-mib-cache.txt
Normal file
@ -0,0 +1,3 @@
|
||||
ssCpuRawUser 1.3.6.1.4.1.2021.11.50
|
||||
ssCpuRawSystem 1.3.6.1.4.1.2021.11.52
|
||||
ssCpuRawNice 1.3.6.1.4.1.2021.11.51
|
@ -8,8 +8,8 @@ html {
|
||||
body {
|
||||
font-family: Verdana, Arial, sans-serif;
|
||||
font-size: 12px;
|
||||
background: #101010;
|
||||
color: #E0E0E0;
|
||||
background: #F8F8F8;
|
||||
color: #202020;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 99%;
|
||||
@ -23,7 +23,7 @@ hr {
|
||||
}
|
||||
|
||||
input {
|
||||
background-color: #FDFFEE;
|
||||
background-color: #F8F8F8;
|
||||
border: 1px solid #2E1500;
|
||||
color: #2E1500;
|
||||
padding: 2px 3px;
|
||||
@ -58,25 +58,29 @@ li {
|
||||
h1 {
|
||||
color: #E0E0E0;
|
||||
font-size: 18px;
|
||||
margin-top: 0;
|
||||
padding: 15px 10px;
|
||||
text-align: right;
|
||||
background: url(/logo.png) no-repeat left center #404040;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #e0e0e0;
|
||||
color: #404040;
|
||||
font-size: 16px;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid #cacaca;
|
||||
border-bottom: 1px solid #A0A0A0;
|
||||
margin-top: 3em;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
h3 {
|
||||
color: #e0e0e0;
|
||||
color: #404040;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
color: #e0e0e0;
|
||||
color: #404040;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
@ -90,7 +94,8 @@ hr {
|
||||
|
||||
div {
|
||||
float: left;
|
||||
background-color: #404040;
|
||||
margin: 0.5em;
|
||||
background-color: #E0e0e0;
|
||||
margin: 0;
|
||||
padding: 0.5em 0em;
|
||||
}
|
||||
|
||||
|
BIN
rrd/br0tkasten.cpu.rrd
Normal file
BIN
rrd/br0tkasten.cpu.rrd
Normal file
Binary file not shown.
BIN
rrd/br0tkasten.estconn.rrd
Normal file
BIN
rrd/br0tkasten.estconn.rrd
Normal file
Binary file not shown.
BIN
rrd/br0tkasten.eth0.rrd
Normal file
BIN
rrd/br0tkasten.eth0.rrd
Normal file
Binary file not shown.
BIN
rrd/br0tkasten.memtotal.rrd
Normal file
BIN
rrd/br0tkasten.memtotal.rrd
Normal file
Binary file not shown.
BIN
rrd/br0tkasten.procs.rrd
Normal file
BIN
rrd/br0tkasten.procs.rrd
Normal file
Binary file not shown.
BIN
rrd/br0tkasten.swap.rrd
Normal file
BIN
rrd/br0tkasten.swap.rrd
Normal file
Binary file not shown.
BIN
rrd/br0tkasten.tap0.rrd
Normal file
BIN
rrd/br0tkasten.tap0.rrd
Normal file
Binary file not shown.
BIN
rrd/br0tkasten.users.rrd
Normal file
BIN
rrd/br0tkasten.users.rrd
Normal file
Binary file not shown.
BIN
rrd/ddwrt.numclients.rrd
Normal file
BIN
rrd/ddwrt.numclients.rrd
Normal file
Binary file not shown.
BIN
rrd/ddwrt.vlan2.rrd
Normal file
BIN
rrd/ddwrt.vlan2.rrd
Normal file
Binary file not shown.
BIN
rrd/kodi.cpu.rrd
Normal file
BIN
rrd/kodi.cpu.rrd
Normal file
Binary file not shown.
BIN
rrd/kodi.eth0.rrd
Normal file
BIN
rrd/kodi.eth0.rrd
Normal file
Binary file not shown.
BIN
rrd/kodi.memtotal.rrd
Normal file
BIN
rrd/kodi.memtotal.rrd
Normal file
Binary file not shown.
BIN
rrd/kodi.swap.rrd
Normal file
BIN
rrd/kodi.swap.rrd
Normal file
Binary file not shown.
BIN
rrd/kodi.tap0.rrd
Normal file
BIN
rrd/kodi.tap0.rrd
Normal file
Binary file not shown.
BIN
rrd/kodi.temp.rrd
Normal file
BIN
rrd/kodi.temp.rrd
Normal file
Binary file not shown.
BIN
rrd/kodi.tv.rrd
Normal file
BIN
rrd/kodi.tv.rrd
Normal file
Binary file not shown.
BIN
rrd/mrtg-l.png
Normal file
BIN
rrd/mrtg-l.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 538 B |
BIN
rrd/mrtg-m.png
Normal file
BIN
rrd/mrtg-m.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 414 B |
BIN
rrd/mrtg-r.png
Normal file
BIN
rrd/mrtg-r.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
BIN
rrd/nas.cpu.rrd
Normal file
BIN
rrd/nas.cpu.rrd
Normal file
Binary file not shown.
BIN
rrd/nas.eth0.rrd
Normal file
BIN
rrd/nas.eth0.rrd
Normal file
Binary file not shown.
BIN
rrd/nas.memtotal.rrd
Normal file
BIN
rrd/nas.memtotal.rrd
Normal file
Binary file not shown.
BIN
rrd/nas.swap.rrd
Normal file
BIN
rrd/nas.swap.rrd
Normal file
Binary file not shown.
BIN
rrd/nas.tap0.rrd
BIN
rrd/nas.tap0.rrd
Binary file not shown.
BIN
rrd/nas.temp.rrd
BIN
rrd/nas.temp.rrd
Binary file not shown.
5
rrd/oid-mib-cache.txt
Normal file
5
rrd/oid-mib-cache.txt
Normal file
@ -0,0 +1,5 @@
|
||||
ssCpuRawUser 1.3.6.1.4.1.2021.11.50
|
||||
ssCpuRawUser 1.3.6.1.4.1.2021.11.50
|
||||
ssCpuRawSystem 1.3.6.1.4.1.2021.11.52
|
||||
ssCpuRawNice 1.3.6.1.4.1.2021.11.51
|
||||
ssCpuRawNice 1.3.6.1.4.1.2021.11.51
|
10
tmpl/br0tkasten.cpu.tmpl
Normal file
10
tmpl/br0tkasten.cpu.tmpl
Normal file
@ -0,0 +1,10 @@
|
||||
-v CPU utilization
|
||||
-t [br0tkasten] CPU utilization
|
||||
--full-size-mode
|
||||
--color=BACK#343637
|
||||
--color=CANVAS#F0F0F0
|
||||
--color=FONT#F0F0F0
|
||||
--font=TITLE:12:DejaVu Bold
|
||||
DEF:in=/var/www/mrtg/rrd/br0tkasten.cpu.rrd:ds0:AVERAGE
|
||||
AREA:in#CC9A5780
|
||||
LINE1:in#CC9A57
|
10
tmpl/br0tkasten.estconn.tmpl
Normal file
10
tmpl/br0tkasten.estconn.tmpl
Normal file
@ -0,0 +1,10 @@
|
||||
-v established connections
|
||||
-t [br0tkasten] established connections
|
||||
--full-size-mode
|
||||
--color=BACK#343637
|
||||
--color=CANVAS#F0F0F0
|
||||
--color=FONT#F0F0F0
|
||||
--font=TITLE:12:DejaVu Bold
|
||||
DEF:in=/var/www/mrtg/rrd/br0tkasten.estconn.rrd:ds0:AVERAGE
|
||||
AREA:in#CC9A5780
|
||||
LINE1:in#CC9A57
|
16
tmpl/br0tkasten.eth0.tmpl
Normal file
16
tmpl/br0tkasten.eth0.tmpl
Normal file
@ -0,0 +1,16 @@
|
||||
-v in/up bps
|
||||
-t [br0tkasten] eth0
|
||||
--full-size-mode
|
||||
--color=BACK#343637
|
||||
--color=CANVAS#F0F0F0
|
||||
--color=FONT#F0F0F0
|
||||
--font=TITLE:12:DejaVu Bold
|
||||
DEF:d=/var/www/mrtg/rrd/br0tkasten.eth0.rrd:ds0:AVERAGE
|
||||
DEF:u=/var/www/mrtg/rrd/br0tkasten.eth0.rrd:ds1:AVERAGE
|
||||
CDEF:down=d,8,*
|
||||
CDEF:up=u,-8,*
|
||||
AREA:down#CC9A5780:Down
|
||||
AREA:up#2EA34960:Up
|
||||
LINE1:down#CC9A57
|
||||
LINE1:up#2EA349
|
||||
LINE1:0#000000
|
10
tmpl/br0tkasten.memtotal.tmpl
Normal file
10
tmpl/br0tkasten.memtotal.tmpl
Normal file
@ -0,0 +1,10 @@
|
||||
-v RAM
|
||||
-t [br0tkasten] Memory usage
|
||||
--full-size-mode
|
||||
--color=BACK#343637
|
||||
--color=CANVAS#F0F0F0
|
||||
--color=FONT#F0F0F0
|
||||
--font=TITLE:12:DejaVu Bold
|
||||
DEF:in=/var/www/mrtg/rrd/br0tkasten.memtotal.rrd:ds0:AVERAGE
|
||||
AREA:in#CC9A5780
|
||||
LINE1:in#CC9A57
|
10
tmpl/br0tkasten.procs.tmpl
Normal file
10
tmpl/br0tkasten.procs.tmpl
Normal file
@ -0,0 +1,10 @@
|
||||
-v Processes
|
||||
-t [br0tkasten] Processes
|
||||
--full-size-mode
|
||||
--color=BACK#343637
|
||||
--color=CANVAS#F0F0F0
|
||||
--color=FONT#F0F0F0
|
||||
--font=TITLE:12:DejaVu Bold
|
||||
DEF:in=/var/www/mrtg/rrd/br0tkasten.procs.rrd:ds0:AVERAGE
|
||||
AREA:in#CC9A5780
|
||||
LINE1:in#CC9A57
|
10
tmpl/br0tkasten.swap.tmpl
Normal file
10
tmpl/br0tkasten.swap.tmpl
Normal file
@ -0,0 +1,10 @@
|
||||
-v SWAP usage
|
||||
-t [br0tkasten] SWAP
|
||||
--full-size-mode
|
||||
--color=BACK#343637
|
||||
--color=CANVAS#F0F0F0
|
||||
--color=FONT#F0F0F0
|
||||
--font=TITLE:12:DejaVu Bold
|
||||
DEF:in=/var/www/mrtg/rrd/br0tkasten.swap.rrd:ds0:AVERAGE
|
||||
AREA:in#CC9A5780
|
||||
LINE1:in#CC9A57
|
16
tmpl/br0tkasten.tap0.tmpl
Normal file
16
tmpl/br0tkasten.tap0.tmpl
Normal file
@ -0,0 +1,16 @@
|
||||
-v in/up bps
|
||||
-t [br0tkasten] tap0
|
||||
--full-size-mode
|
||||
--color=BACK#343637
|
||||
--color=CANVAS#F0F0F0
|
||||
--color=FONT#F0F0F0
|
||||
--font=TITLE:12:DejaVu Bold
|
||||
DEF:d=/var/www/mrtg/rrd/br0tkasten.tap0.rrd:ds0:AVERAGE
|
||||
DEF:u=/var/www/mrtg/rrd/br0tkasten.tap0.rrd:ds1:AVERAGE
|
||||
CDEF:down=d,8,*
|
||||
CDEF:up=u,-8,*
|
||||
AREA:down#CC9A578060:Down
|
||||
AREA:up#2EA3496060:Up
|
||||
LINE1:down#CC9A57
|
||||
LINE1:up#2EA349
|
||||
LINE1:0#000000
|
10
tmpl/br0tkasten.users.tmpl
Normal file
10
tmpl/br0tkasten.users.tmpl
Normal file
@ -0,0 +1,10 @@
|
||||
-v user
|
||||
-t [br0tkasten] users
|
||||
--full-size-mode
|
||||
--color=BACK#343637
|
||||
--color=CANVAS#F0F0F0
|
||||
--color=FONT#F0F0F0
|
||||
--font=TITLE:12:DejaVu Bold
|
||||
DEF:in=/var/www/mrtg/rrd/br0tkasten.users.rrd:ds0:AVERAGE
|
||||
AREA:in#CC9A5780
|
||||
LINE1:in#CC9A57
|
10
tmpl/ddwrt.numclients.tmpl
Normal file
10
tmpl/ddwrt.numclients.tmpl
Normal file
@ -0,0 +1,10 @@
|
||||
-v clients connected
|
||||
-t [DD-WRT] Number of wifi clients
|
||||
--full-size-mode
|
||||
--color=BACK#343637
|
||||
--color=CANVAS#F0F0F0
|
||||
--color=FONT#F0F0F0
|
||||
--font=TITLE:12:DejaVu Bold
|
||||
DEF:in=/var/www/mrtg/rrd/ddwrt.numclients.rrd:ds0:AVERAGE
|
||||
AREA:in#CC9A5780
|
||||
LINE1:in#CC9A57
|
16
tmpl/ddwrt.vlan2.tmpl
Normal file
16
tmpl/ddwrt.vlan2.tmpl
Normal file
@ -0,0 +1,16 @@
|
||||
-v in/up bps
|
||||
-t [DD-WRT] vlan2
|
||||
--full-size-mode
|
||||
--color=BACK#343637
|
||||
--color=CANVAS#F0F0F0
|
||||
--color=FONT#F0F0F0
|
||||
--font=TITLE:12:DejaVu Bold
|
||||
DEF:d=/var/www/mrtg/rrd/ddwrt.vlan2.rrd:ds0:AVERAGE
|
||||
DEF:u=/var/www/mrtg/rrd/ddwrt.vlan2.rrd:ds1:AVERAGE
|
||||
CDEF:down=d,8,*
|
||||
CDEF:up=u,-8,*
|
||||
AREA:down#CC9A5780:Down
|
||||
AREA:up#2EA34960:Up
|
||||
LINE1:down#CC9A57
|
||||
LINE1:up#045C55
|
||||
LINE1:0#000000
|
46
tmpl/details.tmpl
Normal file
46
tmpl/details.tmpl
Normal file
@ -0,0 +1,46 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link href="/style.css" rel="stylesheet">
|
||||
<script type="text/javascript" src="/js/q-4.1.min.js"></script>
|
||||
<script type="text/javascript" src="/js/moment.js"></script>
|
||||
<script type="text/javascript" src="/js/moment-timezone-with-data.js"></script>
|
||||
<script type="text/javascript" src="/js/rrdGraphPng.js"></script>
|
||||
<script type="text/javascript" src="/js/rrdGraphCtrl.js"></script>
|
||||
<script type="text/javascript">
|
||||
q.ready(function(){
|
||||
|
||||
// 'activate' the charts
|
||||
var graph = q('.graph').rrdGraphPng({
|
||||
canvasPadding: 120,
|
||||
initialStart: null
|
||||
});
|
||||
|
||||
// crate a control panel and attach it to the charts
|
||||
q('#ctrl').rrdGraphCtrl(graph,{
|
||||
initialTimeRange: 'Last 24 Hours',
|
||||
resetTimeOnDateChange: true
|
||||
});
|
||||
|
||||
// you can also remove all the magic again
|
||||
q('#rebinder').on('click',function(){
|
||||
// q('#ctrl').dispose();
|
||||
q('.graph').dispose();
|
||||
var graph = q('.graph').rrdGraphPng({
|
||||
canvasPadding: 120,
|
||||
initialStart: null
|
||||
});
|
||||
q('#ctrl').rebind(graph);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="ctrl"></div><br/>
|
||||
<div><img
|
||||
style="width:1000px;height:300px" class="graph"
|
||||
data-src-template="/cgi-bin/graph.pl?graph=[% GRAPH %]&width=1000&height=300&start={{start}}&end={{end}}"
|
||||
/></div>
|
||||
</body>
|
||||
</html>
|
10
tmpl/kodi.cpu.tmpl
Normal file
10
tmpl/kodi.cpu.tmpl
Normal file
@ -0,0 +1,10 @@
|
||||
-v utilization
|
||||
-t [kodi] CPU
|
||||
--full-size-mode
|
||||
--color=BACK#343637
|
||||
--color=CANVAS#F0F0F0
|
||||
--color=FONT#F0F0F0
|
||||
--font=TITLE:12:DejaVu Bold
|
||||
DEF:in=/var/www/mrtg/rrd/kodi.cpu.rrd:ds0:AVERAGE
|
||||
AREA:in#CC9A5780
|
||||
LINE1:in#CC9A57
|
16
tmpl/kodi.eth0.tmpl
Normal file
16
tmpl/kodi.eth0.tmpl
Normal file
@ -0,0 +1,16 @@
|
||||
-v in/up
|
||||
-t [kodi] eth0
|
||||
--full-size-mode
|
||||
--color=BACK#343637
|
||||
--color=CANVAS#F0F0F0
|
||||
--color=FONT#F0F0F0
|
||||
--font=TITLE:12:DejaVu Bold
|
||||
DEF:d=/var/www/mrtg/rrd/kodi.eth0.rrd:ds0:AVERAGE
|
||||
DEF:u=/var/www/mrtg/rrd/kodi.eth0.rrd:ds1:AVERAGE
|
||||
CDEF:down=d,8,*
|
||||
CDEF:up=u,-8,*
|
||||
AREA:down#CC9A5780:Down
|
||||
AREA:up#2EA34960:Up
|
||||
LINE1:down#CC9A57
|
||||
LINE1:up#2EA349
|
||||
LINE1:0#000000
|
10
tmpl/kodi.memtotal.tmpl
Normal file
10
tmpl/kodi.memtotal.tmpl
Normal file
@ -0,0 +1,10 @@
|
||||
-v RAM
|
||||
-t [kodi] memory utilization
|
||||
--full-size-mode
|
||||
--color=BACK#343637
|
||||
--color=CANVAS#F0F0F0
|
||||
--color=FONT#F0F0F0
|
||||
--font=TITLE:12:DejaVu Bold
|
||||
DEF:in=/var/www/mrtg/rrd/kodi.memtotal.rrd:ds0:AVERAGE
|
||||
AREA:in#CC9A5780
|
||||
LINE1:in#CC9A57
|
10
tmpl/kodi.swap.tmpl
Normal file
10
tmpl/kodi.swap.tmpl
Normal file
@ -0,0 +1,10 @@
|
||||
-v swap
|
||||
-t [kodi] swap utilization
|
||||
--full-size-mode
|
||||
--color=BACK#343637
|
||||
--color=CANVAS#F0F0F0
|
||||
--color=FONT#F0F0F0
|
||||
--font=TITLE:12:DejaVu Bold
|
||||
DEF:in=/var/www/mrtg/rrd/kodi.swap.rrd:ds0:AVERAGE
|
||||
AREA:in#CC9A5780
|
||||
LINE1:in#CC9A57
|
16
tmpl/kodi.tap0.tmpl
Normal file
16
tmpl/kodi.tap0.tmpl
Normal file
@ -0,0 +1,16 @@
|
||||
-v in/up
|
||||
-t [kodi] tap0
|
||||
--full-size-mode
|
||||
--color=BACK#343637
|
||||
--color=CANVAS#F0F0F0
|
||||
--color=FONT#F0F0F0
|
||||
--font=TITLE:12:DejaVu Bold
|
||||
DEF:d=/var/www/mrtg/rrd/kodi.tap0.rrd:ds0:AVERAGE
|
||||
DEF:u=/var/www/mrtg/rrd/kodi.tap0.rrd:ds1:AVERAGE
|
||||
CDEF:down=d,8,*
|
||||
CDEF:up=u,-8,*
|
||||
AREA:down#CC9A5780:Down
|
||||
AREA:up#2EA34960:Up
|
||||
LINE1:down#CC9A57
|
||||
LINE1:up#2EA349
|
||||
LINE1:0#000000
|
15
tmpl/kodi.temp.tmpl
Normal file
15
tmpl/kodi.temp.tmpl
Normal file
@ -0,0 +1,15 @@
|
||||
-v Celsius
|
||||
-t [kodi] Temperature
|
||||
--full-size-mode
|
||||
--color=BACK#343637
|
||||
--color=CANVAS#F0F0F0
|
||||
--color=FONT#F0F0F0
|
||||
--font=TITLE:12:DejaVu Bold
|
||||
DEF:in=/var/www/mrtg/rrd/kodi.temp.rrd:ds0:AVERAGE
|
||||
CDEF:red=in,54,GT,in,UNKN,IF
|
||||
CDEF:green=in,54,GT,54,in,IF
|
||||
AREA:red#C7424EC0
|
||||
AREA:green#FFFFFF
|
||||
AREA:green#2EA34960
|
||||
LINE1:green#2EA349
|
||||
LINE1:red#C7424E
|
10
tmpl/kodi.tv.tmpl
Normal file
10
tmpl/kodi.tv.tmpl
Normal file
@ -0,0 +1,10 @@
|
||||
-v on/off
|
||||
-t [kodi] TV stats
|
||||
--full-size-mode
|
||||
--color=BACK#343637
|
||||
--color=CANVAS#F0F0F0
|
||||
--color=FONT#F0F0F0
|
||||
--font=TITLE:12:DejaVu Bold
|
||||
DEF:in=/var/www/mrtg/rrd/kodi.tv.rrd:ds0:AVERAGE
|
||||
AREA:in#CC9A5780
|
||||
LINE1:in#CC9A57
|
10
tmpl/nas.cpu.tmpl
Normal file
10
tmpl/nas.cpu.tmpl
Normal file
@ -0,0 +1,10 @@
|
||||
-v utilization
|
||||
-t [nas] CPU
|
||||
--full-size-mode
|
||||
--color=BACK#343637
|
||||
--color=CANVAS#F0F0F0
|
||||
--color=FONT#F0F0F0
|
||||
--font=TITLE:12:DejaVu Bold
|
||||
DEF:in=/var/www/mrtg/rrd/nas.cpu.rrd:ds0:AVERAGE
|
||||
AREA:in#CC9A5780
|
||||
LINE1:in#CC9A57
|
16
tmpl/nas.eth0.tmpl
Normal file
16
tmpl/nas.eth0.tmpl
Normal file
@ -0,0 +1,16 @@
|
||||
-v in/up
|
||||
-t [nas] eth0
|
||||
--full-size-mode
|
||||
--color=BACK#343637
|
||||
--color=CANVAS#F0F0F0
|
||||
--color=FONT#F0F0F0
|
||||
--font=TITLE:12:DejaVu Bold
|
||||
DEF:u=/var/www/mrtg/rrd/nas.eth0.rrd:ds0:AVERAGE
|
||||
DEF:d=/var/www/mrtg/rrd/nas.eth0.rrd:ds1:AVERAGE
|
||||
CDEF:down=d,8,*
|
||||
CDEF:up=u,-8,*
|
||||
AREA:down#CC9A5780:Down
|
||||
AREA:up#2EA34960:Up
|
||||
LINE1:down#662C00
|
||||
LINE1:up#005A66
|
||||
LINE1:0#000000
|
10
tmpl/nas.memtotal.tmpl
Normal file
10
tmpl/nas.memtotal.tmpl
Normal file
@ -0,0 +1,10 @@
|
||||
-v RAM
|
||||
-t [nas] memory
|
||||
--full-size-mode
|
||||
--color=BACK#343637
|
||||
--color=CANVAS#F0F0F0
|
||||
--color=FONT#F0F0F0
|
||||
--font=TITLE:12:DejaVu Bold
|
||||
DEF:in=/var/www/mrtg/rrd/nas.memtotal.rrd:ds0:AVERAGE
|
||||
AREA:in#CC9A5780
|
||||
LINE1:in#CC9A57
|
10
tmpl/nas.swap.tmpl
Normal file
10
tmpl/nas.swap.tmpl
Normal file
@ -0,0 +1,10 @@
|
||||
-v utilization
|
||||
-t [nas] Swap
|
||||
--full-size-mode
|
||||
--color=BACK#343637
|
||||
--color=CANVAS#F0F0F0
|
||||
--color=FONT#F0F0F0
|
||||
--font=TITLE:12:DejaVu Bold
|
||||
DEF:in=/var/www/mrtg/rrd/nas.swap.rrd:ds0:AVERAGE
|
||||
AREA:in#CC9A5780
|
||||
LINE1:in#CC9A57
|
@ -1,12 +1,16 @@
|
||||
-v in/out
|
||||
-v in/up
|
||||
-t [nas] tap0
|
||||
--color=BACK#909090
|
||||
--color=CANVAS#C5C5C5
|
||||
DEF:in=/var/www/mrtg/rrd/nas.tap0.rrd:ds0:AVERAGE
|
||||
DEF:out=/var/www/mrtg/rrd/nas.tap0.rrd:ds1:AVERAGE
|
||||
CDEF:invout=out,-1,*
|
||||
AREA:in#25679F#7E99B0:Down
|
||||
AREA:invout#25679F#7E99B0:Up
|
||||
LINE1:in#040404
|
||||
LINE1:invout#040404
|
||||
--full-size-mode
|
||||
--color=BACK#343637
|
||||
--color=CANVAS#F0F0F0
|
||||
--color=FONT#F0F0F0
|
||||
--font=TITLE:12:DejaVu Bold
|
||||
DEF:d=/var/www/mrtg/rrd/nas.tap0.rrd:ds0:AVERAGE
|
||||
DEF:u=/var/www/mrtg/rrd/nas.tap0.rrd:ds1:AVERAGE
|
||||
CDEF:down=d,8,*
|
||||
CDEF:up=u,-8,*
|
||||
AREA:down#CC9A5780:Down
|
||||
AREA:up#2EA34960:Up
|
||||
LINE1:down#CC9A57
|
||||
LINE1:up#2EA349
|
||||
LINE1:0#000000
|
||||
|
@ -1,10 +1,15 @@
|
||||
-v Celsius
|
||||
-t [nas] Temperature
|
||||
--color=BACK#909090
|
||||
--color=CANVAS#C5C5C5
|
||||
--full-size-mode
|
||||
--color=BACK#343637
|
||||
--color=CANVAS#F0F0F0
|
||||
--color=FONT#F0F0F0
|
||||
--font=TITLE:12:DejaVu Bold
|
||||
DEF:in=/var/www/mrtg/rrd/nas.temp.rrd:ds0:AVERAGE
|
||||
CDEF:red=in,54,GT,in,UNKN,IF
|
||||
CDEF:green=in,54,GT,54,in,IF
|
||||
AREA:red#FF0000
|
||||
AREA:green#00FF00
|
||||
LINE1:in#040404
|
||||
AREA:red#C7424EC0
|
||||
AREA:green#FFFFFF
|
||||
AREA:green#2EA34960
|
||||
LINE1:green#2EA349
|
||||
LINE1:red#C7424E
|
||||
|
Loading…
x
Reference in New Issue
Block a user