metricator/internal/application/fetcher.go

83 lines
1.6 KiB
Go
Raw Normal View History

package application
import (
"net/http"
"time"
)
// Fetches data from remote endpoint, parses it and updates in storage.
func (a *Application) fetch() {
// Do not do anything if fetching is running.
// ToDo: maybe another approach?
a.fetchIsRunningMutex.RLock()
isFetching := a.fetchIsRunning
a.fetchIsRunningMutex.RUnlock()
if isFetching {
return
}
2020-11-29 19:36:04 +05:00
a.fetchIsRunningMutex.Lock()
a.fetchIsRunning = true
a.fetchIsRunningMutex.Unlock()
2020-12-23 16:28:57 +05:00
a.logger.Infoln("Fetching data for", a.name)
req, err := http.NewRequestWithContext(a.ctx, "GET", a.config.Endpoint, nil)
if err != nil {
2020-12-23 16:28:57 +05:00
a.logger.Infoln("Failed to create request for", a.name, "metrics:", err.Error())
return
}
for header, value := range a.config.Headers {
req.Header.Add(header, value)
}
resp, err := a.httpClient.Do(req)
if err != nil {
2020-12-23 16:28:57 +05:00
a.logger.Infoln("Failed to execute request for", a.name, "metrics:", err.Error())
return
}
defer resp.Body.Close()
data, err := a.parse(resp.Body)
if err != nil {
a.logger.Infoln("Failed to parse response body for", a.name, "metrics:", err.Error())
return
}
a.storage.Put(data)
a.fetchIsRunningMutex.Lock()
a.fetchIsRunning = false
a.fetchIsRunningMutex.Unlock()
}
// Configures and starts Prometheus data fetching goroutine.
func (a *Application) startFetcher() {
fetchTicker := time.NewTicker(a.config.TimeBetweenRequests)
2020-11-29 05:52:52 +05:00
// nolint:exhaustivestruct
a.httpClient = &http.Client{
Timeout: time.Second * 5,
}
2020-12-23 16:28:57 +05:00
defer a.logger.Debugln("Fetcher for", a.name, "completed")
// First fetch should be executed ASAP.
a.fetch()
for {
select {
case <-a.ctx.Done():
return
case <-fetchTicker.C:
a.fetch()
}
}
}