package com.intrbiz.bergamot.worker.engine.nrpe; import java.util.List; import java.util.stream.Collectors; import org.apache.log4j.Logger; import com.codahale.metrics.Counter; import com.codahale.metrics.Timer; import com.intrbiz.Util; import com.intrbiz.bergamot.model.message.check.ExecuteCheck; import com.intrbiz.bergamot.model.message.reading.ReadingParcelMO; import com.intrbiz.bergamot.model.message.result.ActiveResultMO; import com.intrbiz.bergamot.nagios.model.NagiosPerfData; import com.intrbiz.bergamot.queue.key.ReadingKey; import com.intrbiz.bergamot.worker.engine.AbstractExecutor; import com.intrbiz.gerald.polyakov.Reading; import com.intrbiz.gerald.source.IntelligenceSource; import com.intrbiz.gerald.witchcraft.Witchcraft; /** * Execute NRPE checks from pure Java */ public class NRPEExecutor extends AbstractExecutor<NRPEEngine> { private Logger logger = Logger.getLogger(NRPEExecutor.class); private final Timer nrpeRequestTimer; private final Counter failedRequests; public NRPEExecutor() { super(); // setup metrics IntelligenceSource source = Witchcraft.get().source("com.intrbiz.bergamot.nrpe"); this.nrpeRequestTimer = source.getRegistry().timer("all-nrpe-requests"); this.failedRequests = source.getRegistry().counter("failed-nrpe-requests"); } /** * Only execute Checks where the engine == "nrpe" */ @Override public boolean accept(ExecuteCheck task) { return NRPEEngine.NAME.equalsIgnoreCase(task.getEngine()); } @Override public void execute(ExecuteCheck executeCheck) { logger.info("Executing NRPE check : " + executeCheck.getEngine() + "::" + executeCheck.getName() + " for " + executeCheck.getCheckType() + " " + executeCheck.getCheckId()); Timer.Context tctx = this.nrpeRequestTimer.time(); try { // the host String host = executeCheck.getParameter("host"); if (Util.isEmpty(host)) throw new RuntimeException("The 'host' parameter must be provided."); // the command String command = executeCheck.getParameter("command"); if (Util.isEmpty(command)) throw new RuntimeException("The 'command' parameter must be provided."); // arguments - any parameter starting with 'arg' is treated as an argument to send to NRPE List<String> args = executeCheck.getParametersStartingWith("nrpe-arg") .stream() .sorted((a,b) -> a.getName().compareTo(b.getName())) .map((p) -> p.getValue()) .collect(Collectors.toList()); if (logger.isTraceEnabled()) logger.trace("Sending arguments: " + args); // submit the command to the poller // TODO timeouts this.getEngine().getPoller().command( host, 5666, 5, 60, (response) -> { ActiveResultMO resultMO = new ActiveResultMO().fromCheck(executeCheck); resultMO.setOk(response.toOk()); resultMO.setStatus(response.toStatus()); resultMO.setOutput(response.getOutput()); resultMO.setRuntime(response.getRuntime()); tctx.stop(); this.publishActiveResult(executeCheck, resultMO); // readings ReadingParcelMO readings = new ReadingParcelMO().fromCheck(executeCheck.getCheckId()); for (NagiosPerfData perfData : response.getPerfData()) { Reading reading = perfData.toReading(); if (reading != null) readings.reading(reading); } if (readings.getReadings().size() > 0) this.publishReading(new ReadingKey(executeCheck.getCheckId(), executeCheck.getProcessingPool()), readings); }, (exception) -> { tctx.stop(); failedRequests.inc(); this.publishActiveResult(executeCheck, new ActiveResultMO().fromCheck(executeCheck).error(exception)); }, command, args ); } catch (Exception e) { logger.error("Failed to execute NRPE check", e); tctx.stop(); this.failedRequests.inc(); this.publishActiveResult(executeCheck, new ActiveResultMO().fromCheck(executeCheck).error(e)); } } }