add some logging support

This commit is contained in:
John Burwell 2023-04-27 22:00:18 -05:00
parent 60293152d6
commit 993baa47a7
13 changed files with 106 additions and 26 deletions

View File

@ -19,7 +19,7 @@
__all__ = ['config', 'console', __all__ = ['config', 'console',
'controller', 'parser', 'pluginloader'] 'controller', 'parser', 'pluginloader']
__version__ = "0.2.0" __version__ = "0.3.0"
# from .config import Config # from .config import Config
# from .console import Console # from .console import Console

31
rsbbs/logging.py Normal file
View File

@ -0,0 +1,31 @@
#!/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

@ -16,6 +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/>.
import logging
from rsbbs.console import Console from rsbbs.console import Console
from rsbbs.parser import Parser from rsbbs.parser import Parser
@ -25,8 +27,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)
if api.config.debug: logging.info(f"Plugin {__name__} loaded")
print(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(
@ -38,4 +39,5 @@ class Plugin():
def run(self, args) -> None: def run(self, args) -> None:
"""Disconnect and exit.""" """Disconnect and exit."""
self.api.write_output("Bye!") self.api.write_output("Bye!")
logging.info(f"{__name__} exiting")
exit(0) exit(0)

View File

@ -16,6 +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/>.
import logging
import sqlalchemy import sqlalchemy
import sqlalchemy.exc import sqlalchemy.exc
@ -29,8 +31,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)
if api.config.debug: logging.info(f"plugin {__name__} loaded")
print(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(
@ -48,10 +49,11 @@ class Plugin():
session.delete(message) session.delete(message)
session.commit() session.commit()
self.api.write_output(f"Deleted message #{number}") self.api.write_output(f"Deleted message #{number}")
logging.info(f"deleted message {number}")
except sqlalchemy.exc.NoResultFound: except sqlalchemy.exc.NoResultFound:
self.api.write_output(f"Message not found.") self.api.write_output(f"Message not found.")
except Exception as e: except Exception as e:
print(e) logging.error(e)
def run(self, args) -> None: def run(self, args) -> None:
"""Delete a message. """Delete a message.

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 sqlalchemy import sqlalchemy
from rsbbs.console import Console from rsbbs.console import Console
@ -28,8 +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)
if api.config.debug: logging.info(f"plugin {__name__} loaded")
print(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(
@ -52,6 +52,7 @@ class Plugin():
count = len(messages) count = len(messages)
if count > 0: if count > 0:
self.api.write_output(f"Deleted {count} messages") self.api.write_output(f"Deleted {count} messages")
logging.info(f"deleted {count} messages")
else: else:
self.api.write_output(f"No messages to delete.") self.api.write_output(f"No messages to delete.")
except Exception as e: except Exception as e:

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 subprocess import subprocess
from rsbbs.console import Console from rsbbs.console import Console
@ -27,8 +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)
if api.config.debug: logging.info("plugin {__name__} loaded")
print(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(
@ -45,6 +45,7 @@ class Plugin():
try: try:
result = subprocess.run(['mheard'], capture_output=True, text=True) result = subprocess.run(['mheard'], capture_output=True, text=True)
self.api.write_output(result.stdout) self.api.write_output(result.stdout)
logging.info("queried heard log")
except FileNotFoundError: except FileNotFoundError:
self.api.write_output(f"mheard utility not found.") self.api.write_output(f"mheard utility not found.")
except Exception as e: except Exception as e:

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 sqlalchemy import sqlalchemy
from rsbbs.console import Console from rsbbs.console import Console
@ -28,8 +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)
if api.config.debug: logging.info("plugin {__name__} loaded")
print(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(
@ -52,6 +52,7 @@ class Plugin():
result = session.execute( result = session.execute(
statement, statement,
execution_options={"prebuffer_rows": True}) execution_options={"prebuffer_rows": True})
logging.info("list messages")
except Exception: except Exception:
raise raise
return result return result

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 sqlalchemy import sqlalchemy
from rsbbs.console import Console from rsbbs.console import Console
@ -28,8 +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)
if api.config.debug: logging.info("plugin {__name__} loaded")
print(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(
@ -46,6 +46,7 @@ class Plugin():
result = session.execute( result = session.execute(
statement, statement,
execution_options={"prebuffer_rows": True}) execution_options={"prebuffer_rows": True})
logging.info("list my messages")
return result return result
except Exception: except Exception:
raise raise

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 sqlalchemy import sqlalchemy
import sqlalchemy.exc import sqlalchemy.exc
@ -29,8 +30,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)
if api.config.debug: logging.info(f"plugin {__name__} loaded")
print(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(
@ -47,10 +47,11 @@ class Plugin():
Message.id == number) Message.id == number)
result = session.execute(statement).one() result = session.execute(statement).one()
self.api.print_message(result) self.api.print_message(result)
logging.info(f"read message")
except sqlalchemy.exc.NoResultFound: except sqlalchemy.exc.NoResultFound:
self.api.write_output(f"Message not found.") self.api.write_output(f"Message not found.")
except Exception as e: except Exception as e:
print(e) logging.error(e)
def run(self, args) -> None: def run(self, args) -> None:
"""Read a message. """Read a message.

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 sqlalchemy import sqlalchemy
from rsbbs.console import Console from rsbbs.console import Console
@ -28,8 +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)
if api.config.debug: logging.info(f"plugin {__name__} loaded")
print(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(
@ -46,6 +46,7 @@ class Plugin():
result = session.execute( result = session.execute(
statement, statement,
execution_options={"prebuffer_rows": True}) execution_options={"prebuffer_rows": True})
logging.info(f"read message")
return result return result
except Exception: except Exception:
raise raise

View File

@ -16,6 +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/>.
import logging
from rsbbs.console import Console from rsbbs.console import Console
from rsbbs.models import Message from rsbbs.models import Message
from rsbbs.parser import Parser from rsbbs.parser import Parser
@ -26,8 +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)
if api.config.debug: logging.info(f"plugin {__name__} loaded")
print(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(
@ -50,7 +51,9 @@ class Plugin():
is_private=is_private is_private=is_private
)) ))
session.commit() session.commit()
except Exception: logging.info(f"sent message to {args.callsign.upper()}")
except Exception as e:
logging.error(f"error sending message: {e}")
session.rollback() session.rollback()
raise raise

View File

@ -16,6 +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/>.
import logging
from rsbbs.console import Console from rsbbs.console import Console
from rsbbs.models import Message from rsbbs.models import Message
from rsbbs.parser import Parser from rsbbs.parser import Parser
@ -26,8 +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)
if api.config.debug: logging.info(f"plugin {__name__} loaded")
print(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(
@ -50,7 +51,9 @@ class Plugin():
is_private=is_private is_private=is_private
)) ))
session.commit() session.commit()
except Exception: logging.info(f"sent message to {args.callsign.upper()}")
except Exception as e:
logging.error(f"error sending message: {e}")
session.rollback() session.rollback()
raise raise

View File

@ -17,12 +17,14 @@
# 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 argparse import argparse
import logging
import sys import sys
from rsbbs import __version__ 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
def parse_args(): def parse_args():
@ -48,6 +50,14 @@ def parse_args():
group = argv_parser.add_mutually_exclusive_group(required=True) group = argv_parser.add_mutually_exclusive_group(required=True)
# Log level:
group.add_argument(
'--log-level',
action='store',
default='ERROR',
dest='log_level',
help="Logging level")
# Show config option: # Show config option:
group.add_argument( group.add_argument(
'--show-config', '--show-config',
@ -77,10 +87,31 @@ def parse_args():
def main(): def main():
# Grab the invocation arguments
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=parse_args()) args=args)
# Add the calling station to the logs
logger = logging.getLogger()
handler = logging.StreamHandler()
handler.setFormatter(Formatter(config.calling_station))
logger.addHandler(handler)
logger.info("connected")
# Init the controller # Init the controller
controller = Controller(config) controller = Controller(config)
@ -91,6 +122,8 @@ 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()