Add custom log handler for sending logs to UI
This commit is contained in:
parent
dd0b30df51
commit
70d9e2f758
2 changed files with 73 additions and 6 deletions
|
|
@ -11,6 +11,7 @@ OFM_LOG_FILE = os.path.join(OFM_LOG_FOLDER, "openflexure_microscope.log")
|
||||||
def configure_logging():
|
def configure_logging():
|
||||||
root_logger = logging.getLogger()
|
root_logger = logging.getLogger()
|
||||||
root_logger.setLevel(logging.INFO)
|
root_logger.setLevel(logging.INFO)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if not os.path.exists(OFM_LOG_FOLDER):
|
if not os.path.exists(OFM_LOG_FOLDER):
|
||||||
os.makedirs(OFM_LOG_FOLDER)
|
os.makedirs(OFM_LOG_FOLDER)
|
||||||
|
|
@ -20,10 +21,13 @@ def configure_logging():
|
||||||
maxBytes=1000000,
|
maxBytes=1000000,
|
||||||
backupCount=10,
|
backupCount=10,
|
||||||
)
|
)
|
||||||
handler.setFormatter(
|
format_str = "[%(asctime)s] [%(levelname)s] <%(name)s> %(message)s"
|
||||||
logging.Formatter("[%(asctime)s] [%(levelname)s] %(message)s")
|
handler.setFormatter(logging.Formatter(format_str))
|
||||||
)
|
|
||||||
root_logger.addHandler(handler)
|
root_logger.addHandler(handler)
|
||||||
|
ofm_format_str = "[%(asctime)s] [%(levelname)s] %(message)s"
|
||||||
|
OFM_HANDLER.setFormatter(logging.Formatter(ofm_format_str))
|
||||||
|
root_logger.addHandler(OFM_HANDLER)
|
||||||
|
|
||||||
except PermissionError as e:
|
except PermissionError as e:
|
||||||
logging.warning(f"Cannot create log file at {OFM_LOG_FILE}: {e}")
|
logging.warning(f"Cannot create log file at {OFM_LOG_FILE}: {e}")
|
||||||
logging.info("")
|
logging.info("")
|
||||||
|
|
@ -33,5 +37,65 @@ def configure_logging():
|
||||||
|
|
||||||
|
|
||||||
def retrieve_log() -> PlainTextResponse:
|
def retrieve_log() -> PlainTextResponse:
|
||||||
"""The most recent 1Mb of logs from the server"""
|
"""
|
||||||
return FileResponse(OFM_LOG_FILE, media_type=PlainTextResponse.media_type)
|
Returns logs since we started running the server, up to a maxiumum of
|
||||||
|
250 messages. This log is the one shown in the UI and on the logging page.
|
||||||
|
|
||||||
|
It does not include any of the `uvicorn.access` logs as these are emmitted
|
||||||
|
every time any API route is called.
|
||||||
|
|
||||||
|
All logs, including `uvicorn.access` are logged to the OFM_LOG_FILE (see above)
|
||||||
|
ths is the best place to get logs about crashes.
|
||||||
|
"""
|
||||||
|
return PlainTextResponse(OFM_HANDLER.log_history)
|
||||||
|
|
||||||
|
|
||||||
|
class OFMHandler(logging.Handler):
|
||||||
|
"""
|
||||||
|
A child class of logging.Handler. This class handles storing the most recent
|
||||||
|
logs for access by the server.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, level=logging.INFO, max_logs=250):
|
||||||
|
super().__init__(level=level)
|
||||||
|
self._log = []
|
||||||
|
self._max_logs = max_logs
|
||||||
|
|
||||||
|
def append_record(self, record):
|
||||||
|
"""
|
||||||
|
Use the built in formatter to format the record, then save
|
||||||
|
it to an array. Pop any in excess of the mamimum number of logs
|
||||||
|
"""
|
||||||
|
self._log.append(self.format(record))
|
||||||
|
while len(self._log) > self._max_logs:
|
||||||
|
self._log.pop(0)
|
||||||
|
|
||||||
|
def emit(self, record):
|
||||||
|
"""
|
||||||
|
Emit will save the logged record to the log
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Basic filter for now that simply stops uvicorn.access logs
|
||||||
|
# These are the logs each time an API endpoint is accessed
|
||||||
|
# This is only the log for the UI.
|
||||||
|
if record.name.startswith("uvicorn.access"):
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
if record.levelno >= self.level:
|
||||||
|
self.append_record(record)
|
||||||
|
except RecursionError as e:
|
||||||
|
raise e
|
||||||
|
except BaseException:
|
||||||
|
# Never let the logger crash unless there is somehow recursion.
|
||||||
|
# Use built in logging error handler
|
||||||
|
self.handleError(record)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def log_history(self):
|
||||||
|
"""
|
||||||
|
Return the log history up to the maximum number of logs
|
||||||
|
"""
|
||||||
|
return "\n".join(self._log)
|
||||||
|
|
||||||
|
|
||||||
|
OFM_HANDLER = OFMHandler()
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,10 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<a class="uk-button uk-button-default" :href="logFileURI" download
|
<a
|
||||||
|
class="uk-button uk-button-default"
|
||||||
|
:href="logFileURI"
|
||||||
|
download="openflexure_microscope-ui.log"
|
||||||
>Download Log File</a
|
>Download Log File</a
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue