monithor/Monithor.api/Monitors/TcpMonitor.cs
2021-05-13 22:38:02 +02:00

104 lines
3.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
// ReSharper disable PossibleInvalidOperationException
namespace Monithor.api.Monitors {
public class TcpMonitor : IMonitor {
private readonly string _server;
private readonly string _port;
public string Identifier { get; set; }
public string Message { get; set; }
public TcpMonitor(string identifier, string server, string port) {
Identifier = identifier;
_server = server;
_port = port;
}
public string LastValue { get; set; }
public DateTime StartedAt { get; set; }
public DateTime ResolvedAt { get; set; }
public MonitorStatus Status { get; set; }
public IEnumerable<FluxItem> GetFluxItems(Influx influx, string timespan) {
var query = $"from(bucket: \"{influx.Bucket}\")"
+ $"|> range(start: -5m)"
+ $"|> filter(fn: (r) => r[\"_measurement\"] == \"net_response\")"
+ $"|> filter(fn: (r) => r[\"server\"] == \"{_server}\")"
+ $"|> filter(fn: (r) => r[\"port\"] == \"{_port}\")"
+ $"|> 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("result_type").ToString(),
Message = (Math.Ceiling((double) (record.GetValueByKey("response_time") ?? -1d) * 1000) + " ms").Replace("-1000 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 != "success");
var allDown = data.All(p => p.Status != "success");
LastValue = data.Last().Status;
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;
}
}
}
}