web-dev-qa-db-fra.com

Python/Django: connectez-vous à la console sous le serveur d'exécution, connectez-vous au fichier sous Apache

Comment puis-je envoyer des messages de suivi à la console (comme print) lorsque j'exécute mon application Django sous manage.py runserver, mais que ces messages sont envoyés à un fichier journal lorsque j'exécute l'application sous Apache?

J'ai passé en revue Journalisation Django et bien que j’ai été impressionné par sa flexibilité et sa configurabilité pour les utilisations avancées, je ne comprends toujours pas comment gérer mon cas d’utilisation simple.

96
Justin Grant

Le texte imprimé sur stderr apparaîtra dans le journal des erreurs de httpd lors de l'exécution sous mod_wsgi. Vous pouvez utiliser directement print ou plutôt utiliser logging.

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

Voici une solution basée sur la journalisation Django. Il utilise le paramètre DEBUG plutôt que de vérifier si vous utilisez ou non le serveur de développement, mais si vous trouvez un meilleur moyen de vérifier cela, il devrait être facile à adapter.

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']

voir https://docs.djangoproject.com/en/dev/topics/logging/ pour plus de détails.

93
m01

Vous pouvez configurer la journalisation dans votre fichier settings.py

Un exemple:

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'
    )

Cependant, cela dépend du réglage de DEBUG et peut-être que vous ne voulez pas vous inquiéter de la façon dont il est configuré. Voir cette réponse sur Comment savoir si mon application Django s’exécute sur un serveur de développement? pour une meilleure façon d'écrire ce conditionnel. Edit: l'exemple ci-dessus est tiré d'un projet Django 1.1, la configuration de la journalisation dans Django a quelque peu changé depuis cette version.

24
Ben Lopatin

J'utilise ceci:

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 __== '__main__':
    main()
3
xuejunliang

Cela fonctionne assez bien dans mon local.py, cela me évite de gâcher la journalisation normale:

from .settings import *

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

Vous pouvez le faire assez facilement avec tagalog (https://github.com/dorkitude/tagalog)

Par exemple, pendant que le module python standard écrit dans un objet fichier ouvert en mode ajout, le module App Engine (https://github.com/dorkitude/tagalog/blob/master/tagalog_appengine.py) annule ce problème et utilise à la place logging.INFO. .

Pour obtenir ce comportement dans un projet App Engine, on pourrait simplement faire:

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

Vous pouvez étendre le module vous-même et écraser la fonction de journalisation sans trop de difficultés.

0
Kyle Wild