Configuration parameter checks, simplified logging, a lot of refactoring and bug fixes.

This commit is contained in:
Johannes Findeisen 2022-09-07 02:10:08 +02:00
commit e921d36aa5
11 changed files with 85 additions and 53 deletions

7
AUTHORS Normal file
View file

@ -0,0 +1,7 @@
PRIMARY AUTHORS are and/or have been (alphabetic order):
* Findeisen, Johannes
Main Developer since the first code line.
github.com profile: <https://github.com/hanez/>
openhub.net profile: <https://www.openhub.net/accounts/hanez>
Homepage: <http://hanez.org/>

View file

@ -21,8 +21,9 @@
# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# TODO: CHECK ALL ERROR HANDLING!!!
# TODO: Refactor all logging and make it clean and consistent.
# TODO: become more verbose in each log level and log only to error when it really
# is an error else log to info and even add debug messages in DEBUG level
# is an error else log to info and even add debug messages in DEBUG level.
import argparse
import calendar
@ -36,10 +37,10 @@ import time
from uplink.configuration import Configuration
from uplink.uplink import Uplink
__version__ = '0.8.0'
__version__ = '0.8.1'
__author__ = 'Johannes Findeisen <you@hanez.org>'
logger = logging.getLogger(__name__)
logger = logging.getLogger('uplink')
def parse_args():
@ -88,14 +89,12 @@ def parse_args():
def main():
args = parse_args()
root_logger = logging.getLogger()
try:
with open(args.configuration_file, 'r', encoding='utf-8') as configuration_file:
configuration_data = configuration_file.read()
configuration = Configuration(json.loads(configuration_data))
except Exception as err:
logger.error(str('[uplink] configuration error! {0}'.format(err)))
logger.error(str('[uplink] configuration error: {0}'.format(err)))
sys.exit(1)
configuration.set_env_var('_internal_start_date', time.strftime('%Y-%m-%d %H:%M:%S',
@ -119,23 +118,23 @@ def main():
maxBytes=configuration.get_log_size(),
backupCount=configuration.get_log_count())
handler1.setFormatter(formatter1)
root_logger.addHandler(handler1)
logger.addHandler(handler1)
if args.stdout:
formatter2 = logging.Formatter('[%(asctime)s] [%(levelname)s] %(message)s')
handler2 = logging.StreamHandler(sys.stdout)
handler2.setFormatter(formatter2)
root_logger.addHandler(handler2)
logger.addHandler(handler2)
# errors will always show up even when no log_level is set!
root_logger.setLevel(logging.ERROR)
logger.setLevel(logging.ERROR)
log_level = configuration.get_log_level()
if log_level == "warning":
root_logger.setLevel(logging.WARNING)
logger.setLevel(logging.WARNING)
elif log_level == "verbose":
root_logger.setLevel(logging.INFO)
logger.setLevel(logging.INFO)
elif log_level == "debug":
root_logger.setLevel(logging.DEBUG)
logger.setLevel(logging.DEBUG)
if args.httpserver or configuration.get_httpserver():
configuration.set_httpserver(True)
@ -182,7 +181,7 @@ def main():
logger.info(str('[uplink] program terminated by user!'))
sys.exit(0)
else:
logger.error('uplink: no run mode selected; use --cron (-c), --daemon (-d) or '
logger.error('[uplink] no run mode selected; use --cron (-c), --daemon (-d) or '
'--foreground (-f) to run uplink. use --help for more information')

View file

@ -18,9 +18,12 @@
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import re
import socket
from logging import getLogger
logger = getLogger(__name__)
logger = getLogger('uplink')
class Configuration:
@ -45,7 +48,7 @@ class Configuration:
self.__log_level = None
self.__log_size = 0
self.__notification_gammu = False
self.__notification_gammu_configuration = None
self.__notification_gammu_configuration_file = None
self.__notification_gammu_receiver = None
self.__notification_gammu_repeat = 30
self.__pid_file = '/tmp/uplink.pid'
@ -102,12 +105,12 @@ class Configuration:
if 'notification_gammu' in self.__configuration:
self.__notification_gammu = self.__configuration['notification_gammu']
if 'notification_gammu_configuration' in self.__configuration:
self.__notification_gammu_configuration = \
self.__configuration['notification_gammu_configuration']
elif self.__notification_gammu_configuration is None and \
if 'notification_gammu_configuration_file' in self.__configuration:
self.__notification_gammu_configuration_file = \
self.__configuration['notification_gammu_configuration_file']
elif self.__notification_gammu_configuration_file is None and \
'notification_gammu' in self.__configuration:
raise Exception('notification_gammu_configuration required!')
raise Exception('notification_gammu_configuration_file required!')
if 'notification_gammu_receiver' in self.__configuration:
self.__notification_gammu_receiver = \
@ -136,6 +139,26 @@ class Configuration:
if 'uplinks' in self.__configuration:
self.__uplinks = self.__configuration['uplinks']
for uplink in self.__uplinks:
if 'identifier' not in uplink:
raise Exception('missing at least one identifier in an uplink!')
if bool(re.match('^[a-z]+$', uplink['identifier'])) is False:
raise Exception('uplink identifier ' + uplink['identifier'] +
' must only contain lowercase letters!')
if 'ip' not in uplink:
raise Exception('missing ip for identifier ' + uplink['identifier'] + '!')
try:
socket.inet_aton(uplink['ip'])
except Exception as err:
raise Exception('invalid ip for identifier ' + uplink['identifier'] + '!')
if 'password' not in uplink:
raise Exception('missing password for identifier ' + uplink['identifier'] + '!')
if 'provider' not in uplink:
uplink['provider'] = 'Not configured'
if self.__uplinks is None:
raise Exception('uplinks required!')
@ -191,7 +214,7 @@ class Configuration:
def get_notification_gammu(self):
return self.__notification_gammu
def get_notification_gammu_configuration(self):
def get_notification_gammu_configuration_file(self):
return self.__notification_gammu_configuration
def get_notification_gammu_receiver(self):

View file

@ -20,7 +20,7 @@
from logging import getLogger
logger = getLogger(__name__)
logger = getLogger('uplink')
class CSV:

View file

@ -26,7 +26,7 @@ import time
from logging import getLogger
logger = getLogger(__name__)
logger = getLogger('uplink')
class Daemon:

View file

@ -22,7 +22,7 @@ import pymysql
from logging import getLogger
logger = getLogger(__name__)
logger = getLogger('uplink')
class Database:

View file

@ -26,7 +26,7 @@ import json
from logging import getLogger
logger = getLogger(__name__)
logger = getLogger('uplink')
class HTTPServer:

View file

@ -20,7 +20,7 @@
from logging import getLogger
logger = getLogger(__name__)
logger = getLogger('uplink')
class Model:

View file

@ -22,7 +22,7 @@
from logging import getLogger
logger = getLogger(__name__)
logger = getLogger('uplink')
class Notification:
@ -31,7 +31,7 @@ class Notification:
self.__configuration = configuration
#self.__state_machine = gammu.StateMachine()
#self.__state_machine.ReadConfig(
# self.__configuration.get_notification_gammu_configuration())
# self.__configuration.get_notification_gammu_configuration_file())
def send(self, status):
#message = {

View file

@ -24,7 +24,7 @@ import time
from logging import getLogger
logger = getLogger(__name__)
logger = getLogger('uplink')
class Speedtest:
@ -32,9 +32,9 @@ class Speedtest:
def __init__(self, configuration):
self.__configuration = configuration
self.speedtest_maximum_speed = None
self.speedtest_average_speed = None
self.speedtest_time_elapsed = None
self.__speedtest_maximum_speed = None
self.__speedtest_average_speed = None
self.__speedtest_time_elapsed = None
def run_speedtest(self):
while True:
@ -64,19 +64,22 @@ class Speedtest:
total_chunks += 1
total_mbps += mbps
self.speedtest_maximum_speed = maximum_speed
self.__configuration.set_env_var('_speedtest_maximum_speed_megabyte_per_second',
str(round(self.speedtest_maximum_speed)))
self.speedtest_average_speed = total_mbps / total_chunks
self.__speedtest_average_speed = total_mbps / total_chunks
self.__configuration.set_env_var('_speedtest_average_speed_megabyte_per_second',
str(round(self.speedtest_average_speed)))
str(round(self.__speedtest_average_speed)))
self.speedtest_time_elapsed = time.perf_counter() - start
self.__speedtest_maximum_speed = maximum_speed
self.__configuration.set_env_var('_speedtest_maximum_speed_megabyte_per_second',
str(round(self.__speedtest_maximum_speed)))
self.__speedtest_time_elapsed = time.perf_counter() - start
self.__configuration.set_env_var('_speedtest_time_elapsed',
str(self.speedtest_time_elapsed))
str(self.__speedtest_time_elapsed))
logger.info('speedtest average: ' + str(self.__speedtest_average_speed) +
', max: ' + str(self.__speedtest_maximum_speed) +
', time: ' + str(self.__speedtest_time_elapsed))
else:
logger.warning("could not calculate download speed!")
logger.warning('could not calculate download speed!')
time.sleep(self.__configuration.get_speedtest_interval())

