@@ -14,6 +14,7 @@ internal sealed class PrometheusCollectionManager
1414 private readonly int scrapeResponseCacheDurationMilliseconds ;
1515 private readonly Func < Batch < Metric > , ExportResult > onCollectRef ;
1616 private readonly Dictionary < Metric , PrometheusMetric > metricsCache ;
17+ private readonly HashSet < string > scopes ;
1718 private int metricsCacheCount ;
1819 private byte [ ] buffer = new byte [ 85000 ] ; // encourage the object to live in LOH (large object heap)
1920 private int globalLockState ;
@@ -29,6 +30,7 @@ public PrometheusCollectionManager(PrometheusExporter exporter)
2930 this . scrapeResponseCacheDurationMilliseconds = this . exporter . ScrapeResponseCacheDurationMilliseconds ;
3031 this . onCollectRef = this . OnCollect ;
3132 this . metricsCache = new Dictionary < Metric , PrometheusMetric > ( ) ;
33+ this . scopes = new HashSet < string > ( ) ;
3234 }
3335
3436#if NET6_0_OR_GREATER
@@ -170,6 +172,37 @@ private ExportResult OnCollect(Batch<Metric> metrics)
170172
171173 try
172174 {
175+ this . scopes . Clear ( ) ;
176+
177+ foreach ( var metric in metrics )
178+ {
179+ if ( PrometheusSerializer . CanWriteMetric ( metric ) )
180+ {
181+ if ( this . scopes . Add ( metric . MeterName ) )
182+ {
183+ try
184+ {
185+ cursor = PrometheusSerializer . WriteScopeInfo ( this . buffer , cursor , metric . MeterName ) ;
186+
187+ break ;
188+ }
189+ catch ( IndexOutOfRangeException )
190+ {
191+ if ( ! this . IncreaseBufferSize ( ) )
192+ {
193+ // there are two cases we might run into the following condition:
194+ // 1. we have many metrics to be exported - in this case we probably want
195+ // to put some upper limit and allow the user to configure it.
196+ // 2. we got an IndexOutOfRangeException which was triggered by some other
197+ // code instead of the buffer[cursor++] - in this case we should give up
198+ // at certain point rather than allocating like crazy.
199+ throw ;
200+ }
201+ }
202+ }
203+ }
204+ }
205+
173206 foreach ( var metric in metrics )
174207 {
175208 if ( ! PrometheusSerializer . CanWriteMetric ( metric ) )
@@ -194,12 +227,6 @@ private ExportResult OnCollect(Batch<Metric> metrics)
194227 {
195228 if ( ! this . IncreaseBufferSize ( ) )
196229 {
197- // there are two cases we might run into the following condition:
198- // 1. we have many metrics to be exported - in this case we probably want
199- // to put some upper limit and allow the user to configure it.
200- // 2. we got an IndexOutOfRangeException which was triggered by some other
201- // code instead of the buffer[cursor++] - in this case we should give up
202- // at certain point rather than allocating like crazy.
203230 throw ;
204231 }
205232 }
0 commit comments