2 ###############################################################################
4 # collecty - A system statistics collection daemon for IPFire #
5 # Copyright (C) 2012 IPFire development team #
7 # This program is free software: you can redistribute it and/or modify #
8 # it under the terms of the GNU General Public License as published by #
9 # the Free Software Foundation, either version 3 of the License, or #
10 # (at your option) any later version. #
12 # This program is distributed in the hope that it will be useful, #
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15 # GNU General Public License for more details. #
17 # You should have received a copy of the GNU General Public License #
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
20 ###############################################################################
27 from ..colours
import *
28 from ..constants
import *
31 class GraphTemplateInterfaceBase(base
.GraphTemplate
):
34 return self
.object.interface
37 class GraphTemplateInterfaceBits(GraphTemplateInterfaceBase
):
38 name
= "interface-bits"
44 "COMMENT:%s" % EMPTY_LABEL
,
45 "COMMENT:%s" % (COLUMN
% _("Current")),
46 "COMMENT:%s" % (COLUMN
% _("Average")),
47 "COMMENT:%s" % (COLUMN
% _("Minimum")),
48 "COMMENT:%s\\j" % (COLUMN
% _("Maximum")),
50 # Convert everything into bits.
51 "CDEF:bits_rx=bytes_rx,8,*",
52 "CDEF:bits_tx=bytes_tx,8,*",
55 "VDEF:bits_rx_95p=bits_rx,95,PERCENT",
56 "VDEF:bits_tx_95p=bits_tx,95,PERCENT",
58 # Draw the received area.
59 "AREA:bits_rx%s:%s" % (
60 transparency(COLOUR_RX
, AREA_OPACITY
),
61 LABEL
% _("Received"),
63 "GPRINT:bits_rx_cur:%s" % BPS
,
64 "GPRINT:bits_rx_avg:%s" % BPS
,
65 "GPRINT:bits_rx_min:%s" % BPS
,
66 "GPRINT:bits_rx_max:%s\\j" % BPS
,
68 # Draw the transmitted area.
69 "AREA:bits_tx%s:%-15s" % (
70 transparency(COLOUR_TX
, AREA_OPACITY
),
71 LABEL
% _("Transmitted"),
73 "GPRINT:bits_tx_cur:%s" % BPS
,
74 "GPRINT:bits_tx_avg:%s" % BPS
,
75 "GPRINT:bits_tx_min:%s" % BPS
,
76 "GPRINT:bits_tx_max:%s\\j" % BPS
,
79 "LINE1:bits_rx%s" % COLOUR_RX
,
80 "LINE1:bits_tx%s" % COLOUR_TX
,
85 "COMMENT:%s" % _("95th Percentile"),
86 "LINE:bits_rx_95p%s:%s:dashes" % (COLOUR_RX
, LABEL
% _("Received")),
87 "GPRINT:bits_rx_95p:%s\\r" % BPS
,
88 "LINE:bits_tx_95p%s:%s:dashes" % (COLOUR_TX
, LABEL
% _("Transmitted")),
89 "GPRINT:bits_tx_95p:%s\\r" % BPS
,
93 def graph_title(self
):
94 return _("Bandwidth Usage on %s") % self
.interface
97 def graph_vertical_label(self
):
101 class GraphTemplateInterfacePackets(GraphTemplateInterfaceBase
):
102 name
= "interface-packets"
108 "COMMENT:%s" % EMPTY_LABEL
,
109 "COMMENT:%s" % (COLUMN
% _("Current")),
110 "COMMENT:%s" % (COLUMN
% _("Average")),
111 "COMMENT:%s" % (COLUMN
% _("Minimum")),
112 "COMMENT:%s\\j" % (COLUMN
% _("Maximum")),
114 # Draw the received area.
115 "AREA:packets_rx%s:%s" % (
116 transparency(COLOUR_RX
, AREA_OPACITY
),
117 LABEL
% _("Received"),
119 "GPRINT:packets_rx_cur:%s" % PPS
,
120 "GPRINT:packets_rx_avg:%s" % PPS
,
121 "GPRINT:packets_rx_min:%s" % PPS
,
122 "GPRINT:packets_rx_max:%s\\j" % PPS
,
124 # Draw the transmitted area.
125 "AREA:packets_tx%s:%s" % (
126 transparency(COLOUR_TX
, AREA_OPACITY
),
127 LABEL
% _("Transmitted"),
129 "GPRINT:packets_tx_cur:%s" % PPS
,
130 "GPRINT:packets_tx_avg:%s" % PPS
,
131 "GPRINT:packets_tx_min:%s" % PPS
,
132 "GPRINT:packets_tx_max:%s\\j" % PPS
,
134 # Draw outlines of the areas on top.
135 "LINE1:packets_rx%s" % COLOUR_RX
,
136 "LINE1:packets_tx%s" % COLOUR_TX
,
140 def graph_title(self
):
141 return _("Transferred Packets on %s") % self
.interface
144 def graph_vertical_label(self
):
145 return _("Packets/s")
148 class GraphTemplateInterfaceErrors(GraphTemplateInterfaceBase
):
149 name
= "interface-errors"
155 "COMMENT:%s" % EMPTY_LABEL
,
156 "COMMENT:%s" % (COLUMN
% _("Current")),
157 "COMMENT:%s" % (COLUMN
% _("Average")),
158 "COMMENT:%s" % (COLUMN
% _("Minimum")),
159 "COMMENT:%s\\j" % (COLUMN
% _("Maximum")),
161 # Invert the transmitted packets to create upside down graph.
162 "CDEF:errors_tx_inv=errors_tx,-1,*",
163 "CDEF:dropped_tx_inv=dropped_tx,-1,*",
165 # Draw the receive errors.
166 "AREA:errors_rx%s:%-15s" % (
167 transparency(COLOUR_RX
, AREA_OPACITY
),
168 LABEL
% _("Receive Errors"),
170 "GPRINT:errors_rx_cur:%s" % PPS
,
171 "GPRINT:errors_rx_avg:%s" % PPS
,
172 "GPRINT:errors_rx_min:%s" % PPS
,
173 "GPRINT:errors_rx_max:%s\\j" % PPS
,
174 "LINE1:errors_rx%s" % COLOUR_RX
,
176 # Draw the transmit errors.
177 "AREA:errors_tx_inv%s:%-15s" % (
178 transparency(COLOUR_TX
, AREA_OPACITY
),
179 LABEL
% _("Transmit Errors"),
181 "GPRINT:errors_tx_cur:%s" % PPS
,
182 "GPRINT:errors_tx_avg:%s" % PPS
,
183 "GPRINT:errors_tx_min:%s" % PPS
,
184 "GPRINT:errors_tx_max:%s\\j" % PPS
,
185 "LINE1:errors_tx_inv%s" % COLOUR_TX
,
187 # Draw the receive drops.
188 "LINE2:dropped_rx%s:%-15s" % (
189 transparency(AMBER
, AREA_OPACITY
),
190 LABEL
% _("Receive Drops"),
192 "GPRINT:dropped_rx_cur:%s" % PPS
,
193 "GPRINT:dropped_rx_avg:%s" % PPS
,
194 "GPRINT:dropped_rx_min:%s" % PPS
,
195 "GPRINT:dropped_rx_max:%s\\j" % PPS
,
196 "LINE1:dropped_rx#228B22",
198 # Draw the transmit drops.
199 "LINE2:dropped_tx%s:%-15s" % (
200 transparency(TEAL
, AREA_OPACITY
),
201 LABEL
% _("Transmit Drops"),
203 "GPRINT:dropped_tx_cur:%s" % PPS
,
204 "GPRINT:dropped_tx_avg:%s" % PPS
,
205 "GPRINT:dropped_tx_min:%s" % PPS
,
206 "GPRINT:dropped_tx_max:%s\\j" % PPS
,
207 "LINE1:dropped_tx%s" % TEAL
,
211 # Draw the collisions as a line.
212 "LINE2:collisions%s:%s" % (
214 LABEL
% _("Collisions"),
216 "GPRINT:collisions_cur:%s" % PPS
,
217 "GPRINT:collisions_avg:%s" % PPS
,
218 "GPRINT:collisions_min:%s" % PPS
,
219 "GPRINT:collisions_max:%s\\j" % PPS
,
223 def graph_title(self
):
224 return _("Errors/Dropped Packets on %s") % self
.interface
227 def graph_vertical_label(self
):
228 return _("Packets/s")
231 class InterfaceObject(base
.Object
):
233 "DS:bytes_rx:DERIVE:0:U",
234 "DS:bytes_tx:DERIVE:0:U",
235 "DS:collisions:DERIVE:0:U",
236 "DS:dropped_rx:DERIVE:0:U",
237 "DS:dropped_tx:DERIVE:0:U",
238 "DS:errors_rx:DERIVE:0:U",
239 "DS:errors_tx:DERIVE:0:U",
240 "DS:multicast:DERIVE:0:U",
241 "DS:packets_rx:DERIVE:0:U",
242 "DS:packets_tx:DERIVE:0:U",
246 return "<%s %s>" % (self
.__class
__.__name
__, self
.interface
)
248 def init(self
, interface
):
249 self
.interface
= interface
253 return self
.interface
256 interface_path
= os
.path
.join("/sys/class/net", self
.interface
)
258 # Check if the interface exists.
259 if not os
.path
.exists(interface_path
):
260 self
.log
.debug(_("Interface %s does not exists. Cannot collect.") \
265 "rx_bytes", "tx_bytes",
267 "rx_dropped", "tx_dropped",
268 "rx_errors", "tx_errors",
270 "rx_packets", "tx_packets",
275 path
= os
.path
.join(interface_path
, "statistics", file)
278 self
.read_file_integer(path
),
284 class InterfacePlugin(base
.Plugin
):
286 description
= "Interface Statistics Plugin"
289 GraphTemplateInterfaceBits
,
290 GraphTemplateInterfacePackets
,
291 GraphTemplateInterfaceErrors
,
298 for interface
in util
.get_network_interfaces():
299 yield InterfaceObject(self
, interface
=interface
)