101 lines
3.1 KiB
C#
101 lines
3.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
// ReSharper disable PossibleInvalidOperationException
|
|
|
|
namespace Monithor.api.Monitors {
|
|
public class IcmpMonitor : IMonitor {
|
|
private readonly string _server;
|
|
|
|
public string Identifier { get; set; }
|
|
|
|
public IcmpMonitor(string identifier, string server) {
|
|
Identifier = identifier;
|
|
_server = server;
|
|
}
|
|
|
|
public string LastValue { get; set; }
|
|
public DateTime StartedAt { get; set; }
|
|
public DateTime ResolvedAt { get; set; }
|
|
public MonitorStatus Status { get; set; }
|
|
public string Message { get; set; }
|
|
|
|
public IEnumerable<FluxItem> GetFluxItems(Influx influx, string timespan) {
|
|
var query = $"from(bucket: \"{influx.Bucket}\")"
|
|
+ $"|> range(start: -5m)"
|
|
+ $"|> filter(fn: (r) => r[\"_measurement\"] == \"ping\")"
|
|
+ $"|> filter(fn: (r) => r[\"url\"] == \"{_server}\")"
|
|
+ $"|> keep(columns:[\"_field\", \"_time\", \"_value\"])"
|
|
+ $"|> pivot(rowKey:[\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\")"
|
|
+ $"|> sort(columns: [\"_time\"], desc: false)";
|
|
|
|
var result = influx.Client.GetQueryApi().QueryAsync(query, influx.Org).Result;
|
|
|
|
return (from table in result
|
|
from record in table.Records
|
|
select new FluxItem {
|
|
Time = record.GetTime().Value,
|
|
Status = record.GetValueByKey("percent_packet_loss") + "%",
|
|
Message = (Math.Ceiling((double) (record.GetValueByKey("percentile50_ms") ?? -1d)) + " ms").Replace("-1 ms", "n/a")
|
|
}).ToList();
|
|
}
|
|
|
|
public bool Update(IEnumerable<FluxItem> data) {
|
|
if (!data.Any()) {
|
|
if (Status == MonitorStatus.Down)
|
|
return false;
|
|
|
|
Status = MonitorStatus.Down;
|
|
return true;
|
|
}
|
|
|
|
if (Status == MonitorStatus.Unknown) {
|
|
Status = MonitorStatus.Up;
|
|
}
|
|
|
|
var anyDown = data.Any(p => p.Status != "0%");
|
|
var allDown = data.All(p => p.Status != "0%");
|
|
|
|
LastValue = data.Last().Status + " loss";
|
|
Message = data.Last().Message;
|
|
|
|
switch (Status) {
|
|
case MonitorStatus.Down when anyDown && !allDown:
|
|
Status = MonitorStatus.Recovering;
|
|
ResolvedAt = DateTime.Now;
|
|
return true;
|
|
case MonitorStatus.Down when allDown: return false;
|
|
case MonitorStatus.Down:
|
|
Status = MonitorStatus.Up;
|
|
return true;
|
|
case MonitorStatus.Validating when anyDown && !allDown: return false;
|
|
case MonitorStatus.Validating when allDown:
|
|
Status = MonitorStatus.Down;
|
|
return true;
|
|
case MonitorStatus.Validating:
|
|
Status = MonitorStatus.Up;
|
|
return false;
|
|
case MonitorStatus.Recovering when anyDown && !allDown: return false;
|
|
case MonitorStatus.Recovering when allDown:
|
|
Status = MonitorStatus.Down;
|
|
return true;
|
|
case MonitorStatus.Recovering:
|
|
Status = MonitorStatus.Up;
|
|
return true;
|
|
case MonitorStatus.Up when anyDown && !allDown:
|
|
Status = MonitorStatus.Validating;
|
|
StartedAt = DateTime.Now;
|
|
return false;
|
|
case MonitorStatus.Up when allDown:
|
|
Status = MonitorStatus.Down;
|
|
StartedAt = DateTime.Now;
|
|
return true;
|
|
case MonitorStatus.Up: return false;
|
|
default:
|
|
Status = MonitorStatus.Up;
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
} |