Skip to content

Instantly share code, notes, and snippets.

@vilaca
Last active December 2, 2021 00:25
Show Gist options
  • Select an option

  • Save vilaca/9f4421292d06c5a7da35b44bc22039b8 to your computer and use it in GitHub Desktop.

Select an option

Save vilaca/9f4421292d06c5a7da35b44bc22039b8 to your computer and use it in GitHub Desktop.
package main
import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"strings"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
const CmlOpendataUrl = "http://opendata-cml.qart.pt:8080/lastmeasurements"
const WrongMeasurementValue = -99
const PollingInterval = 5 * time.Minute
type SensorReading struct {
Id string
Value float64
}
var (
dict = map[string]map[string]string{
"CT0TMD": {
"Category": "Transit",
"Description": "Vehicles"},
"ME00HR": {
"Unit": "%",
"Category": "Weather",
"Description": "Relative humidity"},
"ME00PA": {
"Unit": "mbar",
"Category": "Weather",
"Description": "Atmospheric pressure"},
"ME00PP": {
"Unit": "mm",
"Category": "Weather",
"Description": "Precipitation"},
"ME00UV": {
"Category": "Weather",
"Description": "Ultra violet"},
"ME00VD": {
"Unit": "º",
"Category": "Weather",
"Description": "Wind direction"},
"ME00VI": {
"Unit": "km/h",
"Category": "Weather",
"Description": "Wind intensity"},
"METEMP": {
"Unit": "ºC",
"Category": "Weather",
"Description": "Temperature"},
"QA00CO": {
"Unit": "mg/m3",
"Unit": "mg/m3",
"Category": "Air quality",
"Description": "Carbon monoxide"},
"QA00NO": {
"Unit": "µg/m3",
"Category": "Air quality",
"Description": "Nitrogen oxide"},
"QA00O3": {
"Unit": "µg/m3",
"Category": "Air quality",
"Description": "Ozone"},
"QA0NO2": {
"Unit": "µg/m3",
"Category": "Air quality",
"Description": "Nitrogen dioxide"},
"QA0SO2": {
"Unit": "µg/m3",
"Category": "Air quality",
"Description": "Sulfur dioxide"},
"QAPM10": {
"Unit": "µg/m3",
"Category": "Air quality",
"Description": "Particles < 10 µm"},
"QAPM25": {
"Unit": "µg/m3",
"Category": "Air quality",
"Description": "Particles < 2.5 µm"},
"RULAEQ": {
"Unit": "dB(A)",
"Category": "Noise",
"Description": "Noise level"},
}
cache = map[string]prometheus.Gauge{}
runs = promauto.NewCounter(prometheus.CounterOpts{
Name: "lx_sensor_runs",
Help: "The total number of runs",
})
badRead = promauto.NewCounter(prometheus.CounterOpts{
Name: "lx_sensor_bad_reads",
Help: "The total number of bad reads",
})
executionTime = promauto.NewGauge(prometheus.GaugeOpts{
Name: "lx_sensor_pooling_execution_time",
Help: "Amount of time it took to pool and update metrics",
})
)
func getMeasurements() ([]SensorReading, error) {
resp, err := http.Get(CmlOpendataUrl)
if err != nil {
return nil, err
}
defer func(Body io.ReadCloser) {
err := Body.Close()
if err != nil {
log.Print(err)
}
}(resp.Body)
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return measurements, nil
}
func newGauge(key string) prometheus.Gauge {
keyType := key[0:6]
labels := dict[keyType]
cached := prometheus.NewGauge(prometheus.GaugeOpts{
Name: "lx_sensor_measurement_" + strings.ToLower(key),
ConstLabels: labels,
Help: "Sensor measurement",
})
cache[key] = cached
//fmt.Println(key, "->", measurement[i].Value)
prometheus.MustRegister(cached)
return cached
}
func recordMetrics() {
go func() {
for {
start := time.Now()
measurements, err := getMeasurements()
if err != nil {
log.Println(err)
continue
}
for i := 0; i < len(measurements); i++ {
if measurements[i].Value == WrongMeasurementValue {
badRead.Inc()
continue
}
key := measurements[i].Id
cached := cache[key]
if cached == nil {
cached = newGauge(key)
}
cached.Set(measurements[i].Value)
}
runs.Inc()
elapsed := time.Since(start)
executionTime.Set(float64(elapsed.Milliseconds()))
time.Sleep(PollingInterval)
}
}()
}
func main() {
recordMetrics()
http.Handle("/metrics", promhttp.Handler())
err := http.ListenAndServe(":9090", nil)
if err != nil {
fmt.Println(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment