Python / Django: inicie sesión en la consola en runserver, inicie sesión en un archivo en Apache


114

¿Cómo puedo enviar mensajes de seguimiento a la consola (como print) cuando estoy ejecutando mi aplicación Django en manage.py runserver, pero esos mensajes se envían a un archivo de registro cuando ejecuto la aplicación en Apache?

He revisado el registro de Django y aunque me quedé impresionado con su flexibilidad y capacidad de configuración para usos avanzados, todavía estoy confundido con la forma de manejar mi sencilla de casos de uso.


1
La solución más simple es tener diferentes archivos settings.py para el servidor principal y el entorno de desarrollo, consulte deploydjango.com/django_project_structure
— Alex

Respuestas:


84

El texto impreso en stderr aparecerá en el registro de errores de httpd cuando se ejecute bajo mod_wsgi. Puede usar printdirectamente o usar loggingen su lugar.

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

2
Sin embargo, técnicamente no es WSGI válido y provocará errores en entornos más estrictos.
— Paul McMillan

13
No hay nada de malo en usar 'print' con 'sys.stderr' en lo que respecta a WSGI y no debería generar errores.
— Graham Dumpleton

Importé sys pero esto no parece funcionar para mí.
— Hack-R

17
Esto no funciona en Python 3, eche un vistazo aquí . Necesitasprint("Goodbye cruel world!", file=sys.stderr)
— cardamomo

103

Aquí hay una solución basada en registros de Django. Utiliza la configuración DEBUG en lugar de verificar si está ejecutando el servidor de desarrollo o no, pero si encuentra una mejor manera de verificarlo, debería ser fácil de adaptar.

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

consulte https://docs.djangoproject.com/en/dev/topics/logging/ para obtener más detalles.


8
también intenteLOGGING['loggers'][logger]['handlers'] += ['console']
— Nir Levy

@ m01: Después de configurar esto en settings.py, ¿cómo usarlo para imprimir? Gracias
— Niks Jain

Puse el código de mi respuesta en mi settings.pyhacia la parte inferior y lo configuré DEBUG = True(busque esa configuración cerca de la parte superior en el mismo archivo). Luego, ejecuto python manage.py runserverdesde una terminal (consulte los documentos de django para obtener más detalles) y los mensajes de registro aparecerán en la ventana de la terminal. En producción, usaría un settings.py diferente, donde DEBUG = False- los mensajes de registro van /path/to/your/file.log.
— m01

Tu sangría me dio dolor de cabeza. Gracias por la información, ¡funciona!
— ioan

¡Gracias! Hice algunos cambios en la sangría, espero que esté mejor ahora
— m01

27

Puede configurar el registro en su settings.pyarchivo.

Un ejemplo:

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

Sin embargo, eso depende de la configuración de DEBUG, y tal vez no quieras tener que preocuparte por cómo está configurado. Vea esta respuesta sobre ¿Cómo puedo saber si mi aplicación Django se está ejecutando en el servidor de desarrollo o no? para una mejor forma de escribir ese condicional. Editar: el ejemplo anterior es de un proyecto Django 1.1, la configuración de registro en Django ha cambiado algo desde esa versión.


No quiero depender de DEBUG; Prefiero depender del mecanismo de detección del servidor de desarrollo vinculado en esa otra publicación. Pero el mecanismo de detección de la otra publicación se basa en tener acceso a una instancia de solicitud. ¿Cómo puedo obtener una instancia de solicitud en settings.py?
— Justin Grant

4

Yo uso esto:

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

Puede hacer esto con bastante facilidad con tagalog(https://github.com/dorkitude/tagalog)

Por ejemplo, mientras que el módulo de Python estándar escribe en un objeto de archivo abierto en modo adjunto, el módulo de App Engine (https://github.com/dorkitude/tagalog/blob/master/tagalog_appengine.py) anula este comportamiento y en su lugar usa logging.INFO.

Para obtener este comportamiento en un proyecto de App Engine, simplemente se podría hacer:

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

Puede ampliar el módulo usted mismo y sobrescribir la función de registro sin mucha dificultad.


0

Esto funciona bastante bien en mi local.py, me ahorra estropear el registro regular:

from .settings import *

LOGGING['handlers']['console'] = {
    'level': 'DEBUG',
    'class': 'logging.StreamHandler',
    'formatter': 'verbose'
}
LOGGING['loggers']['foo.bar'] = {
    'handlers': ['console'],
    'propagate': False,
    'level': 'DEBUG',
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.