use of org.opennms.core.utils.TimeoutTracker in project opennms by OpenNMS.
the class TcpMonitor method poll.
/**
* {@inheritDoc}
*
* Poll the specified address for service availability.
*
* During the poll an attempt is made to connect on the specified port. If
* the connection request is successful, the banner line generated by the
* interface is parsed and if the banner text indicates that we are talking
* to Provided that the interface's response is valid we set the service
* status to SERVICE_AVAILABLE and return.
*/
@Override
public PollStatus poll(MonitoredService svc, Map<String, Object> parameters) {
//
// Process parameters
//
//
// Get interface address from NetworkInterface
//
TimeoutTracker tracker = new TimeoutTracker(parameters, DEFAULT_RETRY, DEFAULT_TIMEOUT);
// Port
//
int port = ParameterMap.getKeyedInteger(parameters, PARAMETER_PORT, DEFAULT_PORT);
if (port == DEFAULT_PORT) {
throw new RuntimeException("TcpMonitor: required parameter 'port' is not present in supplied properties.");
}
// BannerMatch
//
String strBannerMatch = ParameterMap.getKeyedString(parameters, PARAMETER_BANNER, null);
// Get the address instance.
//
InetAddress ipAddr = svc.getAddress();
final String hostAddress = InetAddressUtils.str(ipAddr);
LOG.debug("poll: address = {}, port = {}, {}", hostAddress, port, tracker);
// Give it a whirl
//
PollStatus serviceStatus = PollStatus.unavailable();
for (tracker.reset(); tracker.shouldRetry() && !serviceStatus.isAvailable(); tracker.nextAttempt()) {
Socket socket = null;
try {
tracker.startAttempt();
socket = new Socket();
socket.connect(new InetSocketAddress(ipAddr, port), tracker.getConnectionTimeout());
socket.setSoTimeout(tracker.getSoTimeout());
LOG.debug("TcpMonitor: connected to host: {} on port: {}", ipAddr, port);
// We're connected, so upgrade status to unresponsive
serviceStatus = PollStatus.unresponsive();
if (strBannerMatch == null || strBannerMatch.length() == 0 || strBannerMatch.equals("*")) {
serviceStatus = PollStatus.available(tracker.elapsedTimeInMillis());
break;
}
BufferedReader rdr = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//
// Tokenize the Banner Line, and check the first
// line for a valid return.
//
String response = rdr.readLine();
double responseTime = tracker.elapsedTimeInMillis();
if (response == null)
continue;
LOG.debug("poll: banner = {}", response);
LOG.debug("poll: responseTime= {}ms", responseTime);
// Could it be a regex?
if (strBannerMatch.charAt(0) == '~') {
if (!response.matches(strBannerMatch.substring(1)))
serviceStatus = PollStatus.unavailable("Banner does not match Regex '" + strBannerMatch + "'");
else
serviceStatus = PollStatus.available(responseTime);
} else {
if (response.indexOf(strBannerMatch) > -1) {
serviceStatus = PollStatus.available(responseTime);
} else {
serviceStatus = PollStatus.unavailable("Banner: '" + response + "' does not contain match string '" + strBannerMatch + "'");
}
}
} catch (NoRouteToHostException e) {
String reason = "No route to host exception for address " + hostAddress;
LOG.debug(reason, e);
serviceStatus = PollStatus.unavailable(reason);
// Break out of for(;;)
break;
} catch (InterruptedIOException e) {
String reason = "did not connect to host with " + tracker;
LOG.debug(reason);
serviceStatus = PollStatus.unavailable(reason);
} catch (ConnectException e) {
String reason = "Connection exception for address: " + ipAddr;
LOG.debug(reason, e);
serviceStatus = PollStatus.unavailable(reason);
} catch (IOException e) {
String reason = "IOException while polling address: " + ipAddr;
LOG.debug(reason, e);
serviceStatus = PollStatus.unavailable(reason);
} finally {
try {
// Close the socket
if (socket != null)
socket.close();
} catch (IOException e) {
e.fillInStackTrace();
LOG.debug("poll: Error closing socket.", e);
}
}
}
//
return serviceStatus;
}
use of org.opennms.core.utils.TimeoutTracker in project opennms by OpenNMS.
the class AbstractPoll method poll.
/**
* <p>poll</p>
*
* @return a {@link org.opennms.netmgt.poller.PollStatus} object.
* @throws org.opennms.netmgt.protocols.InsufficientParametersException if any.
*/
@Override
public PollStatus poll() throws InsufficientParametersException {
Map<String, ?> emptyMap = Collections.emptyMap();
TimeoutTracker tracker = new TimeoutTracker(emptyMap, 1, getTimeout());
return poll(tracker);
}
use of org.opennms.core.utils.TimeoutTracker in project opennms by OpenNMS.
the class AvailabilityMonitor method poll.
/**
* {@inheritDoc}
*/
@Override
public PollStatus poll(MonitoredService svc, Map<String, Object> parameters) {
TimeoutTracker timeoutTracker = new TimeoutTracker(parameters, DEFAULT_RETRY, DEFAULT_TIMEOUT);
for (timeoutTracker.reset(); timeoutTracker.shouldRetry(); timeoutTracker.nextAttempt()) {
try {
timeoutTracker.startAttempt();
if (svc.getAddress().isReachable(timeoutTracker.getSoTimeout())) {
return PollStatus.available(timeoutTracker.elapsedTimeInMillis());
}
} catch (IOException e) {
LOG.debug("Unable to contact {}", svc.getIpAddr(), e);
}
}
String reason = svc + " failed to respond";
LOG.debug(reason);
return PollStatus.unavailable(reason);
}
use of org.opennms.core.utils.TimeoutTracker in project opennms by OpenNMS.
the class NsclientMonitor method poll.
/**
* {@inheritDoc}
*
* Poll the specified address for service availability. During the poll an
* attempt is made to connect on the specified port. If the connection
* request is successful, the parameters are parsed and turned into
* <code>NsclientCheckParams</code> and a check is performed against the
* remote NSClient service. If the <code>NsclientManager</code> responds
* with a <code>NsclientPacket</code> containing a result code of
* <code>NsclientPacket.RES_STATE_OK</code> then we have determined that
* we are talking to a valid service and we set the service status to
* SERVICE_AVAILABLE and return.
*/
@Override
public PollStatus poll(MonitoredService svc, Map<String, Object> parameters) {
// Holds the response reason.
String reason = null;
// Used to exit the retry loop early, if possible.
int serviceStatus = PollStatus.SERVICE_UNRESPONSIVE;
// This will hold the data the server sends back.
NsclientPacket response = null;
// Used to track how long the request took.
Double responseTime = null;
// NSClient related parameters.
String command = ParameterMap.getKeyedString(parameters, "command", NsclientManager.convertTypeToString(NsclientManager.CHECK_CLIENTVERSION));
int port = ParameterMap.getKeyedInteger(parameters, "port", NsclientManager.DEFAULT_PORT);
String password = ParameterMap.getKeyedString(parameters, "password", NSClientAgentConfig.DEFAULT_PASSWORD);
String params = ParameterMap.getKeyedString(parameters, "parameter", null);
int critPerc = ParameterMap.getKeyedInteger(parameters, "criticalPercent", 0);
int warnPerc = ParameterMap.getKeyedInteger(parameters, "warningPercent", 0);
TimeoutTracker tracker = new TimeoutTracker(parameters, DEFAULT_RETRY, DEFAULT_TIMEOUT);
// Get the address we're going to poll.
InetAddress ipAddr = svc.getAddress();
for (tracker.reset(); tracker.shouldRetry() && serviceStatus != PollStatus.SERVICE_AVAILABLE; tracker.nextAttempt()) {
try {
tracker.startAttempt();
// Create a client, set up details and connect.
NsclientManager client = new NsclientManager(InetAddressUtils.str(ipAddr), port, password);
client.setTimeout(tracker.getSoTimeout());
client.setPassword(password);
client.init();
// Set up the parameters the client will use to validate the
// response.
NsclientCheckParams clientParams = new NsclientCheckParams(critPerc, warnPerc, params);
// Send the request to the server and receive the response.
response = client.processCheckCommand(NsclientManager.convertStringToType(command), clientParams);
// Now save the time it took to process the check command.
responseTime = tracker.elapsedTimeInMillis();
if (response == null) {
continue;
}
if (response.getResultCode() == NsclientPacket.RES_STATE_OK) {
serviceStatus = PollStatus.SERVICE_AVAILABLE;
reason = response.getResponse();
} else if (response.getResultCode() == NsclientPacket.RES_STATE_CRIT) {
serviceStatus = PollStatus.SERVICE_UNAVAILABLE;
reason = response.getResponse();
// set this to null so we don't try to save data when the node is down
responseTime = null;
}
} catch (NsclientException e) {
LOG.debug("Nsclient Poller received exception from client", e);
reason = "NsclientException: " + e.getMessage();
}
}
// end for(;;)
return PollStatus.get(serviceStatus, reason, responseTime);
}
use of org.opennms.core.utils.TimeoutTracker in project opennms by OpenNMS.
the class CiscoPingMibMonitor method poll.
/**
* {@inheritDoc}
*
* <P>
* The poll() method is responsible for setting up and following up the IOS
* ping entry that proxies monitoring of the specified address for ICMP
* service availability.
* </P>
* @exception RuntimeException
* Thrown for any unrecoverable errors.
*/
@Override
public PollStatus poll(MonitoredService svc, Map<String, Object> parameters) {
final InetAddress targetIpAddr = InetAddrUtils.addr(getKeyedString(parameters, "targetIpAddr", null));
final InetAddress proxyIpAddr = InetAddrUtils.addr(getKeyedString(parameters, "proxyIpAddr", null));
int pingProtocol = 0;
try {
pingProtocol = determineAddrType(targetIpAddr);
} catch (RuntimeException e) {
LOG.debug("Unknown address type - neither IPv4 nor IPv6", e);
return PollStatus.unavailable("Unknown address type - neither IPv4 nor IPv6");
}
// Get configuration parameters into a CiscoPingEntry object
//
CiscoPingEntry pingEntry = new CiscoPingEntry();
pingEntry.setCiscoPingPacketCount(ParameterMap.getKeyedInteger(parameters, PARM_PACKET_COUNT, PARM_PACKET_COUNT_DEFAULT));
pingEntry.setCiscoPingPacketSize(ParameterMap.getKeyedInteger(parameters, PARM_PACKET_SIZE, PARM_PACKET_SIZE_DEFAULT));
pingEntry.setCiscoPingPacketTimeout(ParameterMap.getKeyedInteger(parameters, PARM_PACKET_TIMEOUT, PARM_PACKET_TIMEOUT_DEFAULT));
pingEntry.setCiscoPingPacketDelay(ParameterMap.getKeyedInteger(parameters, PARM_PACKET_DELAY, PARM_PACKET_DELAY_DEFAULT));
pingEntry.setCiscoPingEntryOwner(ParameterMap.getKeyedString(parameters, PARM_ENTRY_OWNER, PARM_ENTRY_OWNER_DEFAULT));
pingEntry.setCiscoPingVrfName(ParameterMap.getKeyedString(parameters, PARM_VRF_NAME, PARM_VRF_NAME_DEFAULT));
pingEntry.setCiscoPingSerialNumber(Double.valueOf(System.currentTimeMillis() / 1000d).intValue());
pingEntry.setCiscoPingProtocol(pingProtocol);
pingEntry.setCiscoPingAddress(targetIpAddr);
pingEntry.setCiscoPingEntryStatus(ROWSTATUS_CREATE_AND_GO);
int minSuccessPercent = ParameterMap.getKeyedInteger(parameters, PARM_SUCCESS_PERCENT, PARM_SUCCESS_PERCENT_DEFAULT);
// FIXME: Should the cleanup stuff be fixed to actually use this? Not clear if it really matters.
// int cleanupInterval = ParameterMap.getKeyedInteger(parameters, PARM_CLEANUP_INTERVAL, PARM_CLEANUP_INTERVAL_DEFAULT);
// Retrieve the *proxy* interface's SNMP peer object
//
SnmpAgentConfig agentConfig = getAgentConfig(svc, parameters);
LOG.debug("poll: setting SNMP peer attribute for interface {}", proxyIpAddr.getHostAddress());
// set timeout and retries on SNMP peer object
//
agentConfig.setTimeout(ParameterMap.getKeyedInteger(parameters, "timeout", agentConfig.getTimeout()));
agentConfig.setRetries(ParameterMap.getKeyedInteger(parameters, "retry", ParameterMap.getKeyedInteger(parameters, "retries", agentConfig.getRetries())));
agentConfig.setPort(ParameterMap.getKeyedInteger(parameters, "port", agentConfig.getPort()));
LOG.debug("Setting up CISCO-PING-MIB proxy poll for service {} on interface {} -- {}", svc.getSvcName(), targetIpAddr, pingEntry);
PollStatus serviceStatus = null;
TimeoutTracker timeoutTracker = new TimeoutTracker(parameters, DEFAULT_RETRY, DEFAULT_TIMEOUT);
// Send the SET-REQUEST PDU to create the ciscoPingEntry in createAndGo mode
SnmpValue[] setResult = SnmpUtils.set(agentConfig, pingEntry.generateCreateOids(), pingEntry.generateCreateValues());
if (setResult == null) {
LOG.warn("SNMP SET operation unsuccessful for proxy-ping entry for target {} -- {}", targetIpAddr, pingEntry);
return PollStatus.unknown("SNMP SET failed for ciscoPingTable entry on proxy interface " + proxyIpAddr + " with instance ID " + pingEntry.getCiscoPingSerialNumber());
}
// a good starting point.
try {
Thread.sleep(pingEntry.calculateMinInitialWait() * 2L);
} catch (InterruptedException e) {
}
// Now check whether the ping has completed and, if so, whether it succeeded and its times
SnmpValue[] statusValues = null;
for (timeoutTracker.reset(); (timeoutTracker.shouldRetry() && (statusValues == null || statusValues.length < 6 || statusValues[5].toInt() != 1)); timeoutTracker.nextAttempt()) {
statusValues = SnmpUtils.get(agentConfig, pingEntry.generateResultsOids());
}
// If we didn't get the results back, mark the service as unknown
if (statusValues == null || (statusValues.length == 1 && statusValues[0] == null)) {
LOG.warn("SNMP GET operation unsuccessful for proxy-ping entry for target {} -- {}", targetIpAddr, pingEntry);
return PollStatus.unknown("SNMP GET failed for ciscoPingTable entry on proxy interface " + proxyIpAddr + " with instance ID " + pingEntry.getCiscoPingSerialNumber());
}
// mark the service unknown
if (statusValues.length < 6) {
LOG.warn("Proxy-ping entry did not indicate whether ping completed after retries exhausted for target {} -- {}", targetIpAddr, pingEntry);
return PollStatus.unknown("ciscoPingTable entry is missing pingCompleted column on proxy interface " + proxyIpAddr + " with instance ID " + pingEntry.getCiscoPingSerialNumber());
}
// mark the service unknown
if (statusValues[5].toInt() != 1) {
LOG.warn("Proxy-ping entry marked not completed after retries exhausted for target {} -- {}", targetIpAddr, pingEntry);
return PollStatus.unknown("ciscoPingTable entry marked not completed on proxy interface " + proxyIpAddr + " with instance ID " + pingEntry.getCiscoPingSerialNumber());
}
// If the ping has completed, verify that the percent of completed pings meets our minimum
// success percent. If not, mark the service down.
double sentPings = statusValues[0].toInt();
double receivedPings = statusValues[1].toInt();
double successPct = receivedPings / sentPings * 100;
if (receivedPings == 0) {
LOG.info("Proxy-ping entry indicates no pings succeeded for target {} -- {}", targetIpAddr, pingEntry);
cleanupCurrentEntry(pingEntry, proxyIpAddr, agentConfig);
return PollStatus.unavailable("All remote pings (" + sentPings + " of " + sentPings + ") failed");
} else if (successPct < minSuccessPercent) {
LOG.info("Proxy-ping entry indicates {}% success, which misses the success-percent target of {}% for target {} -- {}", successPct, minSuccessPercent, targetIpAddr, pingEntry);
cleanupCurrentEntry(pingEntry, proxyIpAddr, agentConfig);
return PollStatus.unavailable(successPct + " percent (" + receivedPings + "/" + sentPings + ") pings succeeded, less than target " + minSuccessPercent + " percent");
}
// If we've arrived here, then enough pings completed to consider the service up!
Map<String, Number> pingProps = new HashMap<String, Number>();
double minRtt = statusValues[2].toInt();
double avgRtt = statusValues[3].toInt();
double maxRtt = statusValues[4].toInt();
LOG.debug("Logging successful poll: sent={}, received={}, minRtt={}, avgRtt={}, maxRtt={} for proxy-ping of target {} -- {}", sentPings, receivedPings, minRtt, avgRtt, maxRtt, targetIpAddr, pingEntry);
pingProps.put("sent", sentPings);
pingProps.put("received", receivedPings);
pingProps.put("minRtt", minRtt);
pingProps.put("avgRtt", avgRtt);
pingProps.put("maxRtt", maxRtt);
cleanupCurrentEntry(pingEntry, proxyIpAddr, agentConfig);
// TODO: Find and clean up defunct rows before returning
// Actually it's not clear that this is necessary, seems IOS cleans up old
// entries on its own some minutes after their creation. Need to investigate.
serviceStatus = PollStatus.available(avgRtt);
serviceStatus.setProperties(pingProps);
return serviceStatus;
}
Aggregations