]> git.ipfire.org Git - collecty.git/blame - src/collecty/plugins/latency.py
psi: Add graph template
[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
a031204a 24from .. import _collecty
f37913e8 25from . import base
bae5c928 26
03ba5630 27from ..colours import *
eb06d20a 28from ..constants import *
72fc5ca5 29from ..i18n import _
bae5c928
MT
30
31PING_HOSTS = [
ad4ac1f8
MT
32 # gateway is a special name that is automatically
33 # resolved by myhostname to the default gateway.
34 "gateway",
35
36 # The IPFire main server
bae5c928
MT
37 "ping.ipfire.org",
38]
39
40class GraphTemplateLatency(base.GraphTemplate):
41 name = "latency"
42
f181246a
MT
43 lower_limit = 0
44
bae5c928
MT
45 @property
46 def rrd_graph(self):
47 return [
63f9f8be
MT
48 # Compute the biggest loss and convert into percentage
49 "CDEF:ploss=loss6,loss4,MAX,100,*",
50
51 # Compute standard deviation
52 "CDEF:stddevarea6=stddev6,2,*",
53 "CDEF:spacer6=latency6,stddev6,-",
54 "CDEF:stddevarea4=stddev4,2,*",
55 "CDEF:spacer4=latency4,stddev4,-",
56
57 "CDEF:l005=ploss,0,5,LIMIT,UN,UNKN,INF,IF",
58 "CDEF:l010=ploss,5,10,LIMIT,UN,UNKN,INF,IF",
59 "CDEF:l025=ploss,10,25,LIMIT,UN,UNKN,INF,IF",
60 "CDEF:l050=ploss,25,50,LIMIT,UN,UNKN,INF,IF",
baa4852a 61 "CDEF:l099=ploss,50,99,LIMIT,UN,UNKN,INF,IF",
63f9f8be 62
eb06d20a
MT
63 # Draw average lines
64 "LINE:latency6_avg%s::dashes" % (
65 lighten(COLOUR_IPV6),
03ba5630 66 ),
eb06d20a
MT
67 "LINE:latency4_avg%s::dashes" % (
68 lighten(COLOUR_IPV4),
03ba5630 69 ),
63f9f8be 70
eb06d20a 71 # Colour background on packet loss
63f9f8be 72 "COMMENT:%s" % _("Packet Loss"),
03ba5630 73 "AREA:l005%s:%s" % (
eb06d20a 74 transparency(BLACK, .2), _("0-5%"),
03ba5630
MT
75 ),
76 "AREA:l010%s:%s" % (
eb06d20a 77 transparency(BLACK, .4), _("5-10%"),
03ba5630
MT
78 ),
79 "AREA:l025%s:%s" % (
eb06d20a 80 transparency(BLACK, .6), _("10-25%"),
03ba5630
MT
81 ),
82 "AREA:l050%s:%s" % (
eb06d20a 83 transparency(BLACK, .8), _("25-50%"),
03ba5630 84 ),
eb06d20a 85 "AREA:l099%s:%s\\r" % (BLACK, _("50-99%")),
63f9f8be 86
eb06d20a 87 EMPTY_LINE,
63f9f8be 88
eb06d20a 89 # Plot standard deviation
63f9f8be 90 "AREA:spacer4",
eb06d20a
MT
91 "AREA:stddevarea4%s:STACK" % transparency(COLOUR_IPV4, STDDEV_OPACITY),
92 "LINE2:latency4%s:%s" % (
93 COLOUR_IPV4,
94 LABEL % _("Latency (IPv4)"),
95 ),
96 "GPRINT:latency4_cur:%s" % MS,
97 "GPRINT:latency4_avg:%s" % MS,
98 "GPRINT:latency4_min:%s" % MS,
99 "GPRINT:latency4_max:%s\\j" % MS,
63f9f8be
MT
100
101 "AREA:spacer6",
eb06d20a
MT
102 "AREA:stddevarea6%s:STACK" % transparency(COLOUR_IPV6, STDDEV_OPACITY),
103 "LINE2:latency6%s:%s" % (
104 COLOUR_IPV6,
105 LABEL % _("Latency (IPv6)"),
106 ),
107 "GPRINT:latency6_cur:%s" % MS,
108 "GPRINT:latency6_avg:%s" % MS,
109 "GPRINT:latency6_min:%s" % MS,
110 "GPRINT:latency6_max:%s\\j" % MS,
111
112 # Headline
113 "COMMENT:%s" % EMPTY_LABEL,
114 "COMMENT:%s" % (COLUMN % _("Current")),
115 "COMMENT:%s" % (COLUMN % _("Average")),
116 "COMMENT:%s" % (COLUMN % _("Minimum")),
117 "COMMENT:%s\\j" % (COLUMN % _("Maximum")),
bae5c928
MT
118 ]
119
120 @property
f181246a 121 def graph_title(self):
69eeb1a3
MT
122 if self.object.hostname == "gateway":
123 hostname = _("Default Gateway")
124 else:
125 hostname = self.object.hostname
126
127 return _("Latency to %s") % hostname
bae5c928 128
f181246a
MT
129 @property
130 def graph_vertical_label(self):
131 return _("Milliseconds")
bae5c928 132
63f9f8be
MT
133 @property
134 def rrd_graph_args(self):
135 return [
136 "--legend-direction=bottomup",
137 ]
138
bae5c928 139
72364063 140class LatencyObject(base.Object):
bae5c928 141 rrd_schema = [
63f9f8be
MT
142 "DS:latency6:GAUGE:0:U",
143 "DS:stddev6:GAUGE:0:U",
144 "DS:loss6:GAUGE:0:100",
145 "DS:latency4:GAUGE:0:U",
146 "DS:stddev4:GAUGE:0:U",
147 "DS:loss4:GAUGE:0:100",
bae5c928
MT
148 ]
149
63f9f8be 150 def init(self, hostname):
72364063 151 self.hostname = hostname
bae5c928
MT
152
153 @property
72364063
MT
154 def id(self):
155 return self.hostname
bae5c928 156
72364063 157 def collect(self):
63f9f8be
MT
158 result = []
159
160 for family in (socket.AF_INET6, socket.AF_INET):
161 try:
eb1ebd3d 162 p = _collecty.Ping(self.hostname, family=family)
48903f3b 163 p.ping(count=10, deadline=10)
63f9f8be
MT
164
165 result += (p.average, p.stddev, p.loss)
166
eb1ebd3d 167 except _collecty.PingAddHostError as e:
63f9f8be
MT
168 self.log.debug(_("Could not add host %(host)s for family %(family)s") \
169 % { "host" : self.hostname, "family" : family })
c968f6d9 170
63f9f8be
MT
171 # No data available
172 result += (None, None, None)
173 continue
bae5c928 174
eb1ebd3d 175 except _collecty.PingNoReplyError:
c9991a7a
MT
176 # Unknown but 100% loss
177 result += (None, None, 1)
178 continue
179
eb1ebd3d 180 except _collecty.PingError as e:
63f9f8be
MT
181 self.log.warning(_("Could not run latency check for %(host)s: %(msg)s") \
182 % { "host" : self.hostname, "msg" : e })
183
184 # A hundred percent loss
185 result += (None, None, 1)
186
187 return result
72364063
MT
188
189
190class LatencyPlugin(base.Plugin):
191 name = "latency"
192 description = "Latency (ICMP ping) Plugin"
193
c968f6d9 194 templates = [GraphTemplateLatency]
72364063 195
d38a7885
MT
196 # Because this plugin has the potential to block, we give it a slightly lower priority
197 priority = 10
198
72364063
MT
199 @property
200 def objects(self):
72364063 201 for hostname in PING_HOSTS:
63f9f8be 202 yield LatencyObject(self, hostname)