В настоящее время я пытаюсь отойти от print () и начать с централизованного сбора журналов, используя стек ELK и модуль structlog для генерации структурированных строк журнала json.Это прекрасно работает для модулей, которые я написал сам, используя модуль loggingHelper, который я могу импортировать и использовать с
logger = Logger()
в других модулях и скриптах.Это класс модуля loggingHelper:
class Logger:
"""
Wrapper Class to import within other modules and scripts
All the config and log binding (script
"""
def __init__(self):
self.__log = None
logging.basicConfig(level=logging.DEBUG, format='%(message)s')
structlog.configure(logger_factory=LoggerFactory(),
processors=[structlog.stdlib.add_log_level,
structlog.processors.TimeStamper(fmt="iso"),
structlog.processors.JSONRenderer()])
logger = structlog.get_logger()
main_script = os.path.basename(sys.argv[0]) if sys.argv[0] else None
frame = inspect.stack()[1]
log_invocation = os.path.basename(frame[0].f_code.co_filename)
user = getpass.getuser()
"""
Who executed the __main__, what was the executed __main__ file,
where did the log event happen?
"""
self.__log = logger.bind(executedScript = main_script,
logBirth = log_invocation,
executingUser = user)
def info(self, msg, **kwargs):
self.__log.info(msg, **kwargs)
def debug(self, msg, **kwargs):
self.__log.debug(msg, **kwargs)
def error(self, msg, **kwargs):
self.__log.error(msg, **kwargs)
def warn(self, msg, **kwargs):
self.__log.warning(msg, **kwargs)
Это производит красиво отформатированный вывод (один JSON на строку), который filebeat может читать и пересылать в Elasticsearch.Однако сторонние библиотекари полностью разбивают хорошо отформатированные журналы.
{"executingUser": "xyz", "logBirth": "efood.py", "executedScript": "logAlot.py", "context": "SELECT displayname FROM point_of_sale WHERE name = '123'", "level": "debug", "timestamp": "2019-03-15T12:52:42.792398Z", "message": "querying local"}
{"executingUser": "xyz", "logBirth": "efood.py", "executedScript": "logAlot.py", "level": "debug", "timestamp": "2019-03-15T12:52:42.807922Z", "message": "query successful: got 0 rows"}
building service object
auth version used is: v4
Traceback (most recent call last):
File "logAlot.py", line 26, in <module>
ef.EfoodDataControllerMerchantCenter().get_displayname(123)
File "/home/xyz/src/toolkit/commons/connectors/efood.py", line 1126, in get_displayname
return efc.select_from_local(q)['displayname'].values[0]
IndexError: index 0 is out of bounds for axis 0 with size 0
Как видно, сообщения информационного уровня и уровня ошибок от сторонних библиотек (googleapiclient) печатаются без прохождения через процессоры журналирования..
Каков наилучший (и самый питонический) способ захвата и форматирования всего, что происходит при выполнении одного скрипта, с помощью написанного мной модуля loggingHelper?Является ли это даже лучшей практикой?
Редактировать: В настоящее время регистратор действительно выполняет запись в сам stdout, который затем перенаправляется в файл в crontab, используя >> и 2> & 1.Мне кажется, что это плохая практика, если я хочу перенаправить все, что записано в stdout / stderr, путем сторонней регистрации в библиотеке, потому что это приведет к циклу, правильно?Таким образом, моя цель - не перенаправление, а захват всего в моем процессоре регистрации.Соответственно изменил название.
Кроме того, вот приблизительный обзор того, чего я пытаюсь достичь.Я очень открыт для общей критики и предложений, которые отличаются от этого.![enter image description here](https://i.stack.imgur.com/gMlhh.png)