1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160 | # Common functions for rrdtool graphing pages
proc rrdgraph {graphname period} {
switch -glob -- $period \
d* {
set duration day
set info(start) e-1d
set info(step) 300
set info(type) AVERAGE
set info(title) "24 Hours"
} \
w* {
set duration week
set info(start) e-1w
set info(step) 1800
set info(type) AVERAGE
set info(title) "1 Week"
} \
m* {
set duration month
set info(start) e-1month
set info(step) 3600
set info(type) AVERAGE
set info(title) "1 Month"
} \
y* {
set duration year
set info(start) e-1year
set info(step) 43200
set info(type) AVERAGE
set info(title) "1 year"
} \
* {
set duration hour
set info(start) e-1h
set info(step) 30
set info(type) LAST
set info(title) "1 Hour"
}
set host [env HOST ""]
set info(rrd) $host/settings/logging/system.rrd
file mkdir $host/tmp/rrd/
set info(png) $host/tmp/rrd/${graphname}_${duration}.png
set params {}
lappend params -s $info(start) -e now -S $info(step)
lambda {cmd args} {info params} {
set params [rrdgraph.$cmd $params $info {*}$args]
}
}
proc rrdgraph.close {params info} {
lassign [info level 0] r
rename $r ""
}
proc rrdgraph.stdinit {params info} {
rrdgraph.size $params $info 620 200
}
proc rrdgraph.size {params info w h} {
lappend params -w $w -h $h
}
proc rrdgraph.title {params info title} {
lappend params -t "$title ($info(title))"
}
proc rrdgraph.ylabel {params info ylabel} {
lappend params -v $ylabel
}
proc rrdgraph.comment {params info text} {
lappend params COMMENT:[rrdgraph._escape $text]
}
proc rrdgraph.params {params info args} {
lappend params {*}$args
}
# Escapes a label to convert \n to \\n and : to \\:
proc rrdgraph._escape {label} {
string map [list \n \\n : \\:] $label
}
# Optional arguments are:
# -col graph colour, otherwise uses a default
# -width width of the line, otherwise 2
# -label label for the graph, otherwise none
# -format format string for the x axis, otherwise none
# -units units string, otherwise none
# -multiplier multiply the raw value by this, otherwise 1
proc rrdgraph.line {params info name var args} {
set opts [dict merge {-col #1111AA -width 2 -label "" -format "" -units "" -multiplier 1} $args]
set opts(-label) [rrdgraph._escape $opts(-label)]
lappend params DEF:$name=$info(rrd):$var:$info(type)
lappend params CDEF:g_$name=$name,$opts(-multiplier),*
lappend params LINE$opts(-width):g_$name$opts(-col):$opts(-label)
if {$opts(-format) ne ""} {
set opts(-format) [rrdgraph._escape $opts(-format)]
set opts(-units) [rrdgraph._escape $opts(-units)]
lappend params VDEF:min$name=g_$name,MINIMUM "GPRINT:min$name:Min $opts(-format)"
lappend params VDEF:max$name=g_$name,MAXIMUM "GPRINT:max$name:Max $opts(-format)"
lappend params VDEF:avg$name=g_$name,AVERAGE "GPRINT:avg$name:Avg $opts(-format) $opts(-units)\\n"
}
return $params
}
# Optional arguments are:
# -col graph colour, otherwise uses a default
# -label label for the graph, otherwise none
proc rrdgraph.area {params info name var args} {
set opts [dict merge {-col #66ee66 -label ""} $args]
set opts(-label) [rrdgraph._escape $opts(-label)]
lappend params DEF:$name=$info(rrd):$var:$info(type)
lappend params AREA:$name$opts(-col):$opts(-label)
}
# Optional arguments are:
# -col graph colour, otherwise uses a default
# -value height of the line, otherwise 1
# -width width of the line, otherwise 2
# -label label for the graph, otherwise none
proc rrdgraph.bool {params info name var args} {
set opts [dict merge {-col #888888 -label "" -value 1 -width 2} $args]
set opts(-label) [rrdgraph._escape $opts(-label)]
lappend params DEF:$name=$info(rrd):$var:$info(type)
lappend params CDEF:g_$name=$name,$opts(-value),*
lappend params LINE$opts(-width):g_$name$opts(-col):$opts(-label)
}
proc rrdgraph.output {params info} {
# If it was created less than 'step' seconds ago, don't recreate
set now [clock seconds]
if {![file exists $info(png)] || [file mtime $info(png)] < $now - $info(step)} {
# Note we use locking here to avoid trying to create multiple graphs at once
exec setlock [env HOST ""]/var/run/rrdgraph.lock rrdtool graph $info(png) {*}$params
}
cgi nodisplay
cgi http header Content-Type image/png
cgi http header Content-Length [file size $info(png)]
cgi http response 200
set f [open $info(png)]
$f copyto stdout
$f close
}
proc rrdgraph.debug {params info} {
puts [list rrdtool graph $info(png) {*}$params]
}
# vim: se ts=4:
|