Pencatatan Default Pengaturan Django

94

Saya tidak dapat menemukan cara untuk mengatur pencatat "default" untuk instalasi Django saya. Saya ingin menggunakan LOGGINGpengaturan baru Django 1.3 di settings.py.

Saya telah melihat contoh Dokumen Pencatatan Django , tetapi bagi saya sepertinya mereka hanya penangan pengaturan yang akan melakukan pencatatan untuk penebang tertentu. Dalam kasus contoh mereka, mereka menyiapkan penangan untuk penebang bernama 'django', 'django.request', dan 'myproject.custom'.

Yang ingin saya lakukan adalah mengatur default logging.handlers.RotatingFileHandleryang akan menangani semua logger secara default. yaitu, jika saya membuat modul baru di suatu tempat dalam proyek saya dan itu dilambangkan dengan sesuatu seperti:, my_app_name.my_new_modulesaya harus dapat melakukan ini dan memiliki semua pencatatan ke log file berputar.

# In file './my_app_name/my_new_module.py'
import logging
logger = logging.getLogger('my_app_name.my_new_module')
logger.debug('Hello logs!') # <-- This should get logged to my RotatingFileHandler that I setup in `settings.py`!
Chris W.
sumber

Jawaban:

154

Menemukannya...

Anda mengatur 'menangkap semua' logger dengan referensi dengan string kosong: ''.

Sebagai contoh, dalam pengaturan berikut saya memiliki semua peristiwa log yang disimpan ke logs/mylog.log, dengan pengecualian django.requestperistiwa log yang akan disimpan ke logs/django_request.log. Karena 'propagate'disetel ke Falseuntuk django.requestlogger saya , peristiwa log tidak akan pernah mencapai logger 'tangkap semua'.

LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'formatters': {
        'standard': {
            'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
        },
    },
    'handlers': {
        'default': {
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': 'logs/mylog.log',
            'maxBytes': 1024*1024*5, # 5 MB
            'backupCount': 5,
            'formatter':'standard',
        },  
        'request_handler': {
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': 'logs/django_request.log',
            'maxBytes': 1024*1024*5, # 5 MB
            'backupCount': 5,
            'formatter':'standard',
        },
    },
    'loggers': {
        '': {
            'handlers': ['default'],
            'level': 'DEBUG',
            'propagate': True
        },
        'django.request': {
            'handlers': ['request_handler'],
            'level': 'DEBUG',
            'propagate': False
        },
    }
}
Chris W.
sumber
2
Chris, dokumen Django tentang ini tidak membingungkan. Terima kasih untuk ini.
5
Koreksi kecil: komentar menyiratkan penebangan sql akan dipengaruhi oleh logger django.request. Untuk mengalihkan pencatatan sql, Anda akan menentukan pencatat untuk 'django.db'. Pencatat django.request menangani tanggapan http 5xx & 4xx.
rych
Dalam hal ini membantu noob lain seperti saya: Logger akan membuat file log, tetapi Anda harus membuat logs/folder terlebih dahulu :-). Jika tidak, Anda akan mendapatkan kesalahan saat menjalankan ./manange.py runserver. @ Chris W. Terima kasih untuk contoh pengaturan logging Anda. Itu sangat membantu saya!
Hobbes3
3
@arindamroychowdhury Dengan konfigurasi di atas jika Anda melakukannya logger = logging.getLogger('foo'); logger.warn('bar');maka defaultpawang akan menangkap logging itu dan sesuatu seperti itu <time> WARN: foo: barakan berakhir dilogs/mylog.log
Chris W.
8
Terima kasih, tampaknya ini '' berarti root logger. Bagian informasi yang berguna ini tidak ditemukan dalam dokumentasi Django.
Eino Mäkitalo
25

Seperti yang Anda katakan dalam jawaban Anda , Chris, satu opsi untuk mendefinisikan logger default adalah menggunakan string kosong sebagai kuncinya.

Namun, menurut saya cara yang dimaksudkan adalah dengan mendefinisikan logger khusus di bawah rootkunci kamus konfigurasi logging. Saya menemukan ini di dokumentasi Python :

