get logging more in order

This commit is contained in:
John Burwell 2023-04-28 21:50:12 -05:00
parent 993baa47a7
commit d03622e4bd
9 changed files with 89 additions and 59 deletions

View File

@ -16,8 +16,8 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
__all__ = ['config', 'console', __all__ = ['config', 'console', 'controller',
'controller', 'parser', 'pluginloader'] 'logger', 'parser', 'pluginloader']
__version__ = "0.3.0" __version__ = "0.3.0"

View File

@ -16,6 +16,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
import logging
import sys import sys
import rsbbs import rsbbs
@ -42,6 +43,10 @@ class Console():
# Input and output # Input and output
# #
def disconnect(self) -> None:
logging.info("caller disconnected")
exit(0)
def read_enter(self, prompt) -> None: def read_enter(self, prompt) -> None:
"""Wait for the user to press enter. """Wait for the user to press enter.
""" """

72
rsbbs/logger.py Normal file
View File

@ -0,0 +1,72 @@
#!/usr/bin/env python
#
# Really Simple BBS - a really simple BBS for ax.25 packet radio.
# Copyright (C) 2023 John Burwell <john@atatdotdot.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import datetime
import logging
import logging.handlers
import os
import platformdirs
class RSLogger(logging.Logger):
def __init__(self, config):
super().__init__(name=config.app_name)
self.config = config
self.name = config.app_name
self.caller = config.calling_station
if self.config.args.debug:
self.log_level = logging.DEBUG
else:
self.log_level = getattr(logging,
self.config.args.log_level.upper())
self.init_logger()
def init_logger(self):
logger = logging.getLogger()
logger.setLevel(self.level)
# Remove the default StreamHandler that logs to the console
for handler in logger.handlers:
if isinstance(handler, logging.StreamHandler):
logger.removeHandler(handler)
# Log to a file in the system user log directory
log_dir = platformdirs.user_log_dir(appname=self.name,
ensure_exists=True)
log_filepath = os.path.join(log_dir, 'activity.log')
handler = logging.FileHandler(filename=log_filepath)
# Add the calling station to the log messages
handler.setFormatter(RSFormatter(self.caller))
# Add the handler!
logger.addHandler(handler)
class RSFormatter(logging.Formatter):
def __init__(self, var):
super().__init__()
self.var = var
def format(self, record):
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
record.msg = f"{now} {record.levelname} {self.var} {record.msg}"
return super().format(record)

View File

@ -1,31 +0,0 @@
#!/usr/bin/env python
#
# Really Simple BBS - a really simple BBS for ax.25 packet radio.
# Copyright (C) 2023 John Burwell <john@atatdotdot.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import datetime
import logging
class Formatter(logging.Formatter):
def __init__(self, var):
super().__init__()
self.var = var
def format(self, record):
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
record.msg = f"{now} {record.levelname} {self.var} {record.msg}"
return super().format(record)

View File

@ -40,4 +40,4 @@ class Plugin():
"""Disconnect and exit.""" """Disconnect and exit."""
self.api.write_output("Bye!") self.api.write_output("Bye!")
logging.info(f"{__name__} exiting") logging.info(f"{__name__} exiting")
exit(0) self.api.disconnect()

View File

@ -28,7 +28,7 @@ class Plugin():
def __init__(self, api: Console) -> None: def __init__(self, api: Console) -> None:
self.api = api self.api = api
self.init_parser(api.parser) self.init_parser(api.parser)
logging.info("plugin {__name__} loaded") logging.info(f"plugin {__name__} loaded")
def init_parser(self, parser: Parser) -> None: def init_parser(self, parser: Parser) -> None:
subparser = parser.subparsers.add_parser( subparser = parser.subparsers.add_parser(

View File

@ -29,7 +29,7 @@ class Plugin():
def __init__(self, api: Console) -> None: def __init__(self, api: Console) -> None:
self.api = api self.api = api
self.init_parser(api.parser) self.init_parser(api.parser)
logging.info("plugin {__name__} loaded") logging.info(f"plugin {__name__} loaded")
def init_parser(self, parser: Parser) -> None: def init_parser(self, parser: Parser) -> None:
subparser = parser.subparsers.add_parser( subparser = parser.subparsers.add_parser(

View File

@ -29,7 +29,7 @@ class Plugin():
def __init__(self, api: Console) -> None: def __init__(self, api: Console) -> None:
self.api = api self.api = api
self.init_parser(api.parser) self.init_parser(api.parser)
logging.info("plugin {__name__} loaded") logging.info(f"plugin {__name__} loaded")
def init_parser(self, parser: Parser) -> None: def init_parser(self, parser: Parser) -> None:
subparser = parser.subparsers.add_parser( subparser = parser.subparsers.add_parser(

View File

@ -24,7 +24,7 @@ from rsbbs import __version__
from rsbbs.config import Config from rsbbs.config import Config
from rsbbs.console import Console from rsbbs.console import Console
from rsbbs.controller import Controller from rsbbs.controller import Controller
from rsbbs.logging import Formatter from rsbbs.logger import RSLogger
def parse_args(): def parse_args():
@ -51,10 +51,10 @@ def parse_args():
group = argv_parser.add_mutually_exclusive_group(required=True) group = argv_parser.add_mutually_exclusive_group(required=True)
# Log level: # Log level:
group.add_argument( argv_parser.add_argument(
'--log-level', '--log-level',
action='store', action='store',
default='ERROR', default='INFO',
dest='log_level', dest='log_level',
help="Logging level") help="Logging level")
@ -90,28 +90,14 @@ def main():
# Grab the invocation arguments # Grab the invocation arguments
args = parse_args() args = parse_args()
# Start logging
if args.debug:
log_level = logging.DEBUG
else:
log_level = getattr(logging, args.log_level.upper())
logging.basicConfig(format='%(asctime)s %(message)s',
level=log_level)
logging.info(f"{__name__} started")
# Load configuration # Load configuration
config = Config( config = Config(
app_name='rsbbs', app_name='rsbbs',
args=args) args=args)
# Add the calling station to the logs # Start logging
logger = logging.getLogger() logger = RSLogger(config)
handler = logging.StreamHandler() logging.info(f"caller connected")
handler.setFormatter(Formatter(config.calling_station))
logger.addHandler(handler)
logger.info("connected")
# Init the controller # Init the controller
controller = Controller(config) controller = Controller(config)
@ -122,8 +108,6 @@ def main():
# Start the app # Start the app
console.run() console.run()
logging.info(f"{__name__} exiting")
if __name__ == "__main__": if __name__ == "__main__":
main() main()