2023-09-13 07:12:18 +00:00
|
|
|
|
using Core;
|
|
|
|
|
using KubernetesWorkflow;
|
2023-11-12 09:07:23 +00:00
|
|
|
|
using KubernetesWorkflow.Types;
|
2023-11-07 11:02:17 +00:00
|
|
|
|
using Logging;
|
2023-09-13 09:25:08 +00:00
|
|
|
|
using System.Text;
|
2023-04-13 12:36:17 +00:00
|
|
|
|
|
2023-09-13 07:12:18 +00:00
|
|
|
|
namespace MetricsPlugin
|
2023-04-13 12:36:17 +00:00
|
|
|
|
{
|
2023-09-13 07:12:18 +00:00
|
|
|
|
public class PrometheusStarter
|
2023-04-13 12:36:17 +00:00
|
|
|
|
{
|
2023-09-13 14:06:05 +00:00
|
|
|
|
private readonly PrometheusContainerRecipe recipe = new PrometheusContainerRecipe();
|
2023-09-13 07:12:18 +00:00
|
|
|
|
private readonly IPluginTools tools;
|
|
|
|
|
|
|
|
|
|
public PrometheusStarter(IPluginTools tools)
|
2023-04-13 12:36:17 +00:00
|
|
|
|
{
|
2023-09-13 07:12:18 +00:00
|
|
|
|
this.tools = tools;
|
2023-04-13 12:36:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-11-07 10:17:20 +00:00
|
|
|
|
public RunningContainers CollectMetricsFor(IMetricsScrapeTarget[] targets)
|
2023-04-13 12:36:17 +00:00
|
|
|
|
{
|
2023-11-21 08:03:52 +00:00
|
|
|
|
if (!targets.Any()) throw new ArgumentException(nameof(targets) + " must not be empty.");
|
|
|
|
|
|
2023-09-13 09:25:08 +00:00
|
|
|
|
Log($"Starting metrics server for {targets.Length} targets...");
|
|
|
|
|
var startupConfig = new StartupConfig();
|
|
|
|
|
startupConfig.Add(new PrometheusStartupConfig(GeneratePrometheusConfig(targets)));
|
2023-04-13 12:36:17 +00:00
|
|
|
|
|
2023-09-13 09:25:08 +00:00
|
|
|
|
var workflow = tools.CreateWorkflow();
|
2023-09-25 06:47:19 +00:00
|
|
|
|
var runningContainers = workflow.Start(1, recipe, startupConfig);
|
2023-09-13 09:25:08 +00:00
|
|
|
|
if (runningContainers.Containers.Length != 1) throw new InvalidOperationException("Expected only 1 Prometheus container to be created.");
|
2023-04-13 12:36:17 +00:00
|
|
|
|
|
2023-09-13 09:25:08 +00:00
|
|
|
|
Log("Metrics server started.");
|
2023-11-07 10:17:20 +00:00
|
|
|
|
return runningContainers;
|
2023-04-13 12:36:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-11-07 10:17:20 +00:00
|
|
|
|
public MetricsAccess CreateAccessForTarget(RunningContainers metricsContainer, IMetricsScrapeTarget target)
|
2023-09-13 09:25:08 +00:00
|
|
|
|
{
|
2023-11-07 10:17:20 +00:00
|
|
|
|
var metricsQuery = new MetricsQuery(tools, metricsContainer.Containers.Single());
|
2023-09-13 09:25:08 +00:00
|
|
|
|
return new MetricsAccess(metricsQuery, target);
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-13 14:06:05 +00:00
|
|
|
|
public string GetPrometheusId()
|
|
|
|
|
{
|
|
|
|
|
return recipe.Image;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-13 09:25:08 +00:00
|
|
|
|
private void Log(string msg)
|
|
|
|
|
{
|
|
|
|
|
tools.GetLog().Log(msg);
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-06 14:27:23 +00:00
|
|
|
|
private string GeneratePrometheusConfig(IMetricsScrapeTarget[] targets)
|
2023-09-13 09:25:08 +00:00
|
|
|
|
{
|
|
|
|
|
var config = "";
|
|
|
|
|
config += "global:\n";
|
|
|
|
|
config += " scrape_interval: 10s\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 target in targets)
|
|
|
|
|
{
|
2023-11-06 14:27:23 +00:00
|
|
|
|
config += $" - '{FormatTarget(target)}'\n";
|
2023-09-13 09:25:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var bytes = Encoding.ASCII.GetBytes(config);
|
|
|
|
|
return Convert.ToBase64String(bytes);
|
|
|
|
|
}
|
2023-11-06 14:27:23 +00:00
|
|
|
|
|
|
|
|
|
private string FormatTarget(IMetricsScrapeTarget target)
|
|
|
|
|
{
|
2023-11-07 11:02:17 +00:00
|
|
|
|
return ScrapeTargetHelper.FormatTarget(tools.GetLog(), target);
|
2023-11-06 14:27:23 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static class ScrapeTargetHelper
|
|
|
|
|
{
|
2023-11-07 11:02:17 +00:00
|
|
|
|
public static string FormatTarget(ILog log, IMetricsScrapeTarget target)
|
2023-11-06 14:27:23 +00:00
|
|
|
|
{
|
2023-11-07 11:02:17 +00:00
|
|
|
|
var a = target.Container.GetAddress(log, target.MetricsPortTag);
|
2023-11-06 14:27:23 +00:00
|
|
|
|
var host = a.Host.Replace("http://", "").Replace("https://", "");
|
|
|
|
|
return $"{host}:{a.Port}";
|
|
|
|
|
}
|
2023-04-13 12:36:17 +00:00
|
|
|
|
}
|
|
|
|
|
}
|