Хотя я уже некоторое время работаю с python / i python, я считаю себя новичком. Есть еще много вещей, особенно о поддержке журналирования, как я думал, я понял из документации, но, по-видимому, их сложнее настроить, чем я ранее надеялся. Я использую ipython 5.5.0 / python 2.7.17 on Xubuntu 18.04.04 LTS
с цветными журналами. Ниже приведен мой модуль конфигурации ведения журнала.
import coloredlogs
import datetime
import logging
import logging.config
import os
import yaml
def setup_logging( default_path='../Config/logging.yaml',
default_level=logging.DEBUG,
env_key='LOG_CFG'):
path = os.path.join(os.path.dirname(os.path.realpath(__file__)), default_path)
value = os.getenv(env_key, None)
# If the envvar is set, use it's value
if value:
path = value
_dt = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print("%s Using Logging Configuration: %s" % (_dt, path) )
#
# If the configuration file path is there, read it
#
if os.path.exists(path):
with open(path, 'rt') as f:
try:
config = yaml.safe_load(f.read())
logging.config.dictConfig(config)
coloredlogs.install(level=default_level)
except Exception as err:
print(err)
print('Error in Logging Configuration. Using default configs')
logging.basicConfig(level=default_level)
coloredlogs.install(level=default_level)
# Otherwise, continue without a configuration
else:
logging.basicConfig(level=logging.DEBUG)
coloredlogs.install(level=logging.DEBUG)
print('Failed to load configuration file. Using default configs')
Конфигурация хранится в файле yaml со следующими определениями.
version: 1
disable_existing_loggers: False
formatters:
basic:
format: "%(name)s - %(message)s"
standard:
format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
error:
format: "%(levelname)s <PID %(process)d:%(processName)s> %(name)s.%(funcName)s(): %(message)s"
handlers:
console_basic:
class: logging.StreamHandler
level: DEBUG
formatter: basic
stream: ext://sys.stdout
console_out:
class: logging.StreamHandler
level: DEBUG
formatter: standard
stream: ext://sys.stdout
console_err:
class: logging.StreamHandler
level: DEBUG
formatter: standard
stream: ext://sys.stderr
debug_file_handler:
class: logging.handlers.RotatingFileHandler
level: DEBUG
formatter: standard
filename: /tmp/debug.log
maxBytes: 10485760 # 10MB
backupCount: 20
encoding: utf8
info_file_handler:
class: logging.handlers.RotatingFileHandler
level: INFO
formatter: standard
filename: /tmp/info.log
maxBytes: 10485760 # 10MB
backupCount: 20
encoding: utf8
warn_file_handler:
class: logging.handlers.RotatingFileHandler
level: WARN
formatter: standard
filename: /tmp/warn.log
maxBytes: 10485760 # 10MB
backupCount: 20
encoding: utf8
error_file_handler:
class: logging.handlers.RotatingFileHandler
level: ERROR
formatter: error
filename: /tmp/errors.log
maxBytes: 10485760 # 10MB
backupCount: 20
encoding: utf8
critical_file_handler:
class: logging.handlers.RotatingFileHandler
level: CRITICAL
formatter: standard
filename: /tmp/critical.log
maxBytes: 10485760 # 10MB
backupCount: 20
encoding: utf8
root:
level: CRITICAL
handlers: [console_err]
propogate: no
loggers:
test:
level: DEBUG
handlers: [console_basic]
propogate: no
Utils.paragraph_processing:
level: DEBUG
handlers: [info_file_handler, debug_file_handler, warn_file_handler, error_file_handler, critical_file_handler]
propogate: no
Utils.graphing_functions:
level: DEBUG
handlers: [info_file_handler, debug_file_handler, warn_file_handler, error_file_handler, critical_file_handler]
propogate: no
Следующий фрагмент моего модуля test.py:
import coloredlogs
from copy import deepcopy
import cv2
import imutils
import logging
import logging.config
import os
import yaml
import matplotlib.pyplot as PLT
import matplotlib.image as MPI
import numpy as np
import Tests.filtering_tests as FT
import Tests.morphology_tests as MT
import Utils.global_defs as GL
import Utils.graphing_functions as GF
import Utils.paragraph_processing as PP
import Utils.logging_functions as LF
.
.
.
def phony_main():
LF.setup_logging()
# create logger
LOG = logging.getLogger(__name__)
LOG.critical("Logging Started...")
# -----------------------------------------------------------------------------
#
# Main
#
img = None
if __name__ == "__main__":
# execute only if run as a script
phony_main()
У меня следующие вопросы: когда я меняю конфигурацию, как я это сделал, с [console_out] на [console_basic], я ожидал, что сообщения будут соответствовать, но это не так. Заставить меня поверить, что какой-то другой регистратор, root (?), Обрабатывает вызов? Но если я изменю это на использование [console_basic], сообщения останутся прежними. То есть можно было бы ожидать, что времени и имени уровня больше не будет, но они есть! ![enter image description here](https://i.stack.imgur.com/4vyu6.png)
Опять же, я не претендую на понимание того, что происходит, но там, где я думал, что документация показывает простое наследование, я начинаю задумываться, что это немного сложнее, чем это. Что я делаю не так?
Когда я исправляю орфографическую ошибку и удаляю регистратор для проверки, я все равно получаю такое же поведение. Включение распространения, чтобы журналы консоли попадали в регистратор root, в котором [console_basic] по-прежнему отображаются сообщения в старом формате. ![enter image description here](https://i.stack.imgur.com/msqae.png)
Внесение следующих изменений в мой yaml, похоже, решает проблемы, как указано @ blues.
root:
level: NOTSET
handlers: [console_basic]
propagate: no
loggers:
__main__:
level: DEBUG
handlers: [console_basic]
propagate: no
Utils.paragraph_processing:
level: DEBUG
handlers: [info_file_handler, debug_file_handler, warn_file_handler, error_file_handler, critical_file_handler]
propagate: no
Utils.graphing_functions:
level: DEBUG
handlers: [info_file_handler, debug_file_handler, warn_file_handler, error_file_handler, critical_file_handler]
propagate: no