View Javadoc

1   /*******************************************************************************
2    * Copyright (c) 2007, 2014 Massimiliano Ziccardi
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *******************************************************************************/
16  package it.jnrpe.plugin;
17  
18  import it.jnrpe.ICommandLine;
19  import it.jnrpe.Status;
20  import it.jnrpe.plugin.utils.Utils;
21  import it.jnrpe.plugins.Metric;
22  import it.jnrpe.plugins.MetricGatheringException;
23  import it.jnrpe.plugins.PluginBase;
24  import it.jnrpe.plugins.annotations.Option;
25  import it.jnrpe.plugins.annotations.Plugin;
26  import it.jnrpe.plugins.annotations.PluginOptions;
27  import it.jnrpe.utils.BadThresholdException;
28  import it.jnrpe.utils.thresholds.ThresholdsEvaluatorBuilder;
29  
30  import java.io.IOException;
31  import java.math.BigDecimal;
32  import java.net.InetAddress;
33  import java.util.ArrayList;
34  import java.util.Collection;
35  import java.util.Date;
36  import java.util.List;
37  
38  import org.apache.commons.net.time.TimeTCPClient;
39  import org.apache.commons.net.time.TimeUDPClient;
40  
41  /**
42   * Checks the time on a specified host
43   * 
44   * @author Frederico Campos
45   * 
46   */
47  
48  @Plugin(name = "CHECK_TIME",
49  description = "Checks time on a specified host." )
50  @PluginOptions({
51      @Option(shortName = "H", longName = "hostname", description = "Host name or IP Address", required = true, hasArgs = true, argName = "hostname", optionalArgs = false, option = "hostname"),
52  
53      @Option(shortName = "p", longName = "port", description = "Port number (default is 37)", required = false, hasArgs = true, argName = "port", optionalArgs = false, option = "port"),
54  
55      @Option(shortName = "u", longName = "udp", description = "Use udp instead of tcp to connect.", required = false, hasArgs = false, argName = "udp", optionalArgs = false, option = "udp"),
56  
57      @Option(shortName = "c", longName = "critical-variance", description = "Time difference (sec.) necessary to result in a critical status", required = false, hasArgs = true, argName = "critical-variance", optionalArgs = false, option = "critical-variance"),
58  
59      @Option(shortName = "w", longName = "warning-variance", description = "Time difference (sec.) necessary to result in a warning status", required = false, hasArgs = true, argName = "warning", optionalArgs = false, option = "warning"),
60  
61      @Option(shortName = "C", longName = "critical-connect", description = "Return critical if elapsed time exceeds value. Default off", required = false, hasArgs = true, argName = "critical", optionalArgs = false, option = "critical"),
62  
63      @Option(shortName = "W", longName = "warning-connect", description = "Return warning if elapsed time exceeds value. Default off", required = false, hasArgs = true, argName = "warning", optionalArgs = false, option = "warning"),
64  
65      @Option(shortName = "t", longName = "timeout", description = "Seconds before connection times out (default: 10)", required = false, hasArgs = true, argName = "timeout", optionalArgs = false, option = "timeout"), 
66  
67  })
68  
69  public class CheckTime extends PluginBase {
70  
71  
72      private static final int DEFAULT_TIMEOUT = 10;
73  
74      private static final int DEFAULT_PORT = 37;
75  
76      @Override
77      protected String getPluginName() {
78          return "CHECK_TIME";
79      }
80  
81      public final void configureThresholdEvaluatorBuilder(
82              final ThresholdsEvaluatorBuilder thrb, final ICommandLine cl)
83                      throws BadThresholdException {
84          String criticalConnect = cl.getOptionValue("critical-connect");
85          String warningConnect = cl.getOptionValue("warning-connect");
86          thrb.withLegacyThreshold("time", null, warningConnect, criticalConnect);
87  
88          String critical = cl.getOptionValue("critical-variance");
89          String warning = cl.getOptionValue("warning-variance");
90          thrb.withLegacyThreshold("offset", null, warning, critical);
91  
92         
93      }
94  
95      public Collection<Metric> gatherMetrics(ICommandLine cl)
96              throws MetricGatheringException {
97          List<Metric> metrics = new ArrayList<Metric>();
98          String host = cl.getOptionValue("hostname");
99          int timeout = DEFAULT_TIMEOUT;
100         if (cl.getOptionValue("timeout") != null){
101             timeout = Integer.parseInt(cl.getOptionValue("timeout"));    
102         }
103         int port = DEFAULT_PORT;
104         if (cl.getOptionValue("port") != null){
105             port = Integer.parseInt(cl.getOptionValue("port"));
106         }
107         try {
108             Date date = null;
109             long then = System.currentTimeMillis();
110             if (cl.hasOption("udp")){ 
111                 date = getTimeUDP(host, timeout);
112             }else{
113                 date = getTimeTCP(host, timeout, port);
114             }
115             long ellapsed = (System.currentTimeMillis() - then);
116 
117             Date now = new Date();
118             
119             analyze(metrics, ellapsed, now, date);    
120 
121         } catch (IOException e) {
122             throw new MetricGatheringException(e.getMessage(), Status.CRITICAL, e);
123         }
124 
125         return metrics;
126     }
127 
128     private void analyze(List<Metric> metrics, long ellapsed, Date now, Date date){
129         long diff = 0;
130 
131         boolean behind = false;
132         if (now.before(date)){
133             behind = true;
134             diff = date.getTime() - now.getTime();               
135         }else if (now.after(date)){
136             diff = now.getTime() - date.getTime();               
137         }
138 
139         long diffSeconds = diff / 1000 % 60;
140         long diffMinutes = diff / (60 * 1000) % 60;
141         long diffHours = diff / (60 * 60 * 1000) % 24;
142         long diffDays = diff / (24 * 60 * 60 * 1000);
143 
144         long totalDiffSecs = Utils.milliToSec(diff);
145 
146         String msg = getMessage(diffSeconds, diffHours, diffMinutes, diffDays);
147         if (diff > 1000){
148             if (behind){
149                 msg += "behind";
150             }else{
151                 msg += "ahead";
152             }
153         }
154         metrics.add(new Metric("offset", msg, new BigDecimal(totalDiffSecs), null, null));            
155         metrics.add(new Metric("time", "", new BigDecimal(ellapsed/1000), null, null));           
156     }
157 
158     private String getMessage(long diffSeconds, long diffHours, long diffMinutes, long diffDays){
159         String msg = diffSeconds + " seconds ";
160 
161         if (diffMinutes > 0 ) {
162             msg += diffMinutes + " minutes ";
163         }
164         if (diffHours > 0 ) {
165             msg += diffHours + " hours ";
166         }
167         if (diffHours > 0 ) {
168             msg += diffDays + " days ";
169         }
170         return msg + "difference ";
171     }
172 
173     private Date getTimeTCP(String host, int timeout, int port) throws IOException {
174         TimeTCPClient client = new TimeTCPClient();
175         client.setDefaultPort(port);
176         client.setDefaultTimeout(timeout * 1000);
177         client.connect(host);
178         Date date = client.getDate();
179         client.disconnect();
180         return date;
181 
182     }
183 
184     private Date getTimeUDP(String host, int timeout) throws IOException {
185         TimeUDPClient client = new TimeUDPClient();
186         client.setDefaultTimeout(timeout * 1000);
187         client.open();
188         Date date = client.getDate(InetAddress.getByName(host));
189         client.close();
190         return date;
191     }
192 }