1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package it.jnrpe.plugin;
17
18 import it.jnrpe.ICommandLine;
19 import it.jnrpe.Status;
20 import it.jnrpe.plugins.Metric;
21 import it.jnrpe.plugins.MetricGatheringException;
22 import it.jnrpe.plugins.PluginBase;
23 import it.jnrpe.plugins.annotations.Option;
24 import it.jnrpe.plugins.annotations.Plugin;
25 import it.jnrpe.plugins.annotations.PluginOptions;
26 import it.jnrpe.utils.BadThresholdException;
27 import it.jnrpe.utils.thresholds.ThresholdsEvaluatorBuilder;
28
29 import java.io.IOException;
30 import java.math.BigDecimal;
31 import java.net.Inet4Address;
32 import java.net.Inet6Address;
33 import java.net.InetAddress;
34 import java.net.UnknownHostException;
35 import java.util.ArrayList;
36 import java.util.Collection;
37 import java.util.List;
38
39
40
41
42
43
44
45
46
47 @Plugin(name = "CHECK_PING",
48
49 description =
50 "Checks connection statistics for a remote host.\n\n"
51 + "Usage:\n\n"
52 + "The example will be based upon the following command definition (ini file)\n\n"
53 + "check_ssh : CHECK_PING --hostname $ARG1$ --critical $ARG2$ \n"
54 + "check_nrpe -H myjnrpeserver -c check_ping -a myhostname 3000,50%:\n\n"
55 + "THRESHOLD is <rta>,<pl>% where <rta> is the round trip average travel time (ms) which triggers a WARNING or CRITICAL state, and <pl> is the \n"
56 + "percentage of packet loss to trigger an alarm state.\n"
57 + "Note: a root privilege is required"
58
59 )
60 @PluginOptions({
61 @Option(shortName = "H", longName = "hostname", description = "Hostname or ip address to ping", required = true, hasArgs = true, argName = "hostname", optionalArgs = false, option = "hostname"),
62 @Option(shortName = "p", longName = "packets", description = "number of ICMP ECHO packets to send (Default: 5)", required = false, hasArgs = true, argName = "packets", optionalArgs = false, option = "packets"),
63 @Option(shortName = "4", longName = "use-ipv4", description = "Use IPv4.", required = false, hasArgs = false, argName = "use-ipv4", optionalArgs = false, option = "use-ipv4"),
64 @Option(shortName = "6", longName = "use-ipv6", description = "Use IPv6.", required = false, hasArgs = false, argName = "use-ipv6", optionalArgs = false, option = "use-ipv6"),
65 @Option(shortName = "c", longName = "critical", description = "critical threshold pair", required = false, hasArgs = true, argName = "critical", optionalArgs = false, option = "critical"),
66 @Option(shortName = "w", longName = "warning", description = "warning threshold pair", required = false, hasArgs = true, argName = "warning", optionalArgs = false, option = "warning"),
67 @Option(shortName = "t", longName = "timeout", description = "Seconds before connection times out (default: 10)", required = false, hasArgs = true, argName = "timeout", optionalArgs = false, option = "timeout") })
68 public class CheckPing extends PluginBase {
69
70
71
72
73
74 private static final int DEFAULT_TIMEOUT = 10;
75
76
77
78
79 private static final int DEFAULT_PACKETS = 5;
80
81
82 private static final String RTA = "round trip average";
83
84 private static final String PACKET_LOSS = "packet loss";
85
86 @Override
87 protected String getPluginName() {
88 return "CheckPing";
89 }
90
91
92 public final void configureThresholdEvaluatorBuilder(
93 final ThresholdsEvaluatorBuilder thrb, final ICommandLine cl)
94 throws BadThresholdException {
95 String critical = cl.getOptionValue("critical");
96 String warning = cl.getOptionValue("warning");
97
98 String rtaCritical = getValue(0, critical);
99 String rtaWarning = getValue(0, warning);
100 String plCritical = getValue(1, critical);
101 String plWarning = getValue(1, warning);
102
103 if (rtaCritical != null || rtaWarning != null){
104 thrb.withLegacyThreshold(RTA, null, rtaWarning, rtaCritical);
105 }
106
107 if (plCritical != null || plWarning != null){
108 thrb.withLegacyThreshold(PACKET_LOSS, null, plWarning, plCritical);
109 }
110
111 }
112
113 private String getValue(int index, String str){
114 if (str == null){
115 return null;
116 }
117 String arr[] = str.split(",");
118 if (arr.length >= index){
119 if (arr[index].equals("")){
120 return null;
121 }
122 String val = arr[index].trim().replace("%", "");
123 if (val.indexOf(":") < 0){
124 val = val + ":";
125 }
126 return val;
127 }
128 return null;
129 }
130
131 public Collection<Metric> gatherMetrics(ICommandLine cl) throws MetricGatheringException {
132 List<Metric> metrics = new ArrayList<Metric>();
133
134 String hostname = cl.getOptionValue("hostname");
135 int timeout = DEFAULT_TIMEOUT;
136 if (cl.getOptionValue("timeout") != null) {
137 timeout = Integer.parseInt(cl.getOptionValue("timeout"));
138 }
139 int packets = DEFAULT_PACKETS;
140 if (cl.getOptionValue("packets") != null) {
141 packets = Integer.parseInt(cl.getOptionValue("packets"));
142 }
143
144 double roundTripAvg = 0;
145 int packetLossPerc = 0;
146 long time = 0;
147 long packetLoss = 0;
148 for (int pings = 0; pings < packets; pings++){
149 try {
150 InetAddress inet = null;
151 if (cl.hasOption("ipv6")){
152 inet = Inet6Address.getByName(hostname);
153 }else if (cl.hasOption("ipv4")){
154 inet = Inet4Address.getByName(hostname);
155 }else{
156 inet = InetAddress.getByName(hostname);
157 }
158 boolean reachable = false;
159 long then = System.currentTimeMillis();
160 reachable = inet.isReachable(timeout * 1000);
161 time += (System.currentTimeMillis() - then);
162 if (!reachable){
163 packetLoss++;
164 }
165 } catch (UnknownHostException e) {
166 throw new MetricGatheringException(e.getMessage(), Status.CRITICAL, e);
167 } catch(IOException e){
168 throw new MetricGatheringException(e.getMessage(), Status.CRITICAL, e);
169 }
170 }
171
172 roundTripAvg = (double)time / packets;
173 packetLossPerc = (int) (packetLoss/packets) * 100;
174
175 metrics.add(new Metric(RTA, "", new BigDecimal(roundTripAvg), null, null));
176 metrics.add(new Metric(PACKET_LOSS, "", new BigDecimal(packetLossPerc), null, null));
177
178 return metrics;
179 }
180
181 }