Registrazione predefinita di Django Setup


94

Non riesco a capire come impostare un logger "predefinito" per la mia installazione di Django. Vorrei usare la nuova LOGGINGimpostazione di Django 1.3 in settings.py.

Ho esaminato l'esempio di Django Logging Doc , ma mi sembra che abbiano configurato solo gestori che eseguiranno la registrazione per particolari logger. Nel caso del loro esempio, hanno impostato il gestore per i logger denominato "django", "django.request" e "myproject.custom".

Tutto quello che voglio fare è impostare un valore predefinito logging.handlers.RotatingFileHandlerche gestirà tutti i logger per impostazione predefinita. cioè, se creo un nuovo modulo da qualche parte nel mio progetto ed è indicato da qualcosa del tipo my_app_name.my_new_module:, dovrei essere in grado di farlo e fare in modo che tutti i log andranno ai log dei file rotanti.

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

Risposte:


153

Capito...

È possibile impostare la 'cattura tutti' logger facendo riferimento con la stringa vuota: ''.

Ad esempio, nella seguente configurazione vengono salvati tutti gli eventi di registro logs/mylog.log, ad eccezione degli django.requesteventi di registro in cui verranno salvati logs/django_request.log. Poiché 'propagate'è impostato su Falseper il mio django.requestlogger, l'evento di log non raggiungerà mai il logger "catch all".

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, i documenti di Django su questo non sono fonte di confusione. Grazie per questo.

5
Piccola correzione: il commento implica che il logging sql sarebbe influenzato dal logger django.request. Per reindirizzare la registrazione sql, devi definire un logger per "django.db". Il logger django.request gestisce le risposte http 5xx e 4xx.
rych

In questo aiuta altri niubbi come me: il logger creerà i file di log, ma devi logs/prima creare la cartella :-). Altrimenti riceverai un errore quando corri ./manange.py runserver. @ Chris W. Grazie per le tue impostazioni di registrazione di esempio. Mi ha aiutato molto!
hobbes3

3
@arindamroychowdhury Con la configurazione di cui sopra, se lo fai, logger = logging.getLogger('foo'); logger.warn('bar');il defaultgestore catturerà quel registro e qualcosa del genere <time> WARN: foo: barfinirà inlogs/mylog.log
Chris W.

8
Grazie, sembra che questo "" significhi root logger. Questa utile informazione non è stata trovata nella documentazione di Django.
Eino Mäkitalo

25

Come hai detto nella tua risposta , Chris, un'opzione per definire un logger predefinito è usare la stringa vuota come chiave.

Tuttavia, penso che il modo previsto sia definire un logger speciale sotto la rootchiave del dizionario di configurazione del logging. Ho trovato questo nella documentazione di Python :

root : questa sarà la configurazione per il logger di root. L'elaborazione della configurazione sarà come per qualsiasi logger, tranne per il fatto che l' propagateimpostazione non sarà applicabile.

Ecco la configurazione dalla tua risposta modificata per utilizzare la rootchiave:

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

Per essere onesti, non vedo alcuna differenza nel comportamento tra le due configurazioni. Sembra che la definizione di un logger con una chiave stringa vuota modificherà il logger di root, perché logging.getLogger('')restituirà il logger di root.

L'unica ragione per cui preferisco 'root'sopra ''è che è esplicito su come modificare il logger principale. Nel caso fossi curioso, 'root'sovrascrive ''se definisci entrambi, solo perché la voce di root viene elaborata per ultima.


Sì, è vero, scusa per l'errata correzione! Sebbene l'uso di "" invece di "root" sia in qualche modo logico, trovo ancora un po 'incoerente da parte loro spostare l' rootentrata nella radice del dict nel processo di transizione altrimenti fluida dalla logica fileConfig 2.6 a quella dictConfig 2.7.
Antony Hatchkins

2
import logging
logger = logging.getLogger(__name__)

dopo aggiungi:

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

possiamo cambiare formato in:

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

o

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

0

Ho fatto un rapido esempio per verificare quale configurazione viene utilizzata quando sia la rootchiave che il ''logger vuoto sono referenziati in 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")

Stampa il seguente risultato:

[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

indicando che la configurazione sotto rootchiave ha la priorità più alta. Se il blocco viene rimosso, il risultato è:

[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

In entrambi i casi, sono stato in grado di eseguire il debug e determinare che tutte e tre logger ( l1, l2e root) riferimento la stessa istanza logger, il logger principale.

Spero che questo possa aiutare gli altri che, come me, erano confusi dai 2 diversi modi per configurare il logger di root.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.