root - ini akan menjadi konfigurasi untuk root logger. Pemrosesan konfigurasi akan dilakukan seperti pada logger mana pun, kecuali bahwa propagatepengaturan tersebut tidak dapat diterapkan.

Berikut konfigurasi dari jawaban Anda yang diubah untuk menggunakan rootkunci:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'formatters': {
        'standard': {
            'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
        },
    },
    'handlers': {
        'default': {
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': 'logs/mylog.log',
            'maxBytes': 1024*1024*5, # 5 MB
            'backupCount': 5,
            'formatter':'standard',
        },  
        'request_handler': {
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': 'logs/django_request.log',
            'maxBytes': 1024*1024*5, # 5 MB
            'backupCount': 5,
            'formatter':'standard',
        },
    },
    'root': {
        'handlers': ['default'],
        'level': 'DEBUG'
    },
    'loggers': {
        'django.request': {
            'handlers': ['request_handler'],
            'level': 'DEBUG',
            'propagate': False
        },
    }
}

Agar adil, saya tidak dapat melihat perbedaan perilaku antara kedua konfigurasi tersebut. Tampaknya mendefinisikan logger dengan kunci string kosong akan mengubah logger root, karena logging.getLogger('')akan mengembalikan logger root.

Satu-satunya alasan saya lebih memilih 'root'lebih ''adalah bahwa itu adalah eksplisit tentang memodifikasi akar logger. Jika Anda penasaran, 'root'ganti ''jika Anda mendefinisikan keduanya, hanya karena entri root diproses terakhir.

Don Kirkby
sumber
Ya, benar, maaf atas kesalahan koreksi! Meskipun menggunakan '' alih-alih 'root' agak logis, saya masih merasa agak tidak konsisten untuk memindahkan rootentri ke root dict dalam proses transisi yang mulus dari logika fileConfig 2.6 ke logika 2.7 dictConfig.
Antony Hatchkins
2
import logging
logger = logging.getLogger(__name__)

setelah menambahkan:

logging.basicConfig(
    level = logging.DEBUG,
    format = '%(name)s %(levelname)s %(message)s',
)

kami dapat mengubah format menjadi:

format = '"%(levelname)s:%(name)s:%(message)s"  ',

atau

format = '%(name)s %(asctime)s %(levelname)s %(message)s',
Sérgio
sumber
0

Saya membuat contoh cepat untuk memeriksa konfigurasi apa yang digunakan ketika rootkunci dan ''logger kosong direferensikan di config dict.

import logging.config

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'fmt1': {
            'format': '[FMT1] %(asctime)-15s %(message)s',
        },
        'fmt2': {
            'format': '[FMT2] %(asctime)-15s %(message)s',
        }
    },
    'handlers': {
        'console1': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'fmt1',
        },
        'console2': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'fmt2',
        },
    },
    # First config for root logger: console1 -> fmt1
    'root': {
        'handlers': ['console1'],
        'level': 'DEBUG',
        'propagate': True,
    },
    'loggers': {
        # Second config for root logger: console2 -> fmt2
        '': {
            'handlers': ['console2'],
            'level': 'DEBUG',
            'propagate': True,
        },
    },
}

logging.config.dictConfig(LOGGING)

l1 = logging.getLogger()
l2 = logging.getLogger('')
root = logging.root

l1.info("l1")
l2.info("l2")
root.info("root logger")

Mencetak hasil sebagai berikut:

[FMT1] 2018-12-18 17:24:47,691 l1
[FMT1] 2018-12-18 17:24:47,691 l2
[FMT1] 2018-12-18 17:24:47,691 root logger

menunjukkan bahwa konfigurasi di bawah rootkunci memiliki prioritas tertinggi. Jika blok dihilangkan, hasilnya adalah:

[FMT2] 2018-12-18 17:25:43,757 l1
[FMT2] 2018-12-18 17:25:43,757 l2
[FMT2] 2018-12-18 17:25:43,757 root logger

Dalam kedua kasus tersebut, saya dapat men-debug dan menentukan bahwa ketiga logger ( l1, l2dan root) mereferensikan instance logger yang sama, root logger.

Harapan itu akan membantu orang lain yang, seperti saya, bingung dengan 2 cara berbeda untuk mengkonfigurasi logger root.

Antwane
sumber