]> git.ipfire.org Git - collecty.git/blame - src/collecty/plugins/latency.py
Add df plugin
[collecty.git] / src / collecty / plugins / latency.py
CommitLineData
f37913e8 1#!/usr/bin/python3
bae5c928
MT
2###############################################################################
3# #
4# collecty - A system statistics collection daemon for IPFire #
5# Copyright (C) 2012 IPFire development team #
6# #
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. #
11# #
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. #
16# #
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/>. #
19# #
20###############################################################################
21
63f9f8be 22import socket
bae5c928 23
63f9f8be 24import collecty._collecty
f37913e8 25from . import base
bae5c928
MT
26
27from ..i18n import _
28
29PING_HOSTS = [
30 "ping.ipfire.org",
31]
32
33class GraphTemplateLatency(base.GraphTemplate):
34 name = "latency"
35
f181246a
MT
36 lower_limit = 0
37
bae5c928
MT
38 @property
39 def rrd_graph(self):
c92c02ea
MT
40 _ = self.locale.translate
41
bae5c928 42 return [
63f9f8be
MT
43 "DEF:latency6=%(file)s:latency6:AVERAGE",
44 "DEF:loss6=%(file)s:loss6:AVERAGE",
45 "DEF:stddev6=%(file)s:stddev6:AVERAGE",
46
47 "DEF:latency4=%(file)s:latency4:AVERAGE",
48 "DEF:loss4=%(file)s:loss4:AVERAGE",
49 "DEF:stddev4=%(file)s:stddev4:AVERAGE",
50
51 # Compute the biggest loss and convert into percentage
52 "CDEF:ploss=loss6,loss4,MAX,100,*",
53
54 # Compute standard deviation
55 "CDEF:stddevarea6=stddev6,2,*",
56 "CDEF:spacer6=latency6,stddev6,-",
57 "CDEF:stddevarea4=stddev4,2,*",
58 "CDEF:spacer4=latency4,stddev4,-",
59
60 "CDEF:l005=ploss,0,5,LIMIT,UN,UNKN,INF,IF",
61 "CDEF:l010=ploss,5,10,LIMIT,UN,UNKN,INF,IF",
62 "CDEF:l025=ploss,10,25,LIMIT,UN,UNKN,INF,IF",
63 "CDEF:l050=ploss,25,50,LIMIT,UN,UNKN,INF,IF",
baa4852a 64 "CDEF:l099=ploss,50,99,LIMIT,UN,UNKN,INF,IF",
63f9f8be
MT
65
66 "VDEF:latency6min=latency6,MINIMUM",
67 "VDEF:latency6max=latency6,MAXIMUM",
68 "VDEF:latency6avg=latency6,AVERAGE",
69 "VDEF:latency4min=latency4,MINIMUM",
70 "VDEF:latency4max=latency4,MAXIMUM",
71 "VDEF:latency4avg=latency4,AVERAGE",
72
73 "LINE1:latency6avg#00ff0066:%s" % _("Average latency (IPv6)"),
74 "LINE1:latency4avg#ff000066:%s\\r" % _("Average latency (IPv4)"),
75
76 "COMMENT:%s" % _("Packet Loss"),
bae5c928 77 "AREA:l005#ffffff:%s" % _("0-5%%"),
63f9f8be
MT
78 "AREA:l010#cccccc:%s" % _("5-10%%"),
79 "AREA:l025#999999:%s" % _("10-25%%"),
80 "AREA:l050#666666:%s" % _("25-50%%"),
baa4852a 81 "AREA:l099#333333:%s" % _("50-99%%") + "\\r",
63f9f8be
MT
82
83 "COMMENT: \\n", # empty line
84
85 "AREA:spacer4",
86 "AREA:stddevarea4#ff000033:STACK",
87 "LINE2:latency4#ff0000:%s" % _("Latency (IPv4)"),
88 "GPRINT:latency4max:%12s\:" % _("Maximum") + " %6.2lf",
89 "GPRINT:latency4min:%12s\:" % _("Minimum") + " %6.2lf",
90 "GPRINT:latency4avg:%12s\:" % _("Average") + " %6.2lf\\n",
91
92 "AREA:spacer6",
93 "AREA:stddevarea6#00ff0033:STACK",
94 "LINE2:latency6#00ff00:%s" % _("Latency (IPv6)"),
95 "GPRINT:latency6max:%12s\:" % _("Maximum") + " %6.2lf",
96 "GPRINT:latency6min:%12s\:" % _("Minimum") + " %6.2lf",
97 "GPRINT:latency6avg:%12s\:" % _("Average") + " %6.2lf\\n",
bae5c928
MT
98 ]
99
100 @property
f181246a 101 def graph_title(self):
c92c02ea 102 _ = self.locale.translate
63f9f8be 103 return _("Latency to %s") % self.object.hostname
bae5c928 104
f181246a
MT
105 @property
106 def graph_vertical_label(self):
c92c02ea 107 _ = self.locale.translate
f181246a 108 return _("Milliseconds")
bae5c928 109
63f9f8be
MT
110 @property
111 def rrd_graph_args(self):
112 return [
113 "--legend-direction=bottomup",
114 ]
115
bae5c928 116
72364063 117class LatencyObject(base.Object):
bae5c928 118 rrd_schema = [
63f9f8be
MT
119 "DS:latency6:GAUGE:0:U",
120 "DS:stddev6:GAUGE:0:U",
121 "DS:loss6:GAUGE:0:100",
122 "DS:latency4:GAUGE:0:U",
123 "DS:stddev4:GAUGE:0:U",
124 "DS:loss4:GAUGE:0:100",
bae5c928
MT
125 ]
126
72364063
MT
127 def __repr__(self):
128 return "<%s %s>" % (self.__class__.__name__, self.hostname)
bae5c928 129
63f9f8be 130 def init(self, hostname):
72364063 131 self.hostname = hostname
bae5c928
MT
132
133 @property
72364063
MT
134 def id(self):
135 return self.hostname
bae5c928 136
72364063 137 def collect(self):
63f9f8be
MT
138 result = []
139
140 for family in (socket.AF_INET6, socket.AF_INET):
141 try:
142 p = collecty._collecty.Ping(self.hostname, family=family)
143 p.ping(count=5, deadline=10)
144
145 result += (p.average, p.stddev, p.loss)
146
147 except collecty._collecty.PingAddHostError as e:
148 self.log.debug(_("Could not add host %(host)s for family %(family)s") \
149 % { "host" : self.hostname, "family" : family })
c968f6d9 150
63f9f8be
MT
151 # No data available
152 result += (None, None, None)
153 continue
bae5c928 154
63f9f8be
MT
155 except collecty._collecty.PingError as e:
156 self.log.warning(_("Could not run latency check for %(host)s: %(msg)s") \
157 % { "host" : self.hostname, "msg" : e })
158
159 # A hundred percent loss
160 result += (None, None, 1)
161
162 return result
72364063
MT
163
164
165class LatencyPlugin(base.Plugin):
166 name = "latency"
167 description = "Latency (ICMP ping) Plugin"
168
c968f6d9 169 templates = [GraphTemplateLatency]
72364063 170
72364063
MT
171 @property
172 def objects(self):
72364063 173 for hostname in PING_HOSTS:
63f9f8be 174 yield LatencyObject(self, hostname)