package com.intrbiz.bergamot.worker.engine.agent;
import java.text.DecimalFormat;
import java.util.UUID;
import java.util.stream.Collectors;
import org.apache.log4j.Logger;
import com.intrbiz.bergamot.agent.server.BergamotAgentServerHandler;
import com.intrbiz.bergamot.model.message.agent.check.CheckDiskIO;
import com.intrbiz.bergamot.model.message.agent.stat.DiskIOStat;
import com.intrbiz.bergamot.model.message.agent.stat.diskio.DiskIOInfo;
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.worker.engine.AbstractExecutor;
import com.intrbiz.gerald.polyakov.gauge.DoubleGaugeReading;
/**
* Check disk IO for an interface via Bergamot Agent
*/
public class DiskIOExecutor extends AbstractExecutor<AgentEngine>
{
public static final String NAME = "disk-io";
private Logger logger = Logger.getLogger(DiskIOExecutor.class);
private static final DecimalFormat DFMT = new DecimalFormat("0.00");
public DiskIOExecutor()
{
super();
}
/**
* Only execute Checks where the engine == "agent"
*/
@Override
public boolean accept(ExecuteCheck task)
{
return AgentEngine.NAME.equals(task.getEngine()) && NAME.equals(task.getExecutor());
}
/**
* Parameters:
* devices - CSV list of block device names (eg: /dev/sda1) to check, blank for all
* warning - the throughput warning threshold in MB/s
* critical - the throughput critical threshold in MB/s
* peak - check the peak IO rate rather than 5 minute average
*/
@Override
public void execute(ExecuteCheck executeCheck)
{
if (logger.isTraceEnabled()) logger.trace("Checking Bergamot Agent disk io");
try
{
// check the host presence
UUID agentId = executeCheck.getAgentId();
if (agentId == null) throw new RuntimeException("No agent id was given");
// lookup the agent
BergamotAgentServerHandler agent = this.getEngine().getAgentServer().getRegisteredAgent(agentId);
if (agent != null)
{
// get the user stats
long sent = System.nanoTime();
agent.sendMessageToAgent(new CheckDiskIO(executeCheck.getParameterCSV("device")), (response) -> {
double runtime = ((double)(System.nanoTime() - sent)) / 1000_000D;
DiskIOStat stat = (DiskIOStat) response;
if (logger.isTraceEnabled()) logger.trace("Got DiskIOStat in " + runtime + "ms: " + stat);
// thresholds
double warning = executeCheck.getDoubleParameter("warning", 200);
double critical = executeCheck.getDoubleParameter("critical", 250);
// apply the check
boolean peak = executeCheck.getBooleanParameter("peak", false);
this.publishActiveResult(executeCheck, new ActiveResultMO().fromCheck(executeCheck).applyThresholds(
stat.getDisks(),
(v, t) -> (peak ? v.getFiveMinuteRate().getReadPeakRateMBps(): v.getFiveMinuteRate().getReadRateMBps()) > t || (peak ? v.getFiveMinuteRate().getWritePeakRateMBps(): v.getFiveMinuteRate().getWriteRateMBps()) > t,
warning,
critical,
stat.getDisks().stream().map((n) ->
n.getName() +
" Read: " + DFMT.format(n.getFiveMinuteRate().getReadRateMBps()) + "MB/s (" + DFMT.format(n.getFiveMinuteRate().getReadPeakRateMBps()) + "MB/s Peak) - " + DFMT.format(n.getFiveMinuteRate().getReads()) + "/s (" + DFMT.format(n.getFiveMinuteRate().getPeakReads()) + "/s Peak)" +
" Write: " + DFMT.format(n.getFiveMinuteRate().getWriteRateMBps()) + "MB/s (" + DFMT.format(n.getFiveMinuteRate().getWritePeakRateMBps()) + "MB/s Peak) - " + DFMT.format(n.getFiveMinuteRate().getWrites()) + "/s (" + DFMT.format(n.getFiveMinuteRate().getPeakWrites()) + "/s Peak)"
).collect(Collectors.joining("; "))
).runtime(runtime));
// readings
ReadingParcelMO readings = new ReadingParcelMO().fromCheck(executeCheck.getCheckId()).captured(System.currentTimeMillis());
for (DiskIOInfo disk : stat.getDisks())
{
// rate
readings.reading(new DoubleGaugeReading("read-rate-[" + disk.getName() + "]", "MB/s", disk.getFiveMinuteRate().getReadRateMBps(), warning, critical, null, null));
readings.reading(new DoubleGaugeReading("read-rate-peak-[" + disk.getName() + "]", "MB/s", disk.getFiveMinuteRate().getReadPeakRateMBps(), warning, critical, null, null));
readings.reading(new DoubleGaugeReading("write-rate-[" + disk.getName() + "]", "MB/s", disk.getFiveMinuteRate().getWriteRateMBps(), warning, critical, null, null));
readings.reading(new DoubleGaugeReading("write-rate-peak-[" + disk.getName() + "]", "MB/s", disk.getFiveMinuteRate().getWritePeakRateMBps(), warning, critical, null, null));
// reads
readings.reading(new DoubleGaugeReading("reads-[" + disk.getName() + "]", null, disk.getFiveMinuteRate().getReads(), warning, critical, null, null));
readings.reading(new DoubleGaugeReading("writes-[" + disk.getName() + "]", null, disk.getFiveMinuteRate().getWrites(), warning, critical, null, null));
}
this.publishReading(executeCheck, readings);
});
}
else
{
// raise an error
this.publishActiveResult(executeCheck, new ActiveResultMO().fromCheck(executeCheck).disconnected("Bergamot Agent disconnected"));
}
}
catch (Exception e)
{
this.publishActiveResult(executeCheck, new ActiveResultMO().fromCheck(executeCheck).error(e));
}
}
}