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.

Justin Grant
fuente
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!'
Ignacio Vázquez-Abrams
fuente
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.

m01
fuente
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.

3 revoluciones
fuente
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()
xuejunliang
fuente
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.

Kyle salvaje
fuente
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',
}
jmoz
fuente