Use a logger rather than print statements.
Unfortunately, bottle.py logs to stderr/stdout on its own.
This commit is contained in:
parent
2ceb141864
commit
dec4e98a0c
5 changed files with 48 additions and 27 deletions
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
with opener.open(config.url) as response:
|
||||
data = response.read().decode('utf-8')
|
||||
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():
|
||||
|
|
|
@ -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
|
||||
with open(filename, 'r') as f:
|
||||
json_config = json.loads(f.read())
|
||||
CONFIG = Config(json_config)
|
||||
JENV = jinja2.Environment()
|
||||
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():
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import sys
|
||||
import logging
|
||||
|
||||
import bottle
|
||||
|
||||
|
@ -11,17 +12,32 @@ from icalendar_timeseries_server.api import prometheus_api
|
|||
|
||||
|
||||
def main():
|
||||
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:])}"')
|
||||
exit(1)
|
||||
# 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:
|
||||
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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue