@@ -103,6 +103,13 @@ var (
103103 exporterName = "exporter"
104104)
105105
106+ // ScrapResult is container structure for error handling
107+ type ScrapeResult struct {
108+ Err error
109+ Metric Metric
110+ ScrapeStart time.Time
111+ }
112+
106113func maskDsn (dsn string ) string {
107114 parts := strings .Split (dsn , "@" )
108115 if len (parts ) > 1 {
@@ -277,15 +284,33 @@ func (e *Exporter) scheduledScrape(tick *time.Time) {
277284func (e * Exporter ) scrape (ch chan <- prometheus.Metric , tick * time.Time ) {
278285 e .totalScrapes .Inc ()
279286 var err error
280- var errmutex sync.Mutex
287+ var scrapemutex sync.Mutex
288+ errChan := make (chan ScrapeResult , len (e .metricsToScrape .Metric ))
281289
282290 defer func (begun time.Time ) {
291+ // other error
283292 e .duration .Set (time .Since (begun ).Seconds ())
284293 if err == nil {
285294 e .error .Set (0 )
286295 } else {
287296 e .error .Set (1 )
288297 }
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+
289314 }(time .Now ())
290315
291316 if err = e .db .Ping (); err != nil {
@@ -355,20 +380,12 @@ func (e *Exporter) scrape(ch chan<- prometheus.Metric, tick *time.Time) {
355380 }
356381
357382 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 }
372389 } else {
373390 level .Debug (e .logger ).Log ("msg" , "Successfully scraped metric" ,
374391 "Context" , metric .Context ,
0 commit comments