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


114

Як я можу надсилати повідомлення про трасування до консолі (наприклад print), коли я запускаю додаток Django manage.py runserver, але чи надсилати ці повідомлення в файл журналу, коли я запускаю програму під Apache?

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


1
Найпростішим рішенням є наявність різних файлів settings.py для основного сервера та середовища розробки, див. Implemendjango.com/django_project_structure
Alex

Відповіді:


84

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

print >>sys.stderr, 'Goodbye, cruel world!'

2
Технічно не є дійсним WSGI, і це призведе до помилок у більш жорстких умовах.
Пол Макміллан

13
Немає нічого поганого у використанні "print" із "sys.stderr", наскільки це стосується WSGI, і це не повинно викликати помилок.
Грем Дамплетон

Я імпортував sys, але це, здається, не працює для мене.
Hack-R

17
Це не працює в Python 3. Подивіться тут . Вам потрібноprint("Goodbye cruel world!", file=sys.stderr)
кардамон

103

Ось рішення на основі журналу 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/ .


8
також спробуйтеLOGGING['loggers'][logger]['handlers'] += ['console']
Нір Леві

@ m01: Після конфігурації цього параметра в settings.py, як це використовувати для друку? Спасибі
Нікс Джейн

Я вкладаю код від своєї відповіді до моєї settings.pyзнизу і встановлюю DEBUG = True(шукайте це налаштування біля верху в тому самому файлі). Потім я запускаю python manage.py runserverз терміналу (детальніше див. Документи django), і повідомлення журналу з’являться у вікні терміналу. У виробництві я б використовував інший settings.py, де DEBUG = False- повідомлення журналу /path/to/your/file.log.
m01

Ваші відступи дали мені головний біль. Дякую за інформацію, хоча це працює!
Іоан

Дякую! Я вніс деякі зміни в відступ, сподіваюся, що зараз краще
m01

27

Ви можете налаштувати вхід у свій 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 дещо змінилася після цієї версії.


Я не хочу покладатися на DEBUG; Я вважаю за краще залежати від механізму виявлення dev-сервера, пов'язаного в цій іншій посаді. Але механізм виявлення інших публікацій покладається на доступ до екземпляра запиту. Як я можу отримати екземпляр запиту в settings.py?
Джастін Грант

4

Я використовую це:

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

Це можна зробити досить легко за допомогою 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'])

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


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',
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.