Python / Django: вход в консоль под runserver, вход в файл под Apache

87

Как отправить сообщения трассировки на консоль (например, print), когда я запускаю приложение Django в manage.py runserver, но эти сообщения отправляются в файл журнала, когда я запускаю приложение под Apache?

Я просмотрел запись в Django, и хотя я был впечатлен своей гибкостью и настраиваемостью для расширенного использования, я все еще не понимаю, как обращаться с моими простой прецедент.

Теги:
logging

6 ответов

71
Лучший ответ

Текст, напечатанный в stderr, будет отображаться в журнале ошибок httpd при работе в режиме mod_wsgi. Вы можете использовать print напрямую или вместо этого использовать logging.

print >>sys.stderr, 'Goodbye, cruel world!'
  • 1
    Хотя это технически недопустимый WSGI и будет вызывать ошибки в более строгих средах.
  • 12
    Нет ничего плохого в использовании 'print' с 'sys.stderr' в том, что касается WSGI, и это не должно вызывать ошибок.
Показать ещё 2 комментария
85

Здесь находится решение, основанное на протоколе Django. Он использует настройку DEBUG вместо фактической проверки того, запускаете ли вы сервер разработки, но если вы найдете лучший способ проверить, что его легко адаптировать.

LOGGING = {
    'version': 1,
    'formatters': {
        'verbose': {
            'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
        },
        'simple': {
            'format': '%(levelname)s %(message)s'
        },
    },
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'simple'
        },
        'file': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': '/path/to/your/file.log',
            'formatter': 'simple'
        },
    },
    'loggers': {
        'django': {
            'handlers': ['file'],
            'level': 'DEBUG',
            'propagate': True,
        },
    }
}

if DEBUG:
    # make all loggers use the console.
    for logger in LOGGING['loggers']:
        LOGGING['loggers'][logger]['handlers'] = ['console']

Подробнее см. https://docs.djangoproject.com/en/dev/topics/logging/.

  • 5
    также попробуйте LOGGING['loggers'][logger]['handlers'] += ['console']
  • 0
    @ m01: после настройки в settings.py, как использовать это для печати? Спасибо
Показать ещё 5 комментариев
22

Вы можете настроить ведение журнала в вашем файле settings.py.

Один пример:

if DEBUG:
    # will output to your console
    logging.basicConfig(
        level = logging.DEBUG,
        format = '%(asctime)s %(levelname)s %(message)s',
    )
else:
    # will output to logging file
    logging.basicConfig(
        level = logging.DEBUG,
        format = '%(asctime)s %(levelname)s %(message)s',
        filename = '/my_log_file.log',
        filemode = 'a'
    )

Однако это зависит от установки DEBUG и, возможно, вам не нужно беспокоиться о том, как он настроен. См. Этот ответ на Как узнать, работает ли приложение Django на сервере разработки или нет? для лучшего способа написания этого условного. Изменить: приведенный выше пример - из проекта Django 1.1, настройка журнала в Django несколько изменилась с этой версии.

  • 0
    Я не хочу полагаться на DEBUG; Я бы предпочел зависеть от механизма обнаружения dev-server, описанного в этом другом посте. Но механизм обнаружения другого поста зависит от наличия доступа к экземпляру запроса. Как я могу получить экземпляр запроса в settings.py?
2

Я использую это:

logging.conf:

[loggers]
keys=root,applog
[handlers]
keys=rotateFileHandler,rotateConsoleHandler

[formatters]
keys=applog_format,console_format

[formatter_applog_format]
format=%(asctime)s-[%(levelname)-8s]:%(message)s

[formatter_console_format]
format=%(asctime)s-%(filename)s%(lineno)d[%(levelname)s]:%(message)s

[logger_root]
level=DEBUG
handlers=rotateFileHandler,rotateConsoleHandler

[logger_applog]
level=DEBUG
handlers=rotateFileHandler
qualname=simple_example

[handler_rotateFileHandler]
class=handlers.RotatingFileHandler
level=DEBUG
formatter=applog_format
args=('applog.log', 'a', 10000, 9)

[handler_rotateConsoleHandler]
class=StreamHandler
level=DEBUG
formatter=console_format
args=(sys.stdout,)

testapp.py:

import logging
import logging.config

def main():
    logging.config.fileConfig('logging.conf')
    logger = logging.getLogger('applog')

    logger.debug('debug message')
    logger.info('info message')
    logger.warn('warn message')
    logger.error('error message')
    logger.critical('critical message')
    #logging.shutdown()

if __name__ == '__main__':
    main()
0

Это хорошо работает на моем local.py, меня избавляет от регулярного ведения журнала:

from .settings import *

LOGGING['handlers']['console'] = {
    'level': 'DEBUG',
    'class': 'logging.StreamHandler',
    'formatter': 'verbose'
}
LOGGING['loggers']['foo.bar'] = {
    'handlers': ['console'],
    'propagate': False,
    'level': 'DEBUG',
}
0

Вы можете сделать это довольно легко с помощью tagalog (https://github.com/dorkitude/tagalog)

Например, хотя стандартный модуль python записывает в объект файла, открытый в режиме добавления, модуль App Engine (https://github.com/dorkitude/tagalog/blob/master/tagalog_appengine.py) переопределяет это поведение и вместо этого использует logging.INFO.

Чтобы получить это поведение в проекте App Engine, можно просто сделать:

import tagalog.tagalog_appengine as tagalog
tagalog.log('whatever message', ['whatever','tags'])

Вы можете расширить модуль самостоятельно и перезаписать функцию журнала без особых трудностей.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню