2021-06-21 20:41:01 +01:00
|
|
|
"""
|
|
|
|
Present observational weather data to Prometheus
|
|
|
|
"""
|
|
|
|
|
|
|
|
import json
|
|
|
|
import time
|
|
|
|
import os
|
|
|
|
|
|
|
|
import requests
|
|
|
|
from flask import Flask, Response
|
|
|
|
|
|
|
|
app = Flask(__name__)
|
|
|
|
|
|
|
|
|
2021-06-22 16:09:56 +01:00
|
|
|
def fetch_weather_data(location: int, apikey: str) -> dict:
|
2021-06-21 20:41:01 +01:00
|
|
|
"""
|
|
|
|
Fetch current data from the Met Office for the provided postcode
|
|
|
|
"""
|
|
|
|
|
|
|
|
obs_data = requests.get(
|
2021-06-22 16:09:56 +01:00
|
|
|
f'http://api.weatherapi.com/v1/current.json?'
|
2021-06-21 20:41:01 +01:00
|
|
|
f'key={apikey}&'
|
2021-06-22 16:09:56 +01:00
|
|
|
f'q={location}&'
|
|
|
|
f'aqi=yes'
|
2021-06-21 20:41:01 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
return json.loads(obs_data.content)
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/metrics')
|
|
|
|
def metrics():
|
|
|
|
"""
|
|
|
|
Output Prometheus-style metrics
|
|
|
|
"""
|
2021-06-22 16:09:56 +01:00
|
|
|
apikey = os.environ.get('WEATHER_APIKEY')
|
|
|
|
location = os.environ.get('WEATHER_LOCATION')
|
2021-06-21 20:41:01 +01:00
|
|
|
|
2021-06-22 16:09:56 +01:00
|
|
|
latest_data = fetch_weather_data(location, apikey)['current']
|
2021-06-21 20:41:01 +01:00
|
|
|
|
|
|
|
ret_data = [
|
|
|
|
{
|
2021-06-21 20:55:43 +01:00
|
|
|
'key': 'sensor_weather_outdoor_temperature_celsius',
|
2021-06-21 20:41:01 +01:00
|
|
|
'labels': {
|
2021-06-22 16:09:56 +01:00
|
|
|
'location': location,
|
2021-06-21 20:41:01 +01:00
|
|
|
},
|
|
|
|
'type': 'gauge',
|
2021-06-22 16:09:56 +01:00
|
|
|
'value': float(latest_data['temp_c']),
|
2021-06-21 20:41:01 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
'key': 'sensor_weather_outdoor_humidity_percent',
|
|
|
|
'labels': {
|
2021-06-22 16:09:56 +01:00
|
|
|
'location': location,
|
2021-06-21 20:41:01 +01:00
|
|
|
},
|
|
|
|
'type': 'gauge',
|
2021-06-22 16:09:56 +01:00
|
|
|
'value': float(latest_data['humidity']),
|
2021-06-21 20:41:01 +01:00
|
|
|
},
|
2021-06-28 10:00:13 +01:00
|
|
|
{
|
|
|
|
'key': 'sensor_weather_outdoor_uv',
|
|
|
|
'labels': {
|
|
|
|
'location': location,
|
|
|
|
},
|
|
|
|
'type': 'gauge',
|
|
|
|
'value': float(latest_data['uv']),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
'key': 'sensor_weather_outdoor_cloud_percent',
|
|
|
|
'labels': {
|
|
|
|
'location': location,
|
|
|
|
},
|
|
|
|
'type': 'gauge',
|
|
|
|
'value': float(latest_data['cloud']),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
'key': 'sensor_weather_outdoor_precip',
|
|
|
|
'labels': {
|
|
|
|
'location': location,
|
|
|
|
},
|
|
|
|
'type': 'gauge',
|
|
|
|
'value': float(latest_data['precip_mm']),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
'key': 'sensor_weather_outdoor_wind_speed',
|
|
|
|
'labels': {
|
|
|
|
'location': location,
|
|
|
|
},
|
|
|
|
'type': 'gauge',
|
|
|
|
'value': float(latest_data['wind_kph']),
|
|
|
|
},
|
2021-07-01 15:16:57 +01:00
|
|
|
{
|
|
|
|
'key': 'sensor_weather_outdoor_wind_gust',
|
|
|
|
'labels': {
|
|
|
|
'location': location,
|
|
|
|
},
|
|
|
|
'type': 'gauge',
|
|
|
|
'value': float(latest_data['gust_kph']),
|
|
|
|
},
|
2021-06-28 10:00:13 +01:00
|
|
|
{
|
|
|
|
'key': 'sensor_weather_outdoor_wind_direction',
|
|
|
|
'labels': {
|
|
|
|
'location': location,
|
|
|
|
},
|
|
|
|
'type': 'gauge',
|
|
|
|
'value': float(latest_data['wind_degree']),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
'key': 'sensor_weather_outdoor_temp_feel_c',
|
|
|
|
'labels': {
|
|
|
|
'location': location,
|
|
|
|
},
|
|
|
|
'type': 'gauge',
|
|
|
|
'value': float(latest_data['feelslike_c']),
|
|
|
|
},
|
2021-07-01 15:16:57 +01:00
|
|
|
{
|
|
|
|
'key': 'sensor_weather_outdoor_pressure',
|
|
|
|
'labels': {
|
|
|
|
'location': location,
|
|
|
|
},
|
|
|
|
'type': 'gauge',
|
|
|
|
'value': float(latest_data['pressure_mb']),
|
|
|
|
},
|
2021-06-21 20:41:01 +01:00
|
|
|
]
|
|
|
|
|
2021-06-21 21:43:46 +01:00
|
|
|
ret_strs = list()
|
2021-06-21 20:41:01 +01:00
|
|
|
for item in ret_data:
|
2021-06-21 21:43:46 +01:00
|
|
|
ret_strs.append(f'# HELP {item["key"]} Weather metric')
|
|
|
|
ret_strs.append(f'# TYPE {item["key"]} {item["type"]}')
|
|
|
|
ret_strs.append(
|
|
|
|
item["key"]
|
|
|
|
+ '{'
|
|
|
|
+ " ".join([f'{key}="{val}"' for key, val in item["labels"].items()])
|
|
|
|
+ '} '
|
|
|
|
+ str(item["value"])
|
|
|
|
)
|
|
|
|
|
|
|
|
resp = Response('\n'.join(ret_strs))
|
2021-06-21 20:41:01 +01:00
|
|
|
resp.headers['Content-type'] = 'text/plain'
|
|
|
|
|
|
|
|
return resp
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
app.run(host='0.0.0.0')
|