Use a logger rather than print statements.

Unfortunately, bottle.py logs to stderr/stdout on its own.
This commit is contained in:
s3lph 2019-09-01 23:13:24 +02:00
parent 2ceb141864
commit dec4e98a0c
5 changed files with 48 additions and 27 deletions

View file

@ -1,8 +1,7 @@
from typing import List
import json
from urllib.error import HTTPError
import traceback
import logging
import bottle
@ -26,7 +25,7 @@ def prometheus_api():
'error': str(e)
}
bottle.response.status = 400
traceback.print_exc()
logging.exception('Cannot parse PromQL query')
bottle.response.add_header('Content-Type', 'application/json')
return json.dumps(response)
@ -42,14 +41,6 @@ def prometheus_api():
'result': [e.serialize() for e in events]
}
}
except HTTPError as e:
response = {
'status': 'error',
'errorType': 'internal',
'error': str(e)
}
bottle.response.status = 500
traceback.print_exc()
except BaseException:
response = {
'status': 'error',
@ -57,7 +48,7 @@ def prometheus_api():
'error': 'An internal error occurred.'
}
bottle.response.status = 500
traceback.print_exc()
logging.exception('An internal error occurred')
bottle.response.add_header('Content-Type', 'application/json')
return json.dumps(response)

View file

@ -2,6 +2,7 @@ from typing import Dict, List, Iterable
import sys
import urllib.request
import logging
from datetime import datetime, date, timedelta
from threading import Lock, Timer
@ -54,8 +55,12 @@ def _scrape_calendar(name: str, config: CalendarConfig, start: datetime, end: da
events = []
opener: urllib.request.OpenerDirector = config.get_url_opener()
try:
with opener.open(config.url) as response:
data = response.read().decode('utf-8')
except BaseException:
logging.exception(f'An error occurred while scraping the calendar endpoint "{name}" ({config.url})')
return
calendar = cal.Calendar.from_ical(data)
for element in calendar.walk():

View file

@ -6,6 +6,7 @@ from datetime import timedelta
import ssl
import urllib.request
import sys
import logging
import pytz
import jinja2
@ -155,7 +156,7 @@ def _keycheck(key: str,
raise KeyError(f'Expected member "{key}" not found at path {path}')
value: Any = config[key]
if not isinstance(value, typ):
raise TypeError(f'Expected {typ}, not {type(value).__name__} for path {path}.{key}')
raise TypeError(f'Expected {typ.__name__}, not {type(value).__name__} for path {path}.{key}')
if valid_values is not None:
if value not in valid_values:
raise ValueError(f'Expected one of {", ".join(valid_values)} ({typ}), not {value} for path {path}.{key}')
@ -216,10 +217,17 @@ def get_jenv() -> jinja2.Environment:
def load_config(filename: str):
global CONFIG, JENV
try:
with open(filename, 'r') as f:
json_config = json.loads(f.read())
CONFIG = Config(json_config)
JENV = jinja2.Environment()
except json.JSONDecodeError as e:
logging.exception('Cannot parse config JSON')
raise e
except Exception as e:
logging.error(e)
raise e
def load_default_config():

View file

@ -1,4 +1,5 @@
import sys
import logging
import bottle
@ -11,17 +12,32 @@ from icalendar_timeseries_server.api import prometheus_api
def main():
# Set up logger
log_handler = logging.StreamHandler()
log_handler.setFormatter(logging.Formatter(
'%(asctime)s %(filename)s:%(lineno)d(%(funcName)s) [%(levelname)s]: %(message)s'))
logging.getLogger().addHandler(log_handler)
# Load configuration
config = get_config()
try:
if len(sys.argv) == 1:
load_default_config()
elif len(sys.argv) == 2:
load_config(sys.argv[1])
else:
print(f'Can only read one config file, got "{" ".join(sys.argv[1:])}"')
logging.log(logging.FATAL, f'Can only read one config file, got "{" ".join(sys.argv[1:])}"')
exit(1)
# Re-fetch config after parsing
config = get_config()
except:
logging.fatal('Could not parse configuration file')
exit(1)
# Schedule calendar scraping in the background
for calname in config.calendars.keys():
start_scrape_calendar(calname, config.calendars[calname])
# Start the Bottle HTTP server
bottle.run(host=config.addr, port=get_config().port)

View file

@ -1,6 +1,7 @@
from typing import Dict
import re
import logging
LABEL_MATCH_OPERATORS = [
'=',
@ -64,7 +65,7 @@ class MetricQuery:
self.__parse(q)
def __parse(self, q: str):
print(q)
logging.debug(f'Parsing PromQL query string: {q}')
# globalstate:
# 0 = parsing metric name
# 1 = parsing filters