@@ -103,6 +103,13 @@ var (
103
103
exporterName = "exporter"
104
104
)
105
105
106
+ // ScrapResult is container structure for error handling
107
+ type ScrapeResult struct {
108
+ Err error
109
+ Metric Metric
110
+ ScrapeStart time.Time
111
+ }
112
+
106
113
func maskDsn (dsn string ) string {
107
114
parts := strings .Split (dsn , "@" )
108
115
if len (parts ) > 1 {
@@ -277,15 +284,33 @@ func (e *Exporter) scheduledScrape(tick *time.Time) {
277
284
func (e * Exporter ) scrape (ch chan <- prometheus.Metric , tick * time.Time ) {
278
285
e .totalScrapes .Inc ()
279
286
var err error
280
- var errmutex sync.Mutex
287
+ var scrapemutex sync.Mutex
288
+ errChan := make (chan ScrapeResult , len (e .metricsToScrape .Metric ))
281
289
282
290
defer func (begun time.Time ) {
291
+ // other error
283
292
e .duration .Set (time .Since (begun ).Seconds ())
284
293
if err == nil {
285
294
e .error .Set (0 )
286
295
} else {
287
296
e .error .Set (1 )
288
297
}
298
+
299
+ // scrape error
300
+ close (errChan )
301
+ for scrape := range errChan {
302
+ if scrape .Err != nil {
303
+ if shouldLogScrapeError (scrape .Err , scrape .Metric .IgnoreZeroResult ) {
304
+ level .Error (e .logger ).Log ("msg" , "Error scraping metric" ,
305
+ "Context" , scrape .Metric .Context ,
306
+ "MetricsDesc" , fmt .Sprint (scrape .Metric .MetricsDesc ),
307
+ "time" , time .Since (scrape .ScrapeStart ),
308
+ "error" , scrape .Err )
309
+ }
310
+ e .scrapeErrors .WithLabelValues (scrape .Metric .Context ).Inc ()
311
+ }
312
+ }
313
+
289
314
}(time .Now ())
290
315
291
316
if err = e .db .Ping (); err != nil {
@@ -355,20 +380,12 @@ func (e *Exporter) scrape(ch chan<- prometheus.Metric, tick *time.Time) {
355
380
}
356
381
357
382
scrapeStart := time .Now ()
358
- if err1 := e .ScrapeMetric (e .db , ch , metric , tick ); err1 != nil {
359
- errmutex .Lock ()
360
- {
361
- err = err1
362
- }
363
- errmutex .Unlock ()
364
- if shouldLogScrapeError (err , metric .IgnoreZeroResult ) {
365
- level .Error (e .logger ).Log ("msg" , "Error scraping metric" ,
366
- "Context" , metric .Context ,
367
- "MetricsDesc" , fmt .Sprint (metric .MetricsDesc ),
368
- "time" , time .Since (scrapeStart ),
369
- "error" , err )
370
- }
371
- e .scrapeErrors .WithLabelValues (metric .Context ).Inc ()
383
+ if err1 := func () error {
384
+ scrapemutex .Lock ()
385
+ defer scrapemutex .Unlock ()
386
+ return e .ScrapeMetric (e .db , ch , metric , tick )
387
+ }(); err1 != nil {
388
+ errChan <- ScrapeResult {Err : err1 , Metric : metric , ScrapeStart : scrapeStart }
372
389
} else {
373
390
level .Debug (e .logger ).Log ("msg" , "Successfully scraped metric" ,
374
391
"Context" , metric .Context ,
0 commit comments