using System.Text.Json; namespace PrometheusAPI; public class PrometheusClient { private readonly HttpClient _client; public PrometheusClient(HttpClient client) { _client = client; } public async Task InstantQuery(string query, DateTime? time = null, CancellationToken token = default) { var q = new List> { new KeyValuePair("query", query) }; if (time != null) q.Add(new KeyValuePair("time", TimeSeries.DateTimeToUnixTimestamp(time.Value).ToString("F3"))); var form = new FormUrlEncodedContent(q); var response = await _client.PostAsync("/api/v1/query", form); var json = await response.Content.ReadAsStringAsync() ?? throw new InvalidDataException("Responce is null"); var res = JsonSerializer.Deserialize(json, JsonSetializerSetup.Options) ?? throw new InvalidDataException("Can't convert responce to InstantQueryResponse"); return res; } public async Task RangeQuery(string query, DateTime start, DateTime end, TimeSpan step, TimeSpan timeout = default, CancellationToken token = default) { var q = new List> { new KeyValuePair("query", query), new KeyValuePair("start", TimeSeries.DateTimeToUnixTimestamp(start).ToString("F3")), new KeyValuePair("end", TimeSeries.DateTimeToUnixTimestamp(end).ToString("F3")), new KeyValuePair("step", step.TotalSeconds.ToString("F3")) }; if( timeout != default ) { q.Add(new KeyValuePair("timeout", timeout.TotalSeconds.ToString("F3"))); } var form = new FormUrlEncodedContent(q); var response = await _client.PostAsync("/api/v1/query_range", form); var json = await response.Content.ReadAsStringAsync() ?? throw new InvalidDataException("Responce is null"); var res = JsonSerializer.Deserialize(json, JsonSetializerSetup.Options) ?? throw new InvalidDataException("Can't convert responce to InstantQueryResponse"); return res; } public async Task FormatQuery(string query, CancellationToken token = default) { var q = new List> { new KeyValuePair("query", query), }; var form = new FormUrlEncodedContent(q); var response = await _client.PostAsync("/api/v1/format_query", form); var json = await response.Content.ReadAsStringAsync() ?? throw new InvalidDataException("Responce is null"); var res = JsonSerializer.Deserialize(json, JsonSetializerSetup.Options) ?? throw new InvalidDataException("Can't convert responce to JsonDocument"); var status = res.RootElement.GetProperty("status").GetString() ?? throw new InvalidDataException("Can't get status"); if (!status.Equals("success", StringComparison.OrdinalIgnoreCase) ) throw new InvalidDataException(res.RootElement.GetProperty("error").GetString()); var data = res.RootElement.GetProperty("data").GetString() ?? throw new InvalidDataException("Can't get formatted query"); return data; } public async Task GetMetricsNames(CancellationToken token = default) { var response = await _client.GetAsync("/api/v1/label/__name__/values"); var json = await response.Content.ReadAsStringAsync() ?? throw new InvalidDataException("Responce is null"); var res = JsonSerializer.Deserialize(json, JsonSetializerSetup.Options) ?? throw new InvalidDataException("Can't convert responce to JsonDocument"); var status = res.RootElement.GetProperty("status").GetString() ?? throw new InvalidDataException("Can't get status"); if (!status.Equals("success", StringComparison.OrdinalIgnoreCase)) throw new InvalidDataException(res.RootElement.GetProperty("error").GetString()); var data = res.RootElement.GetProperty("data").EnumerateArray().Select(x => x.GetString()).Where( x => x != null).Cast().ToArray() ?? throw new InvalidDataException("Can't get formatted query"); return data; } }