import io
import logging
import pyrosetta
import re
from typing import (Any, Optional, Union, Dict, List)
[docs]def get_log_entries(levelname: Union[str, int]=logging.INFO, query: Optional[str]=None) -> List[Dict[str, Any]]:
"""
Get a list of all entries in log at a given level.
levelname can be either an int (``logging.INFO`` etc. are numbers multiples of 10 in increasing severity)
or a string of the level.
Note that it is very crude: if INFO is requested, ERROR is not shown!
:param levelname: int for the level number or str of the name
:return: List of str
"""
if isinstance(levelname, int):
# logging.INFO is actually an int, not an enum
levelnumber = logging.getLevelName(levelname)
entries = get_all_log_entries()
if query is None:
return [e for e in entries if e['level'] == levelnumber]
else:
return [e for e in entries if str(query) in e['text']]
[docs]def get_all_log_entries() -> List[Dict[str, Any]]:
stringio = logging.getLogger("rosetta").handlers[0].stream
cleaned = []
previous = None
for entry in stringio.getvalue().split('\n'):
rex = re.match(f'\[(.*)\] (.*) - (.*)', entry)
if rex:
if previous:
cleaned.append(previous)
previous = dict(datetime=rex.group(1),
level=logging.getLevelName(rex.group(2)),
text=rex.group(3))
else:
previous['text'] += '\n' + entry
if previous:
cleaned.append(previous)
return cleaned