Ведение журнала Flask в нескольких модулях

У меня следующая структура каталогов во Flask, и я пытаюсь добавить в эту систему ведение журнала. Мои API определены в main.py, а backend.py предоставляет некоторую внутреннюю логику для API.

├── README.md
├── __init__.py
├── main.py
├── module
│   ├── __init__.py
│   └── backend.py

Мои API определены в main.py, а компоненты, связанные с журналированием, в файле выглядят следующим образом:

from logging.config import dictConfig
import logging
from module import backend

log_level = "DEBUG"
LOGFILENAME = "flask.log"
dictConfig({
    'version': 1,
    'formatters': {'default': {
        'format': '[%(asctime)s] {%(pathname)s:%(funcName)s:%(lineno)d} %(levelname)s - %(message)s',
    }},
    'handlers': {'default': {
                'level': 'DEBUG',
                'formatter': 'default',
                'class': 'logging.handlers.RotatingFileHandler',
                'filename': LOGFILENAME,
                'maxBytes': 5000000,
                'backupCount': 10
            }},
    'root': {
        'level': log_level,
        'handlers': ['default']
    }
})

app = Flask(__name__)
logger = logging.getLogger(__name__)

@app.route('/')
def hello():
    logger.debug("DEBUG: Inside the home function")
    logger.info("INFO: Inside the home function")
    backend.test()
    return "Welcome"

Ведение журнала работает должным образом в main.py. В зависимости от log_level журналы записываются на LOGFILENAME.

Проблемы возникают, когда я пытаюсь включить ведение журнала с помощью следующих шагов внутри backend.py.

import logging
logger = logging.getLogger(__name__)

def test():
    logger.info("info test")
    logger.debug("debug test")

Я не вижу никаких журналов записи backend.py на flask.log. Я чувствую, что что-то упускаю, но не понимаю, что. Любая помощь приветствуется.

Как запустить backend.py?

Sraw 15.08.2018 06:51
backend.py запускается API на main.py как from module import backendbackend.test()
lordlabakdas 15.08.2018 06:55

вы пробовали вызвать backend.test из метода hello?

James Lim 15.08.2018 07:08

Да, извините за попытку упростить проблему, я не отразил этот шаг выше. По-прежнему нет логов от backend.py

lordlabakdas 15.08.2018 07:13
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
4
2 212
2

Ответы 2

У вашей библиотеки другое имя регистратора. Для обоих вам нужно иметь одно и то же имя регистратора. См., Например, поваренная книга журнала.

Лучше всего создать собственную иерархию журналов, например myapp в main.py (logger = logging.getLogger("myapp")), и прикрепить к ней в backend.py, например, myapp.backend (logger = logging.getLogger(".".join("myapp", __name__)).

Найдите ниже слегка измененную версию ваших main.py и backend.py. Я удалил часть Flask. Я предполагаю, что это не влияет на механику регистрации.

main.py

import logging.config

from module import backend

dict_config = {
    'version': 1,
    'formatters': {
        'default': {
            'format': '[%(asctime)s] {%(pathname)s:%(funcName)s:%(lineno)d} %(levelname)s - %(message)s',
        }
    },
    'handlers': {'default': {
        'level': 'DEBUG',
        'formatter': 'default',
        'class': 'logging.handlers.RotatingFileHandler',
        'filename': "test.log",
        'maxBytes': 5000000,
        'backupCount': 10
    },
        'console': {
            'class': 'logging.StreamHandler',
            'level': 'DEBUG',
            'formatter': 'default',
        },
    },
    'loggers': {
        'myapp': {
            'handlers': ["default"],
            'level': 'DEBUG',
        },
    },
    'root': {
        'handlers': ["console"],
        'level': 'DEBUG',
    },
}

print(__name__)
logger = logging.getLogger("myapp")
logging.config.dictConfig(dict_config)


def hello():
    logger.debug("DEBUG: Inside the home function")
    logger.info("INFO: Inside the home function")
    backend.test()
    return "Welcome"


print(hello())

backend.py

import logging
logger = logging.getLogger("myapp")

def test():
    logger.info("info test")
    logger.debug("debug test")

Похоже, не работает. В тот момент, когда я перехожу на logger = logging.getLogger("myapp") на main.py, я не вижу журналов из API. Раньше, когда я использовал logger = logging.getLogger(__name__), я мог это просмотреть.

lordlabakdas 15.08.2018 08:10

Извини за это. Дай мне минутку, я проверю.

M.Rau 15.08.2018 08:12

Я думаю, что в вашем журнале отсутствует ключ loggers, см. docs.python.org/3/howto/…. Все регистраторы, не перечисленные здесь, отключаются. Таким образом, вам нужно будет указать имя вашего регистратора, желаемые обработчики и уровень журнала в разделе loggers.

M.Rau 15.08.2018 08:39

Добавление регистраторов, похоже, не имеет значения.

lordlabakdas 15.08.2018 09:11

Думаю, я нашел решение своей проблемы. Ниже приведены мои обновленные main.py и backend.py, которые, как подтверждено, работают.

main.py

import logging
from module import backend

log_level = "DEBUG"
LOGFILENAME = "flask.log"
class LoggerConfig:
    dictConfig = {
        'version': 1,
        'formatters': {'default': {
            'format': '[%(asctime)s] {%(pathname)s:%(funcName)s:%(lineno)d} %(levelname)s - %(message)s',
        }},
        'handlers': {'default': {
                    'level': 'DEBUG',
                    'formatter': 'default',
                    'class': 'logging.handlers.RotatingFileHandler',
                    'filename': LOGFILENAME,
                    'maxBytes': 5000000,
                    'backupCount': 10
                }},
        'root': {
            'level': log_level,
            'handlers': ['default']
        },
    }

app = Flask(__name__)

logging.config.dictConfig(LoggerConfig.dictConfig)

@app.route('/')
def hello():
    app.logger.debug("DEBUG: Inside the home function")
    app.logger.info("INFO: Inside the home function")
    backend.test()
    return "Welcome"

backend.py

import logging
logger = logging.getLogger()

def test():
    logger.info("info test")
    logger.debug("debug test")

Если вы заметили, вторая строка backend.py - это, по сути, logging.getLogger() без имени. Это сработало с backend side.

Также помог app.logger на стороне API (сторона main.py).

В целом, мне удалось заставить и main.py, и backend.py записывать в один и тот же файл, указанный в dictConfig.

Другие вопросы по теме