119 lines
4.1 KiB
Python
119 lines
4.1 KiB
Python
import configparser
|
|
import json
|
|
import logging
|
|
import os
|
|
import sys
|
|
from http.server import HTTPServer, BaseHTTPRequestHandler
|
|
from time import sleep, time
|
|
|
|
import requests
|
|
from pytz import utc
|
|
from apscheduler.schedulers.background import BackgroundScheduler
|
|
|
|
|
|
# try to read configfile
|
|
config = configparser.ConfigParser()
|
|
try:
|
|
config.read('pagespeed.conf')
|
|
exporter_config = config['EXPORTER']
|
|
except:
|
|
exporter_config = {'EXPORTER': {}}
|
|
|
|
|
|
# try to get config from ENV
|
|
TEST_URI = os.environ.get('PAGESPEED_TEST_URI', exporter_config.get('TEST_URI'))
|
|
API_KEY = os.environ.get('PAGESPEED_API_KEY', exporter_config.get('API_KEY'))
|
|
BIND_IP = os.environ.get('PAGESPEED_HOST', exporter_config.get('BIND_IP', ''))
|
|
BIND_PORT = os.environ.get('PAGESPEED_PORT', exporter_config.get('BIND_PORT', 9113))
|
|
FETCH_INTERVAL = os.environ.get('PAGESPEED_FETCH_INTERVAL', exporter_config.get('FETCH_INTERVAL', 300))
|
|
|
|
|
|
# input validation :)
|
|
if not TEST_URI:
|
|
logger.error('TEST_URI needs to be defined either in config file or in ENV.')
|
|
sys.exit(1)
|
|
if not API_KEY:
|
|
logger.error('API_KEY needs to be definer either in config file or in ENV.')
|
|
sys.exit(1)
|
|
try:
|
|
FETCH_INTERVAL = int(FETCH_INTERVAL)
|
|
BIND_PORT = int(BIND_PORT)
|
|
except:
|
|
logger.exception('Value error in FETCH_INTERVAL or BIND_PORT.')
|
|
sys.exit(1)
|
|
|
|
|
|
metric_data = ""
|
|
error_instances = 0
|
|
logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s')
|
|
logger = logging.getLogger(__name__)
|
|
logger.setLevel(logging.DEBUG)
|
|
|
|
|
|
def fetch_pagespeed():
|
|
global metric_data
|
|
global error_instances
|
|
|
|
logger.debug('fetching pagespeed')
|
|
|
|
try:
|
|
req = requests.get('https://www.googleapis.com/pagespeedonline/v2/'
|
|
'runPagespeed?url={url}&key={key}&'
|
|
'prettyprint=false'.format(
|
|
url=TEST_URI,
|
|
key=API_KEY
|
|
))
|
|
result = req.json()
|
|
except:
|
|
logger.exception('error while doing request')
|
|
error_instances += 1
|
|
|
|
translation_table = {
|
|
'speed_score': result['ruleGroups']['SPEED']['score'],
|
|
'stats_resources_total': result['pageStats']['numberResources'],
|
|
'stats_hosts_total': result['pageStats']['numberHosts'],
|
|
'stats_request_bytes': result['pageStats']['totalRequestBytes'],
|
|
'stats_static_resources_total': result['pageStats']['numberStaticResources'],
|
|
'stats_html_resources_bytes': result['pageStats']['htmlResponseBytes'],
|
|
'stats_image_resources_bytes': result['pageStats']['imageResponseBytes'],
|
|
'stats_javascript_resources_bytes': result['pageStats']['javascriptResponseBytes'],
|
|
'stats_javascript_resources_total': result['pageStats']['numberJsResources'],
|
|
'stats_css_resources_bytes': result['pageStats']['cssResponseBytes'],
|
|
'stats_css_resources_total': result['pageStats']['numberCssResources'],
|
|
'stats_other_resources_bytes': result['pageStats']['otherResponseBytes'],
|
|
}
|
|
metric_data = ""
|
|
for metric, value in translation_table.items():
|
|
metric_data += 'pagespeed_{metric}{{site="{job}"}}' \
|
|
' {metric_value}\n'.format(
|
|
metric=metric,
|
|
job=result['id'],
|
|
metric_value=value,
|
|
)
|
|
metric_data += 'pagespeed_last_update {}\n'.format(time())
|
|
metric_data += 'pagespeed_metric_errors_total {}\n'.format(error_instances)
|
|
metric_data += 'up 1\n'
|
|
logger.debug('fetched pagespeed')
|
|
|
|
|
|
class AllGetHTTPRequestHandler(BaseHTTPRequestHandler):
|
|
def do_GET(s):
|
|
s.send_response(200)
|
|
s.send_header("Content-Type", "text/plain")
|
|
s.end_headers()
|
|
s.wfile.write(metric_data.encode('utf-8'))
|
|
|
|
scheduler = BackgroundScheduler(timezone=utc)
|
|
scheduler.add_job(fetch_pagespeed, 'interval', seconds=FETCH_INTERVAL, max_instances=1)
|
|
scheduler.start()
|
|
|
|
|
|
if __name__=='__main__':
|
|
logger.info('starting pagespeed_exporter')
|
|
if metric_data == '':
|
|
fetch_pagespeed()
|
|
server_address = (BIND_IP, BIND_PORT)
|
|
httpd = HTTPServer(server_address, AllGetHTTPRequestHandler)
|
|
logger.info('binding to {}'.format(server_address))
|
|
httpd.serve_forever()
|