From 34d2c31d90269ddcd5341a669eb6051a91801dbb Mon Sep 17 00:00:00 2001 From: Hemna Date: Wed, 31 Mar 2021 10:49:49 -0400 Subject: [PATCH] Added log config for flask and lnav config file This patch adds the aprsd-lnav.json formatting file. This is useful when you want to tail the logfile with the lnav log tailing app. http://lnav.org/ To install the aprsd-lnav.json formatter 1) install lnav 2) lnav -i aprsd-lnav.json 3) lnav -C -- just to test it out The next time you launch aprsd do it with this aprsd server --loglevel DEBUG | lnav This patch also updates the logging output from the flask web service to 1) disable flask web url logging and 2) use the same output format as the rest of the app. --- aprsd-lnav.json | 39 +++++++++++++++++++++++++++++++++++++++ aprsd/flask.py | 41 +++++++++++++++++++++++++++++++++++++++-- aprsd/main.py | 11 ++--------- aprsd/stats.py | 1 + aprsd/utils.py | 12 +++++++++++- 5 files changed, 92 insertions(+), 12 deletions(-) create mode 100644 aprsd-lnav.json diff --git a/aprsd-lnav.json b/aprsd-lnav.json new file mode 100644 index 0000000..de0d4a9 --- /dev/null +++ b/aprsd-lnav.json @@ -0,0 +1,39 @@ +{ + "aprsd" : { + "title" : "APRSD APRS-IS server log format", + "description" : "Log formats used by ARPRSD server", + "url" : "http://github.com/craigerl/aprsd", + "regex" : { + "std" : { + "pattern" : "^\\[(?\\d{2}\\/\\d{2}\\/\\d{4} \\d{2}:\\d{2}:\\d{2} ([AaPp][Mm]))\\] \\[(?\\w+\\s*)\\] \\[(?\\w+\\s*)\\] (?([^-]*)-*)\\s\\[(?([^:]*))\\:(?\\d+)\\]" + } + }, + "level-field" : "alert_level", + "level" : { + "info" : "INFO", + "error" : "ERROR", + "warning" : "WARN", + "debug" : "DEBUG", + "fatal" : "FATAL", + "info" : "UNKNOWN" + }, + "value" : { + "alert_level": { "kind" : "string", "identifier" : true }, + "thread": { "kind" : "string", "identifier" : true }, + "body" : { "kind" : "string" }, + "file" : { "kind" : "string" } + }, + "timestamp-field" : "timestamp", + "timestamp-format" : [ + "%m/%d/%Y %I:%M:%S %p" + ], + "sample" : [ + { + "line" : "[03/30/2021 08:57:44 PM] [MainThread ] [INFO ] Skipping Custom Plugins directory. - [/home/waboring/devel/aprsd/aprsd/plugin.py:232]" + }, + { + "line" : "[03/30/2021 08:57:44 PM] [KeepAlive ] [DEBUG] Uptime (0:00:00.577754) Tracker(0) Msgs: TX:0 RX:0 EmailThread: N/A RAM: Current:50289 Peak:99697 - [/home/waboring/devel/aprsd/aprsd/threads.py:89]" + } + ] + } +} diff --git a/aprsd/flask.py b/aprsd/flask.py index dca018b..9f8a84f 100644 --- a/aprsd/flask.py +++ b/aprsd/flask.py @@ -1,10 +1,13 @@ import datetime import json import logging +from logging import NullHandler +from logging.handlers import RotatingFileHandler +import sys import tracemalloc import aprsd -from aprsd import client, messaging, plugin, stats +from aprsd import client, messaging, plugin, stats, utils import flask import flask_classful from flask_httpauth import HTTPBasicAuth @@ -95,13 +98,47 @@ class APRSDFlask(flask_classful.FlaskView): return json.dumps(self._stats()) -def init_flask(config): +def setup_logging(config, flask_app, loglevel, quiet): + flask_log = logging.getLogger("werkzeug") + + if not config["aprsd"]["web"].get("logging_enabled", False): + # disable web logging + flask_log.disabled = True + flask_app.logger.disabled = True + return + + log_level = utils.LOG_LEVELS[loglevel] + LOG.setLevel(log_level) + log_format = config["aprsd"].get("logformat", utils.DEFAULT_LOG_FORMAT) + date_format = config["aprsd"].get("dateformat", utils.DEFAULT_DATE_FORMAT) + log_formatter = logging.Formatter(fmt=log_format, datefmt=date_format) + log_file = config["aprsd"].get("logfile", None) + if log_file: + fh = RotatingFileHandler(log_file, maxBytes=(10248576 * 5), backupCount=4) + else: + fh = NullHandler() + + fh.setFormatter(log_formatter) + for handler in flask_app.logger.handlers: + handler.setFormatter(log_formatter) + print(handler) + + flask_log.addHandler(fh) + + if not quiet: + sh = logging.StreamHandler(sys.stdout) + sh.setFormatter(log_formatter) + flask_log.addHandler(sh) + + +def init_flask(config, loglevel, quiet): flask_app = flask.Flask( "aprsd", static_url_path="", static_folder="web/static", template_folder="web/templates", ) + setup_logging(config, flask_app, loglevel, quiet) server = APRSDFlask() server.set_config(config) flask_app.route("/", methods=["GET"])(server.index) diff --git a/aprsd/main.py b/aprsd/main.py index 2bf476f..119a9a6 100644 --- a/aprsd/main.py +++ b/aprsd/main.py @@ -42,13 +42,6 @@ import click_completion # logging.basicConfig(level=logging.DEBUG) # level=10 LOG = logging.getLogger("APRSD") -LOG_LEVELS = { - "CRITICAL": logging.CRITICAL, - "ERROR": logging.ERROR, - "WARNING": logging.WARNING, - "INFO": logging.INFO, - "DEBUG": logging.DEBUG, -} CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"]) @@ -175,7 +168,7 @@ def signal_handler(sig, frame): # to disable logging to stdout, but still log to file # use the --quiet option on the cmdln def setup_logging(config, loglevel, quiet): - log_level = LOG_LEVELS[loglevel] + log_level = utils.LOG_LEVELS[loglevel] LOG.setLevel(log_level) log_format = config["aprsd"].get("logformat", utils.DEFAULT_LOG_FORMAT) date_format = config["aprsd"].get("dateformat", utils.DEFAULT_DATE_FORMAT) @@ -485,7 +478,7 @@ def server( if web_enabled: flask_enabled = True - app = flask.init_flask(config) + app = flask.init_flask(config, loglevel, quiet) app.run( host=config["aprsd"]["web"]["host"], port=config["aprsd"]["web"]["port"], diff --git a/aprsd/stats.py b/aprsd/stats.py index 986a795..4b4ce1e 100644 --- a/aprsd/stats.py +++ b/aprsd/stats.py @@ -162,6 +162,7 @@ class APRSDStats: "mic-e recieved": self.msgs_mice_rx, }, "email": { + "enabled": self.config["aprsd"]["email"]["enabled"], "sent": self._email_tx, "recieved": self._email_rx, "thread_last_update": last_update, diff --git a/aprsd/utils.py b/aprsd/utils.py index c101fe5..0be68f9 100644 --- a/aprsd/utils.py +++ b/aprsd/utils.py @@ -2,6 +2,7 @@ import errno import functools +import logging import os from pathlib import Path import sys @@ -11,9 +12,17 @@ from aprsd import plugin import click import yaml +LOG_LEVELS = { + "CRITICAL": logging.CRITICAL, + "ERROR": logging.ERROR, + "WARNING": logging.WARNING, + "INFO": logging.INFO, + "DEBUG": logging.DEBUG, +} + DEFAULT_LOG_FORMAT = ( "[%(asctime)s] [%(threadName)-12s] [%(levelname)-5.5s]" - " %(message)s - [%(pathname)s.%(funcName)s:%(lineno)d]" + " %(message)s - [%(pathname)s:%(lineno)d]" ) DEFAULT_DATE_FORMAT = "%m/%d/%Y %I:%M:%S %p" @@ -37,6 +46,7 @@ DEFAULT_CONFIG_DICT = { "units": "imperial", "web": { "enabled": True, + "logging_enabled": True, "host": "0.0.0.0", "port": 8001, "users": {