Django Kurulumu Varsayılan Günlük Kaydı


94

Django kurulumum için "varsayılan" bir günlükçüyü nasıl kuracağımı çözemiyorum. Django 1.3'ün yeni LOGGINGayarını settings.py.

Django Logging Doc örneğine baktım ama bana öyle geliyor ki sadece belirli logger'lar için loglama yapacak işleyiciler kuruyorlar. Örneklerinde 'django', 'django.request' ve 'myproject.custom' adlı kaydediciler için işleyici kurarlar.

Tüm yapmak istediğim, varsayılan olarak logging.handlers.RotatingFileHandlertüm kaydedicileri işleyecek bir varsayılan ayarlamak . Örneğin, projemde bir yerde yeni bir modül yaparsam ve şu şekilde ifade edilirse my_app_name.my_new_module, bunu yapabilmeli ve tüm günlük kayıtlarını dönen dosya günlüklerine gitmeliyim.

# 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`!

Yanıtlar:


154

Anladım ...

Sen boş dize ile başvurarak 'bütün yakalamak' logger ayarlayın: ''.

Örnek olarak, aşağıdaki kurulumda logs/mylog.log, kaydedilecek django.requestgünlük olayları haricinde kaydedilecek tüm günlük olaylarına sahibim logs/django_request.log. Çünkü 'propagate'ayarlandığında Falsebenim için django.requestkaydedici, kayıt olayı 'tüm yakalamak' logger ulaşmak asla.

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
        },
    }
}

2
Chris, bu konudaki Django dokümanları kafa karıştırıcı değil. Bunun için teşekkürler.

5
Küçük düzeltme: Yorum, sql günlüğünün django.request logger tarafından etkileneceği anlamına gelir. Sql günlüğünü yeniden yönlendirmek için, 'django.db' için bir kaydedici tanımlarsınız. Django.request logger, 5xx ve 4xx http yanıtlarını işler.
rych

Bu, benim gibi diğer noob'lara yardımcı olur: Logger, günlük dosyalarını oluşturacaktır, ancak önce logs/klasörü oluşturmanız gerekir :-). Aksi takdirde, çalıştırdığınızda bir hata alırsınız ./manange.py runserver. @Chris W. Örnek günlük kaydı ayarlarınız için teşekkürler. Bana çok yardımcı oldu!
hobbes3

3
Yukarıdaki yapılandırmayla @arindamroychowdhury bunu yaparsanız logger = logging.getLogger('foo'); logger.warn('bar');o zaman defaultböyle işleyicisi o günlüğü ve bir şeyler yakalayacak <time> WARN: foo: bariçinde sona ereceklogs/mylog.log
Chris W.

8
Teşekkürler öyle görünüyor ki bu '' kök kaydedici anlamına geliyor. Bu yararlı bilgi, Django belgelerinde bulunamadı.
Eino Mäkitalo 13

25

Cevabınızda söylediğiniz gibi Chris, varsayılan bir günlükçüyü tanımlamanın bir yolu, boş dizeyi anahtarı olarak kullanmaktır.

Ancak, bence amaçlanan yol, rootgünlük kaydı yapılandırma sözlüğünün anahtarı altında özel bir kaydedici tanımlamaktır . Bunu Python belgelerinde buldum :

root - bu, kök kaydedicinin yapılandırması olacaktır. Yapılandırmanın işlenmesi, propagateayarın uygulanamayacağı durumlar dışında herhangi bir kaydedicide olduğu gibi olacaktır.

rootAnahtarı kullanmak için cevabınızın yapılandırması şu şekildedir:

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
        },
    }
}

Adil olmak gerekirse, iki konfigürasyon arasında herhangi bir davranış farkı göremiyorum. Görünüşe göre boş bir dize anahtarına sahip bir günlük kaydedici tanımlamak, kök günlükçüyü değiştirecektir, çünkü logging.getLogger('')kök günlükçüyü döndürecektir.

Tercihim tek nedeni 'root'üzerinde ''kök logger değiştirmeyle ilgili açık olmasıdır. Merak ettiyseniz, yalnızca kök giriş en son işlendiği için ikisini de tanımlarsanız 'root'geçersiz kılınır ''.


Evet, doğru, yanlış düzeltme için özür dilerim! 'Kök' yerine '' kullanmak biraz mantıklı olsa da root, 2.6 fileConfig mantığından 2.7 dictConfig mantığına yumuşak geçiş sürecinde girişi diktenin köküne taşımayı yine de biraz tutarsız buluyorum .
Antony Hatchkins

2
import logging
logger = logging.getLogger(__name__)

Ekledikten sonra:

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

formatı şu şekilde değiştirebiliriz:

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

veya

format = '%(name)s %(asctime)s %(levelname)s %(message)s',

0

Yapılandırma diktesinde hem rootanahtar hem de boş ''kaydediciye başvurulduğunda hangi yapılandırmanın kullanıldığını kontrol etmek için hızlı bir örnek yaptım .

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

Aşağıdaki sonucu yazdırır:

[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

rootanahtar altındaki yapılandırmanın en yüksek önceliğe sahip olduğunu belirtir . Blok kaldırılırsa sonuç şudur:

[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

Her iki durumda da, hata ayıklama ve her üç kaydediciler (belirlemek başardı l1, l2ve root) aynı logger örneği, kök logger başvurulan.

Umarım bu, benim gibi, kök kaydediciyi yapılandırmanın 2 farklı yolu ile kafası karışan başkalarına yardımcı olur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.