101 lines
3.2 KiB
C#
101 lines
3.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
// ReSharper disable PossibleInvalidOperationException
|
|
|
|
namespace Monithor.api.Monitors {
|
|
public class HttpMonitor : IMonitor {
|
|
private readonly string _server;
|
|
|
|
public string Identifier { get; set; }
|
|
|
|
public HttpMonitor(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\"] == \"http_response\")"
|
|
+ $"|> filter(fn: (r) => r[\"server\"] == \"{_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("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;
|
|
}
|
|
}
|
|
}
|
|
} |