Python / Django: log ke konsol di bawah runserver, masuk ke file di bawah Apache

114

Bagaimana saya bisa mengirim pesan jejak ke konsol (seperti print ) ketika saya menjalankan aplikasi Django saya di bawah manage.py runserver, tetapi pesan tersebut dikirim ke file log ketika saya menjalankan aplikasi di bawah Apache?

Saya meninjau pencatatan Django dan meskipun saya terkesan dengan fleksibilitas dan konfigurasinya untuk penggunaan tingkat lanjut, saya masih bingung dengan cara menangani kasus penggunaan sederhana saya.

Justin Grant
sumber
1
Solusi paling sederhana adalah memiliki file settings.py yang berbeda untuk server utama dan lingkungan pengembangan, lihat deploydjango.com/django_project_structure
Alex

Jawaban:

84

Teks yang dicetak ke stderr akan muncul di log kesalahan httpd saat dijalankan dengan mod_wsgi. Anda dapat menggunakan printsecara langsung, atau loggingsebagai gantinya.

print >>sys.stderr, 'Goodbye, cruel world!'
Ignacio Vazquez-Abrams
sumber
2
Ini secara teknis bukan WSGI yang valid, dan akan memicu kesalahan di lingkungan yang lebih ketat.
Paul McMillan
13
Tidak ada yang salah dengan menggunakan 'print' dengan 'sys.stderr' sejauh WSGI berjalan dan seharusnya tidak memicu kesalahan.
Graham Dumpleton
Saya mengimpor sys tetapi tampaknya ini tidak berhasil untuk saya.
Hack-R
17
Ini tidak bekerja dengan Python 3, lihat di sini . Anda membutuhkanprint("Goodbye cruel world!", file=sys.stderr)
kapulaga
103

Berikut adalah solusi berbasis logging Django. Ini menggunakan pengaturan DEBUG daripada benar-benar memeriksa apakah Anda menjalankan server pengembangan atau tidak, tetapi jika Anda menemukan cara yang lebih baik untuk memeriksanya, itu harus mudah beradaptasi.

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

lihat https://docs.djangoproject.com/en/dev/topics/logging/ untuk detailnya.

m01
sumber
8
juga cobaLOGGING['loggers'][logger]['handlers'] += ['console']
Nir Levy
@ m01: Setelah mengkonfigurasi ini ke settings.py, bagaimana cara menggunakan ini untuk tujuan pencetakan? Terima kasih
Niks Jain
Saya meletakkan kode dari jawaban saya settings.pyke bawah, dan mengatur DEBUG = True(cari pengaturan itu di dekat bagian atas dalam file yang sama). Kemudian, saya menjalankan python manage.py runserverdari terminal (lihat dokumen django untuk detailnya), dan pesan log akan muncul di jendela terminal. Dalam produksi, saya akan menggunakan settings.py yang berbeda, di mana DEBUG = False- pesan log masuk /path/to/your/file.log.
m01
Lekukanmu membuatku pusing. Terima kasih atas infonya, berhasil!
ioan
Terima kasih! Saya telah membuat beberapa perubahan pada lekukan, saya harap sekarang lebih baik
m01
27

Anda dapat mengkonfigurasi logging di settings.pyfile Anda .

Satu contoh:

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

Namun itu tergantung pada pengaturan DEBUG, dan mungkin Anda tidak ingin khawatir tentang bagaimana pengaturannya. Lihat jawaban ini di Bagaimana saya dapat mengetahui apakah aplikasi Django saya berjalan pada server pengembangan atau tidak? untuk cara yang lebih baik dalam menulis bersyarat itu. Edit: contoh di atas adalah dari proyek Django 1.1, konfigurasi pencatatan di Django agak berubah sejak versi itu.

bennylope
sumber
Saya tidak ingin bergantung pada DEBUG; Saya lebih suka bergantung pada mekanisme deteksi server-dev yang ditautkan di pos lain itu. Tetapi mekanisme pendeteksian postingan lain bergantung pada akses ke instance permintaan. Bagaimana saya bisa mendapatkan contoh permintaan di settings.py?
Justin Grant
4

Saya menggunakan ini:

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
sumber
0

Anda dapat melakukan ini dengan cukup mudah dengan tagalog(https://github.com/dorkitude/tagalog)

Misalnya, saat modul python standar menulis ke objek file dibuka dalam mode tambahkan, modul App Engine (https://github.com/dorkitude/tagalog/blob/master/tagalog_appengine.py) menggantikan perilaku ini dan sebagai gantinya menggunakan logging.INFO.

Untuk mendapatkan perilaku ini dalam proyek App Engine, cukup lakukan:

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

Anda dapat memperluas modul sendiri dan menimpa fungsi log tanpa banyak kesulitan.

Kyle Wild
sumber
0

Ini bekerja cukup baik di local.py saya, menyelamatkan saya mengacaukan logging biasa:

from .settings import *

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