2023-03-27 12:49:34 +00:00
|
|
|
|
using NUnit.Framework;
|
2023-03-27 14:24:04 +00:00
|
|
|
|
using System.Text;
|
2023-03-27 12:49:34 +00:00
|
|
|
|
|
|
|
|
|
namespace CodexDistTestCore
|
|
|
|
|
{
|
|
|
|
|
public class MetricsAggregator
|
|
|
|
|
{
|
2023-03-28 11:43:25 +00:00
|
|
|
|
private readonly NumberSource prometheusNumberSource = new NumberSource(0);
|
2023-03-27 12:49:34 +00:00
|
|
|
|
private readonly TestLog log;
|
|
|
|
|
private readonly K8sManager k8sManager;
|
2023-03-29 09:29:43 +00:00
|
|
|
|
private readonly Dictionary<MetricsQuery, OnlineCodexNode[]> activePrometheuses = new Dictionary<MetricsQuery, OnlineCodexNode[]>();
|
2023-03-27 12:49:34 +00:00
|
|
|
|
|
|
|
|
|
public MetricsAggregator(TestLog log, K8sManager k8sManager)
|
|
|
|
|
{
|
|
|
|
|
this.log = log;
|
|
|
|
|
this.k8sManager = k8sManager;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-27 14:24:04 +00:00
|
|
|
|
public MetricsAccess BeginCollectingMetricsFor(OnlineCodexNode[] nodes)
|
2023-03-27 12:49:34 +00:00
|
|
|
|
{
|
2023-03-28 11:43:25 +00:00
|
|
|
|
var alreadyStartedNodes = nodes.Where(n => activePrometheuses.Values.Any(v => v.Contains(n)));
|
|
|
|
|
if (alreadyStartedNodes.Any())
|
2023-03-27 14:24:04 +00:00
|
|
|
|
{
|
2023-03-28 11:43:25 +00:00
|
|
|
|
Assert.Fail("Incorrect test setup: 'GatherMetrics' was already called on one or more of these OnlineCodexNodes.");
|
2023-03-27 14:24:04 +00:00
|
|
|
|
throw new InvalidOperationException();
|
|
|
|
|
}
|
2023-03-27 12:49:34 +00:00
|
|
|
|
|
2023-03-27 14:24:04 +00:00
|
|
|
|
log.Log($"Starting metrics collecting for {nodes.Length} nodes...");
|
2023-03-27 12:49:34 +00:00
|
|
|
|
|
2023-03-27 14:24:04 +00:00
|
|
|
|
var config = GeneratePrometheusConfig(nodes);
|
2023-03-28 11:43:25 +00:00
|
|
|
|
var prometheus = k8sManager.BringOnlinePrometheus(config, prometheusNumberSource.GetNextNumber());
|
2023-03-29 09:29:43 +00:00
|
|
|
|
var query = new MetricsQuery(prometheus);
|
|
|
|
|
activePrometheuses.Add(query, nodes);
|
2023-03-27 12:49:34 +00:00
|
|
|
|
|
2023-03-27 14:24:04 +00:00
|
|
|
|
log.Log("Metrics service started.");
|
2023-03-29 09:29:43 +00:00
|
|
|
|
return new MetricsAccess(query, nodes);
|
2023-03-27 12:49:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void DownloadAllMetrics()
|
|
|
|
|
{
|
2023-03-30 08:43:17 +00:00
|
|
|
|
var download = new MetricsDownloader(log, activePrometheuses);
|
|
|
|
|
download.DownloadAllMetrics();
|
2023-03-27 12:49:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-03-27 14:24:04 +00:00
|
|
|
|
private string GeneratePrometheusConfig(OnlineCodexNode[] nodes)
|
2023-03-27 12:49:34 +00:00
|
|
|
|
{
|
2023-03-27 14:24:04 +00:00
|
|
|
|
var config = "";
|
|
|
|
|
config += "global:\n";
|
|
|
|
|
config += " scrape_interval: 30s\n";
|
|
|
|
|
config += " scrape_timeout: 10s\n";
|
|
|
|
|
config += "\n";
|
|
|
|
|
config += "scrape_configs:\n";
|
|
|
|
|
config += " - job_name: services\n";
|
|
|
|
|
config += " metrics_path: /metrics\n";
|
|
|
|
|
config += " static_configs:\n";
|
|
|
|
|
config += " - targets:\n";
|
|
|
|
|
|
|
|
|
|
foreach (var node in nodes)
|
2023-03-27 12:49:34 +00:00
|
|
|
|
{
|
|
|
|
|
var ip = node.Group.PodInfo!.Ip;
|
2023-03-27 14:24:04 +00:00
|
|
|
|
var port = node.Container.MetricsPort;
|
|
|
|
|
config += $" - '{ip}:{port}'\n";
|
2023-03-27 12:49:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-03-27 14:24:04 +00:00
|
|
|
|
var bytes = Encoding.ASCII.GetBytes(config);
|
|
|
|
|
return Convert.ToBase64String(bytes);
|
2023-03-27 12:49:34 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class PrometheusInfo
|
|
|
|
|
{
|
|
|
|
|
public PrometheusInfo(int servicePort, PodInfo podInfo)
|
|
|
|
|
{
|
|
|
|
|
ServicePort = servicePort;
|
|
|
|
|
PodInfo = podInfo;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int ServicePort { get; }
|
|
|
|
|
public PodInfo PodInfo { get; }
|
|
|
|
|
}
|
|
|
|
|
}
|