|
1 import rrd |
|
2 import time |
|
3 |
|
4 """ |
|
5 RRDTool graph output |
|
6 """ |
|
7 |
|
8 def timestamp () : |
|
9 return time.strftime("%Y/%m/%d %H:%M:%S %Z") |
|
10 |
|
11 def common_opts () : |
|
12 """ |
|
13 Common options for all views |
|
14 """ |
|
15 |
|
16 return dict( |
|
17 # output |
|
18 imgformat = "PNG", |
|
19 # lazy = True, |
|
20 |
|
21 color = [ |
|
22 # disable border |
|
23 # border = 0, |
|
24 "SHADEA#ffffff00", |
|
25 "SHADEB#ffffff00", |
|
26 |
|
27 # keep background transparent |
|
28 "BACK#ffffff00", |
|
29 "SHADEB#ffffff00", |
|
30 ], |
|
31 |
|
32 # labels |
|
33 vertical_label = "bits/s", |
|
34 units = "si", |
|
35 |
|
36 # use logarithmic scaling |
|
37 logarithmic = True, |
|
38 |
|
39 # smooth out lines |
|
40 slope_mode = True, |
|
41 ) |
|
42 |
|
43 def overview_opts () : |
|
44 """ |
|
45 Common options for the overview graph |
|
46 """ |
|
47 |
|
48 return dict( |
|
49 width = 600, |
|
50 height = 50, |
|
51 ), [ |
|
52 "LINE1:in#0000FF:%4s" % "In", |
|
53 "LINE1:out#00CC00:%4s" % "Out", |
|
54 ] |
|
55 |
|
56 def detail_opts () : |
|
57 """ |
|
58 Common options for the detail graph |
|
59 """ |
|
60 |
|
61 return dict( |
|
62 # dimensions |
|
63 width = 600, |
|
64 height = 200, |
|
65 ), [ |
|
66 # values |
|
67 'VDEF:in_max=in,MAXIMUM', |
|
68 'VDEF:in_avg=in,AVERAGE', |
|
69 'VDEF:in_min=in,MINIMUM', |
|
70 'VDEF:out_max=out,MAXIMUM', |
|
71 'VDEF:out_avg=out,AVERAGE', |
|
72 'VDEF:out_min=out,MINIMUM', |
|
73 |
|
74 # legend/graph |
|
75 "COMMENT:%4s" % "", |
|
76 "COMMENT:%11s" % "Maximum", |
|
77 "COMMENT:%11s" % "Average", |
|
78 "COMMENT:%11s\\l" % "Minimum", |
|
79 |
|
80 "LINE1:in#0000FF:%4s" % "In", |
|
81 'GPRINT:in_max:%6.2lf %Sbps', |
|
82 'GPRINT:in_avg:%6.2lf %Sbps', |
|
83 'GPRINT:in_min:%6.2lf %Sbps\\l', |
|
84 |
|
85 "LINE1:out#00CC00:%4s" % "Out", |
|
86 'GPRINT:out_max:%6.2lf %Sbps', |
|
87 'GPRINT:out_avg:%6.2lf %Sbps', |
|
88 'GPRINT:out_min:%6.2lf %Sbps\\l', |
|
89 |
|
90 # mark |
|
91 "COMMENT:Generated %s\\r" % timestamp().replace(':', '\\:'), |
|
92 ] |
|
93 |
|
94 STYLE_DEFS = { |
|
95 'overview': overview_opts, |
|
96 'detail': detail_opts, |
|
97 } |
|
98 |
|
99 def daily_opts (title) : |
|
100 """ |
|
101 Common options for the 'daily' view |
|
102 """ |
|
103 |
|
104 return dict( |
|
105 # labels |
|
106 x_grid = "MINUTE:15:HOUR:1:HOUR:4:0:%H:%M", |
|
107 |
|
108 # general info |
|
109 title = "Daily %s" % (title, ), |
|
110 |
|
111 # interval |
|
112 start = "-24h", |
|
113 ) |
|
114 |
|
115 def weekly_opts (title) : |
|
116 return dict( |
|
117 # labels |
|
118 # x_grid = "MINUTE:15:HOUR:1:HOUR:4:0:%H:%M", |
|
119 |
|
120 # general info |
|
121 title = "Weekly %s" % (title, ), |
|
122 |
|
123 # interval |
|
124 start = "-7d", |
|
125 ) |
|
126 |
|
127 def yearly_opts (title) : |
|
128 return dict( |
|
129 # labels |
|
130 # x_grid = "MINUTE:15:HOUR:1:HOUR:4:0:%H:%M", |
|
131 |
|
132 # general info |
|
133 title = "Yearly %s" % (title, ), |
|
134 |
|
135 # interval |
|
136 start = "-1y", |
|
137 ) |
|
138 |
|
139 |
|
140 INTERVAL_DEFS = { |
|
141 'daily': daily_opts, |
|
142 'weekly': weekly_opts, |
|
143 'yearly': yearly_opts, |
|
144 } |
|
145 |
|
146 def mrtg_data (rrd_path) : |
|
147 """ |
|
148 Data sources for network in/out from an MRTG rrd |
|
149 """ |
|
150 |
|
151 return [ |
|
152 # data sources, bytes/s |
|
153 r'DEF:in0=%s:ds0:AVERAGE' % rrd_path, |
|
154 r'DEF:out0=%s:ds1:AVERAGE' % rrd_path, |
|
155 |
|
156 # data, bits/s |
|
157 'CDEF:in=in0,8,*', |
|
158 'CDEF:out=out0,8,*', |
|
159 |
|
160 ] |
|
161 |
|
162 def mrtg (style, interval, title, rrd_path, out_path) : |
|
163 style_opts, style_vars = STYLE_DEFS[style]() |
|
164 interval_opts = INTERVAL_DEFS[interval](title) |
|
165 |
|
166 opts = rrd.merge_opts(common_opts(), style_opts, interval_opts) |
|
167 data = mrtg_data(rrd_path) + style_vars |
|
168 |
|
169 return rrd.graph(out_path, *data, **opts) |
|
170 |