2023-03-27 14:24:04 +00:00
|
|
|
|
using CodexDistTestCore.Config;
|
|
|
|
|
|
|
|
|
|
namespace CodexDistTestCore
|
2023-03-27 12:49:34 +00:00
|
|
|
|
{
|
|
|
|
|
public interface IMetricsAccess
|
|
|
|
|
{
|
2023-03-28 08:25:48 +00:00
|
|
|
|
int? GetMostRecentInt(string metricName, IOnlineCodexNode node);
|
2023-03-27 12:49:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class MetricsAccess : IMetricsAccess
|
|
|
|
|
{
|
2023-03-27 14:24:04 +00:00
|
|
|
|
private readonly K8sCluster k8sCluster = new K8sCluster();
|
|
|
|
|
private readonly Http http;
|
|
|
|
|
|
|
|
|
|
public MetricsAccess(PrometheusInfo prometheusInfo)
|
|
|
|
|
{
|
|
|
|
|
http = new Http(
|
|
|
|
|
k8sCluster.GetIp(),
|
|
|
|
|
prometheusInfo.ServicePort,
|
|
|
|
|
"api/v1");
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-28 08:25:48 +00:00
|
|
|
|
public int? GetMostRecentInt(string metricName, IOnlineCodexNode node)
|
2023-03-27 12:49:34 +00:00
|
|
|
|
{
|
2023-03-28 08:25:48 +00:00
|
|
|
|
var n = (OnlineCodexNode)node;
|
|
|
|
|
var pod = n.Group.PodInfo!;
|
2023-03-27 14:24:04 +00:00
|
|
|
|
|
2023-03-28 08:25:48 +00:00
|
|
|
|
var response = http.HttpGetJson<PrometheusQueryResponse>($"query?query=last_over_time({metricName}[12h])");
|
|
|
|
|
if (response.status != "success") return null;
|
2023-03-27 14:24:04 +00:00
|
|
|
|
|
2023-03-28 08:25:48 +00:00
|
|
|
|
var forNode = response.data.result.SingleOrDefault(d => d.metric.instance == $"{pod.Ip}:{n.Container.MetricsPort}");
|
|
|
|
|
if (forNode == null) return null;
|
2023-03-27 14:24:04 +00:00
|
|
|
|
|
2023-03-28 08:25:48 +00:00
|
|
|
|
if (forNode.value == null || forNode.value.Length == 0) return null;
|
|
|
|
|
|
|
|
|
|
if (forNode.value.Length != 2) throw new InvalidOperationException("Expected value to be [double, string].");
|
|
|
|
|
// [0] = double, timestamp
|
|
|
|
|
// [1] = string, value
|
|
|
|
|
|
|
|
|
|
return Convert.ToInt32(forNode.value[1]);
|
2023-03-27 12:49:34 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-03-27 14:24:04 +00:00
|
|
|
|
|
2023-03-28 08:25:48 +00:00
|
|
|
|
public class PrometheusQueryResponse
|
2023-03-27 14:24:04 +00:00
|
|
|
|
{
|
|
|
|
|
public string status { get; set; } = string.Empty;
|
2023-03-28 08:25:48 +00:00
|
|
|
|
public PrometheusQueryResponseData data { get; set; } = new();
|
2023-03-27 14:24:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-03-28 08:25:48 +00:00
|
|
|
|
public class PrometheusQueryResponseData
|
2023-03-27 14:24:04 +00:00
|
|
|
|
{
|
|
|
|
|
public string resultType { get; set; } = string.Empty;
|
2023-03-28 08:25:48 +00:00
|
|
|
|
public PrometheusQueryResponseDataResultEntry[] result { get; set; } = Array.Empty<PrometheusQueryResponseDataResultEntry>();
|
2023-03-27 14:24:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-03-28 08:25:48 +00:00
|
|
|
|
public class PrometheusQueryResponseDataResultEntry
|
2023-03-27 14:24:04 +00:00
|
|
|
|
{
|
|
|
|
|
public ResultEntryMetric metric { get; set; } = new();
|
2023-03-28 08:25:48 +00:00
|
|
|
|
public object[] value { get; set; } = Array.Empty<object>();
|
2023-03-27 14:24:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class ResultEntryMetric
|
|
|
|
|
{
|
|
|
|
|
public string __name__ { get; set; } = string.Empty;
|
|
|
|
|
public string instance { get; set; } = string.Empty;
|
|
|
|
|
public string job { get; set; } = string.Empty;
|
|
|
|
|
}
|
2023-03-27 12:49:34 +00:00
|
|
|
|
}
|