prometheus-net
172 строки · 6.9 Кб
1using Prometheus;
2using System;
3using System.Diagnostics;
4using System.Net.Http;
5using System.Threading;
6using System.Threading.Tasks;
7
8#if NET6_0_OR_GREATER
9using System.Diagnostics.Metrics;
10#endif
11
12namespace tester
13{
14internal class Program
15{
16private static void Main()
17{
18// Uncomment this to suppress the default sample metrics.
19//Metrics.SuppressDefaultMetrics();
20
21// Replace the first line with an appropriate type of tester to run different manual tests.
22//var tester = new MetricPusherTester();
23//var tester = new KestrelMetricServerTester();
24var tester = new AspNetCoreMiddlewareTester();
25//var tester = new GrpcMiddlewareTester();
26//var tester = new MetricServerTester();
27
28// For testing Kestrel metric server with HTTPS, you need at least a self-signed certificate (one included here)
29// and the matching domain pointed to 127.0.0.1 (e.g. hardcoded in the PCs hosts file) and you also need to
30// import this certificate into your Trusted Root Certification Authorities certificate store to trust it.
31//var certificate = new X509Certificate2("prometheus-net.test.pfx", "prometheus-net.test");
32//var tester = new KestrelMetricServerTester("prometheus-net.test", certificate);
33
34tester.OnStart();
35
36var metricServer = tester.InitializeMetricServer();
37metricServer?.Start();
38
39var counter = Metrics.CreateCounter("myCounter", "help text", new[] { "method", "endpoint" });
40counter.WithLabels("GET", "/").Inc();
41counter.WithLabels("POST", "/cancel").Inc();
42
43Metrics.CreateCounter("always_zero", "This counter is always zero but still needs to be present in the output!");
44
45var gauge = Metrics.CreateGauge("gauge", "help text");
46gauge.Inc(3.4);
47gauge.Dec(2.1);
48gauge.Set(5.3);
49
50// As the initial value is suppressed and a new one never assigned, this one never shows up in the export.
51Metrics.CreateGauge("should_not_show_up", "", new GaugeConfiguration
52{
53SuppressInitialValue = true
54});
55
56var hist = Metrics.CreateHistogram("myHistogram", "help text", new HistogramConfiguration
57{
58Buckets = new[] { 0, 0.2, 0.4, 0.6, 0.8, 0.9 }
59});
60hist.Observe(0.4);
61
62var timedHistogram = Metrics.CreateHistogram("myTimedHistogram", "help text", new HistogramConfiguration
63{
64Buckets = new[] { 0, 0.2, 0.4, 0.6, 0.8, 0.9 }
65});
66
67var latestGauge = Metrics.CreateGauge("latestGauge", "Reports the latest cycle time");
68
69var summary = Metrics.CreateSummary("mySummary", "help text");
70summary.Observe(5.3);
71
72// Example implementation of updating values before every collection.
73var collectionCount = Metrics.CreateCounter("beforecollect_example", "This counter is incremented before every data collection.");
74
75// Synchronous callbacks should be instantaneous, to avoid causing delays in the pipeline.
76Metrics.DefaultRegistry.AddBeforeCollectCallback(() => collectionCount.Inc());
77
78var googlePageBytes = Metrics.CreateCounter("beforecollect_async_example", "This counter is incremented before every data collection, but asynchronously.");
79
80// Callbacks can also be asynchronous. It is fine for these to take a bit more time.
81// For example, you can make an asynchronous HTTP request to a remote system in such a callback.
82var httpClient = new HttpClient();
83
84Metrics.DefaultRegistry.AddBeforeCollectCallback(async (cancel) =>
85{
86// Probe a remote system.
87var response = await httpClient.GetAsync("https://google.com", cancel);
88
89// Increase a counter by however many bytes we loaded.
90googlePageBytes.Inc(response.Content.Headers.ContentLength ?? 0);
91});
92
93// Uncomment this to test deliberately causing collections to fail. This should result in 503 responses.
94// With MetricPusherTester you might get a 1st push already before it fails but after that it should stop pushing.
95//Metrics.DefaultRegistry.AddBeforeCollectCallback(() => throw new ScrapeFailedException());
96
97#if NETCOREAPP
98var diagnosticSourceRegistration = DiagnosticSourceAdapter.StartListening();
99var eventCounterRegistration = EventCounterAdapter.StartListening();
100#endif
101
102#if NET6_0_OR_GREATER
103var meter = new Meter("sample.dotnet.meter", "1.2.3");
104var meterCounter = meter.CreateCounter<double>("sample_counter");
105var meterGauge = meter.CreateObservableGauge<byte>("sample_gauge", () => 92, "Buckets", "How much cheese is loaded");
106
107var meterRegistration = MeterAdapter.StartListening();
108#endif
109
110var cts = new CancellationTokenSource();
111
112var random = new Random();
113
114// Update metrics on a regular interval until told to stop.
115var updateInterval = TimeSpan.FromSeconds(0.5);
116var updateTask = Task.Factory.StartNew(async delegate
117{
118while (!cts.IsCancellationRequested)
119{
120using (latestGauge.NewTimer())
121using (timedHistogram.NewTimer())
122{
123var duration = Stopwatch.StartNew();
124
125
126counter.Inc();
127counter.Labels("GET", "/").Inc(2);
128gauge.Set(random.NextDouble() + 2);
129hist.Observe(random.NextDouble());
130summary.Observe(random.NextDouble());
131
132#if NET6_0_OR_GREATER
133meterCounter.Add(1);
134#endif
135try
136{
137tester.OnTimeToObserveMetrics();
138}
139catch (Exception ex)
140{
141Console.Error.WriteLine(ex);
142}
143
144var sleepTime = updateInterval - duration.Elapsed;
145
146if (sleepTime > TimeSpan.Zero)
147await Task.Delay(sleepTime, cts.Token);
148}
149}
150}).Result;
151
152Console.WriteLine("Press enter to stop metricServer");
153Console.ReadLine();
154
155cts.Cancel();
156try
157{
158updateTask.GetAwaiter().GetResult();
159}
160catch (OperationCanceledException)
161{
162}
163
164metricServer?.StopAsync().GetAwaiter().GetResult();
165
166tester.OnEnd();
167
168Console.WriteLine("Press enter to stop tester");
169Console.ReadLine();
170}
171}
172}
173