1+ using System ;
2+ using System . Threading . Tasks ;
3+ using Prometheus . Client . Collectors ;
4+ using Microsoft . AspNetCore . Builder ;
5+
6+ namespace Prometheus . Client . AspNetCore
7+ {
8+ /// <summary>
9+ /// PrometheusExtensions
10+ /// </summary>
11+ public static class PrometheusExtensions
12+ {
13+ /// <summary>
14+ /// Add PrometheusServer request execution pipeline.
15+ /// </summary>
16+ public static IApplicationBuilder UsePrometheusServer ( this IApplicationBuilder app )
17+ {
18+ return UsePrometheusServer ( app , null ) ;
19+ }
20+
21+ /// <summary>
22+ /// Add PrometheusServer request execution pipeline.
23+ /// </summary>
24+ public static IApplicationBuilder UsePrometheusServer ( this IApplicationBuilder app , Action < PrometheusOptions > setupOptions )
25+ {
26+ var options = new PrometheusOptions ( ) ;
27+ setupOptions ? . Invoke ( options ) ;
28+
29+ if ( app == null )
30+ throw new ArgumentNullException ( nameof ( app ) ) ;
31+
32+ if ( options == null )
33+ throw new ArgumentNullException ( nameof ( options ) ) ;
34+
35+ if ( ! options . MapPath . StartsWith ( "/" ) )
36+ throw new ArgumentException ( $ "MapPath '{ options . MapPath } ' should start with '/'") ;
37+
38+ RegisterCollectors ( options ) ;
39+
40+ app . Map ( options . MapPath , coreapp =>
41+ {
42+ coreapp . Run ( async context =>
43+ {
44+ var req = context . Request ;
45+ var response = context . Response ;
46+
47+ req . Headers . TryGetValue ( "Accept" , out var acceptHeaders ) ;
48+ var contentType = ScrapeHandler . GetContentType ( acceptHeaders ) ;
49+
50+ response . ContentType = contentType ;
51+
52+ using ( var outputStream = response . Body )
53+ {
54+ var collected = options . CollectorRegistryInstance . CollectAll ( ) ;
55+ ScrapeHandler . ProcessScrapeRequest ( collected , contentType , outputStream ) ;
56+ }
57+
58+ await Task . FromResult ( 0 ) . ConfigureAwait ( false ) ;
59+ } ) ;
60+ } ) ;
61+
62+ return app ;
63+ }
64+
65+
66+ private static void RegisterCollectors ( PrometheusOptions options )
67+ {
68+ if ( options . UseDefaultCollectors )
69+ {
70+ var metricFactory = Metrics . DefaultFactory ;
71+ if ( options . CollectorRegistryInstance != CollectorRegistry . Instance )
72+ metricFactory = new MetricFactory ( options . CollectorRegistryInstance ) ;
73+
74+ options . Collectors . AddRange ( DefaultCollectors . Get ( metricFactory ) ) ;
75+ }
76+
77+ options . CollectorRegistryInstance . RegisterOnDemandCollectors ( options . Collectors ) ;
78+ }
79+ }
80+ }
0 commit comments