package main import ( "encoding/json" "flag" "fmt" "io/ioutil" "log" "net/http" "strconv" "strings" "github.com/cabify/gotoprom" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/robfig/cron/v3" ) var addr = flag.String("listen-address", ":8080", "The address to listen on for HTTP requests.") type OntCovidData struct { Help string `json:"help"` Success bool `json:"success"` Result struct { Sort string `json:"sort"` IncludeTotal bool `json:"include_total"` ResourceID string `json:"resource_id"` Fields []struct { Type string `json:"type"` ID string `json:"id"` Info struct { Notes string `json:"notes"` TypeOverride string `json:"type_override"` Label string `json:"label"` } `json:"info,omitempty"` } `json:"fields"` RecordsFormat string `json:"records_format"` Records []struct { ID int `json:"_id"` ReportDate string `json:"report_date"` PreviousDayDosesAdministered string `json:"previous_day_doses_administered"` TotalDosesAdministered string `json:"total_doses_administered"` TotalDosesInFullyVaccinatedIndividuals string `json:"total_doses_in_fully_vaccinated_individuals"` TotalIndividualsFullyVaccinated string `json:"total_individuals_fully_vaccinated"` } `json:"records"` Limit int `json:"limit"` Links struct { Start string `json:"start"` Next string `json:"next"` } `json:"_links"` Total int `json:"total"` } `json:"result"` } var metrics struct { TotalDosesAdministered func() prometheus.Gauge `name:"total_doses_administered" help:"Total Doses Administered"` PreviousDayDosesAdministered func() prometheus.Gauge `name:"previous_day_doses_administered" help:"Previous Day Doses Administered"` DaysLeft func() prometheus.Gauge `name:"days_left" help:"Days Left"` } func init() { gotoprom.MustInit(&metrics, "ont_covid_data") } func updateMetrics() { data_url := "https://data.ontario.ca/api/3/action/datastore_search?sort=report_date+desc&limit=1&resource_id=8a89caa9-511c-4568-af89-7f2174b4378c" population := int64(11971129) resp, getErr := http.Get(data_url) if getErr != nil { log.Fatalln(getErr) } body, readErr := ioutil.ReadAll(resp.Body) if readErr != nil { log.Fatalln(readErr) } data := OntCovidData{} err := json.Unmarshal(body, &data) if err != nil { fmt.Println(err) } totalString := strings.Replace(data.Result.Records[0].TotalDosesAdministered, ",", "", -1) total, _ := strconv.ParseInt(totalString, 0, 64) prevDayString := strings.Replace(data.Result.Records[0].PreviousDayDosesAdministered, ",", "", -1) prevDay, _ := strconv.ParseInt(prevDayString, 0, 64) // reportDate := data.Result.Records[0].ReportDate days := (population - total) / prevDay metrics.TotalDosesAdministered().Set(float64(total)) metrics.PreviousDayDosesAdministered().Set(float64(prevDay)) metrics.DaysLeft().Set(float64(days)) } func main() { c := cron.New() c.AddFunc("@hourly", func() { updateMetrics() }) c.Start() updateMetrics() flag.Parse() http.Handle("/metrics", promhttp.Handler()) log.Fatal(http.ListenAndServe(*addr, nil)) }