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.
This commit is contained in:
Hemna 2021-03-31 10:49:49 -04:00
parent d1a2a14370
commit 34d2c31d90
5 changed files with 92 additions and 12 deletions

39
aprsd-lnav.json Normal file
View File

@ -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" : "^\\[(?<timestamp>\\d{2}\\/\\d{2}\\/\\d{4} \\d{2}:\\d{2}:\\d{2} ([AaPp][Mm]))\\] \\[(?<thread>\\w+\\s*)\\] \\[(?<alert_level>\\w+\\s*)\\] (?<body>([^-]*)-*)\\s\\[(?<file>([^:]*))\\:(?<line>\\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]"
}
]
}
}

View File

@ -1,10 +1,13 @@
import datetime import datetime
import json import json
import logging import logging
from logging import NullHandler
from logging.handlers import RotatingFileHandler
import sys
import tracemalloc import tracemalloc
import aprsd import aprsd
from aprsd import client, messaging, plugin, stats from aprsd import client, messaging, plugin, stats, utils
import flask import flask
import flask_classful import flask_classful
from flask_httpauth import HTTPBasicAuth from flask_httpauth import HTTPBasicAuth
@ -95,13 +98,47 @@ class APRSDFlask(flask_classful.FlaskView):
return json.dumps(self._stats()) 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( flask_app = flask.Flask(
"aprsd", "aprsd",
static_url_path="", static_url_path="",
static_folder="web/static", static_folder="web/static",
template_folder="web/templates", template_folder="web/templates",
) )
setup_logging(config, flask_app, loglevel, quiet)
server = APRSDFlask() server = APRSDFlask()
server.set_config(config) server.set_config(config)
flask_app.route("/", methods=["GET"])(server.index) flask_app.route("/", methods=["GET"])(server.index)

View File

@ -42,13 +42,6 @@ import click_completion
# logging.basicConfig(level=logging.DEBUG) # level=10 # logging.basicConfig(level=logging.DEBUG) # level=10
LOG = logging.getLogger("APRSD") 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"]) 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 # to disable logging to stdout, but still log to file
# use the --quiet option on the cmdln # use the --quiet option on the cmdln
def setup_logging(config, loglevel, quiet): def setup_logging(config, loglevel, quiet):
log_level = LOG_LEVELS[loglevel] log_level = utils.LOG_LEVELS[loglevel]
LOG.setLevel(log_level) LOG.setLevel(log_level)
log_format = config["aprsd"].get("logformat", utils.DEFAULT_LOG_FORMAT) log_format = config["aprsd"].get("logformat", utils.DEFAULT_LOG_FORMAT)
date_format = config["aprsd"].get("dateformat", utils.DEFAULT_DATE_FORMAT) date_format = config["aprsd"].get("dateformat", utils.DEFAULT_DATE_FORMAT)
@ -485,7 +478,7 @@ def server(
if web_enabled: if web_enabled:
flask_enabled = True flask_enabled = True
app = flask.init_flask(config) app = flask.init_flask(config, loglevel, quiet)
app.run( app.run(
host=config["aprsd"]["web"]["host"], host=config["aprsd"]["web"]["host"],
port=config["aprsd"]["web"]["port"], port=config["aprsd"]["web"]["port"],

View File

@ -162,6 +162,7 @@ class APRSDStats:
"mic-e recieved": self.msgs_mice_rx, "mic-e recieved": self.msgs_mice_rx,
}, },
"email": { "email": {
"enabled": self.config["aprsd"]["email"]["enabled"],
"sent": self._email_tx, "sent": self._email_tx,
"recieved": self._email_rx, "recieved": self._email_rx,
"thread_last_update": last_update, "thread_last_update": last_update,

View File

@ -2,6 +2,7 @@
import errno import errno
import functools import functools
import logging
import os import os
from pathlib import Path from pathlib import Path
import sys import sys
@ -11,9 +12,17 @@ from aprsd import plugin
import click import click
import yaml import yaml
LOG_LEVELS = {
"CRITICAL": logging.CRITICAL,
"ERROR": logging.ERROR,
"WARNING": logging.WARNING,
"INFO": logging.INFO,
"DEBUG": logging.DEBUG,
}
DEFAULT_LOG_FORMAT = ( DEFAULT_LOG_FORMAT = (
"[%(asctime)s] [%(threadName)-12s] [%(levelname)-5.5s]" "[%(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" DEFAULT_DATE_FORMAT = "%m/%d/%Y %I:%M:%S %p"
@ -37,6 +46,7 @@ DEFAULT_CONFIG_DICT = {
"units": "imperial", "units": "imperial",
"web": { "web": {
"enabled": True, "enabled": True,
"logging_enabled": True,
"host": "0.0.0.0", "host": "0.0.0.0",
"port": 8001, "port": 8001,
"users": { "users": {