View file

@ -23,6 +23,7 @@
# be optional too. Also reinvent SQLite as database backend.
import calendar
import logging
import socket
import time
@ -33,7 +34,7 @@ from uplink.daemon import Daemon
from uplink.database import Database
from uplink.model import Model
logger = getLogger(__name__)
logger = getLogger('uplink')
class Uplink(Daemon):
@ -86,7 +87,7 @@ class Uplink(Daemon):
self.__configuration.set_env_var('_uplink_' + uplink['identifier'] +
'_status', 'UP')
status = 'UP'
status = 'up'
else:
fail_count = self.__configuration.get_env_var('_uplink_' + uplink['identifier'] +
'_fail_count')
@ -111,7 +112,7 @@ class Uplink(Daemon):
self.__configuration.set_env_var('_uplink_' + uplink['identifier'] +
'_status', 'DOWN')
status = 'DOWN'
status = 'down'
if self.__configuration.get_notification_gammu() is True:
notification_gammu_repeat = self.__configuration.get_notification_gammu_repeat()
@ -126,8 +127,7 @@ class Uplink(Daemon):
notification = Notification(self.__configuration)
notification.send('[' + uplink['provider'] + '] ' + status)
logger.info(str(uplink['provider'] + ' (IP: ' + fritz_connection.external_ip + ') ' +
status))
logger.info(str(uplink['identifier'] + ': ' + status))
model = Model(self.__configuration)
model.set_date(date_formatted)
@ -155,21 +155,21 @@ class Uplink(Daemon):
database.write_log_to_db(model)
except Exception as err:
message = str('error when getting data from ' + uplink['ip'] + ': {0}')
message = str('error when getting data from ' + uplink['ip'] + '')
logger.error(str(message.format(err)))
def run(self):
if self.__configuration.get_http_server():
from uplink.httpserver import HTTPServer
s = HTTPServer(self.__configuration)
st = Thread(target=s.run_server, daemon=True)
st.start()
hs = HTTPServer(self.__configuration)
hst = Thread(target=hs.run_server, daemon=True)
hst.start()
if self.__configuration.get_speedtest():
from uplink.speedtest import Speedtest
se = Speedtest(self.__configuration)
ste = Thread(target=se.run_speedtest, daemon=True)
ste.start()
st = Speedtest(self.__configuration)
stt = Thread(target=st.run_speedtest, daemon=True)
stt.start()
while True:
for i in range(len(self.__configuration.get_uplinks())):