Skip to content

Make push method configurable #305

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 24 additions & 14 deletions Prometheus.NetStandard/MetricPusher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,19 @@ namespace Prometheus
public class MetricPusher : MetricHandler
{
private readonly TimeSpan _pushInterval;
private readonly HttpMethod _method;
private readonly Uri _targetUrl;
private readonly Func<HttpClient> _httpClientProvider;

public MetricPusher(string endpoint, string job, string? instance = null, long intervalMilliseconds = 1000, IEnumerable<Tuple<string, string>>? additionalLabels = null, CollectorRegistry? registry = null) : this(new MetricPusherOptions
public MetricPusher(string endpoint, string job, string? instance = null, long intervalMilliseconds = 1000, IEnumerable<Tuple<string, string>>? additionalLabels = null, CollectorRegistry? registry = null, bool pushReplace = false) : this(new MetricPusherOptions
{
Endpoint = endpoint,
Job = job,
Instance = instance,
IntervalMilliseconds = intervalMilliseconds,
AdditionalLabels = additionalLabels,
Registry = registry
Registry = registry,
PushReplace = pushReplace,
})
{
}
Expand Down Expand Up @@ -65,6 +67,8 @@ public MetricPusher(MetricPusherOptions options) : base(options.Registry)

_pushInterval = TimeSpan.FromMilliseconds(options.IntervalMilliseconds);
_onError = options.OnError;

_method = options.PushReplace ? HttpMethod.Put : HttpMethod.Post;
}

private static readonly MediaTypeHeaderValue ContentTypeHeaderValue = new MediaTypeHeaderValue(PrometheusConstants.ExporterContentTypeMinimal);
Expand All @@ -88,19 +92,25 @@ protected override Task StartServer(CancellationToken cancel)
{
var httpClient = _httpClientProvider();

// We use a copy-pasted implementation of PushStreamContent here to avoid taking a dependency on the old ASP.NET Web API where it lives.
var response = await httpClient.PostAsync(_targetUrl, new PushStreamContentInternal(async (stream, content, context) =>
var request = new HttpRequestMessage
{
try
{
// Do not pass CT because we only want to cancel after pushing, so a flush is always performed.
await _registry.CollectAndExportAsTextAsync(stream, default);
}
finally
{
stream.Close();
}
}, ContentTypeHeaderValue));
Method = _method,
RequestUri = _targetUrl,
// We use a copy-pasted implementation of PushStreamContent here to avoid taking a dependency on the old ASP.NET Web API where it lives.
Content = new PushStreamContentInternal(async (stream, content, context) => {
try
{
// Do not pass CT because we only want to cancel after pushing, so a flush is always performed.
await _registry.CollectAndExportAsTextAsync(stream, default);
}
finally
{
stream.Close();
}
}, ContentTypeHeaderValue),
};

var response = await httpClient.SendAsync(request);

// If anything goes wrong, we want to get at least an entry in the trace log.
response.EnsureSuccessStatusCode();
Expand Down
9 changes: 9 additions & 0 deletions Prometheus.NetStandard/MetricPusherOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,14 @@ public sealed class MetricPusherOptions
/// If null, a singleton HttpClient will be used.
/// </summary>
public Func<HttpClient>? HttpClientProvider { get; set; }

/// <summary>
/// If true, replace the metrics in the group (identified by Job, Instance, AdditionalLabels).
///
/// Replace means a HTTP PUT request will be made, otherwise a HTTP POST request will be made (which means add metrics to the group, if it already exists).
///
/// Note: Other implementations of the pushgateway client default to replace, however to preserve backwards compatibility this implementation defaults to add.
/// </summary>
public bool PushReplace { get; set; } = false;
}
}