Gdzie jest pełny przykład logowania.config.dictConfig?


Odpowiedzi:


201

A może tutaj!

LOGGING_CONFIG = { 
    'version': 1,
    'disable_existing_loggers': True,
    'formatters': { 
        'standard': { 
            'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
        },
    },
    'handlers': { 
        'default': { 
            'level': 'INFO',
            'formatter': 'standard',
            'class': 'logging.StreamHandler',
            'stream': 'ext://sys.stdout',  # Default is stderr
        },
    },
    'loggers': { 
        '': {  # root logger
            'handlers': ['default'],
            'level': 'WARNING',
            'propagate': False
        },
        'my.packg': { 
            'handlers': ['default'],
            'level': 'INFO',
            'propagate': False
        },
        '__main__': {  # if __name__ == '__main__'
            'handlers': ['default'],
            'level': 'DEBUG',
            'propagate': False
        },
    } 
}

Stosowanie:

# Run once at startup:
logging.config.dictConfig(LOGGING_CONFIG)

# Include in each module:
log = logging.getLogger(__name__)
log.debug("Logging is configured.")

Jeśli widzisz zbyt wiele dzienników z pakietów innych firm, pamiętaj, aby uruchomić tę konfigurację przy użyciu logging.config.dictConfig(LOGGING_CONFIG) przed zaimportowaniem pakietów innych firm.

Źródła: https://docs.python.org/3/library/logging.config.html#configuration-dictionary-schema


11
Istnieje alternatywne miejsce na określenie rootloggera: na najwyższym poziomie słownika. Jest to opisane w dokumentach , ma pierwszeństwo przed sytuacją , ['loggers']['']gdy oba są obecne, ale moim zdaniem ['loggers']['']jest bardziej logiczne. Zobacz także dyskusję tutaj
Antony Hatchkins

2
Wszystkie te zwięzłe, piękne fragmenty YAML w dokumentach python logging.config po prostu nie mogą być czytane bezpośrednio. Porażka.
JimB

Czy to nie jest specyficzne dla django? Co jeśli używam innego frameworka (Flask, Bottle itp.) Lub nawet nie pracuję nad aplikacją internetową?
Adam Parkin

Wydaje się, że to oszustwo, 'disable_existing_loggers': Falseponieważ wtedy być może nie konfigurujesz go w całości, ale może ponownie używasz czegoś, co już tam jest True.
Nick T

Cześć @Dave, jak mogę używać niestandardowej klasy w programie formatod formatters?
Rafa Acioly

40

Przyjęta odpowiedź jest miła! Ale co by było, gdyby można było zacząć od czegoś mniej złożonego? Moduł logowania to bardzo potężna rzecz, a dokumentacja jest nieco przytłaczająca, szczególnie dla początkujących. Ale na początku nie musisz konfigurować elementów formatujących i programów obsługi. Możesz go dodać, kiedy dowiesz się, czego chcesz.

Na przykład:

import logging.config

DEFAULT_LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'loggers': {
        '': {
            'level': 'INFO',
        },
        'another.module': {
            'level': 'DEBUG',
        },
    }
}

logging.config.dictConfig(DEFAULT_LOGGING)

logging.info('Hello, log')

To jest bardziej odpowiedni / przydatny przykład, przynajmniej w moim przypadku. To był finał, logging.info('Hello, log')który sprawił, że wszystko się u mnie zaskoczyło. Zamieszanie w dokumentacji polega na tym, że dzięki dictConfig nie musimy już wykonywać getLoggerani żadnej z tych czynności.
Mike Williamson

@theotheo Czy możesz wyjaśnić pusty klucz '': { 'level': 'INFO'...i dlaczego nie działa bez niego (np. przy zmianie pustej wartości na prawidłową wartość, na przykładstandard
user9074332

1
@MikeWilliamson: Może być jednak przydatne, aby nadal dzwonić, getLogger()jeśli chcesz mieć wiele rejestratorów o różnych nazwach. Każdy z tych programów rejestrujących dziedziczy konfigurację z głównego programu rejestrującego.
Elias Strehle,

3
@MikeWilliamson getLoggerjest zawsze opcjonalne. Używając tej logging.info()metody bezpośrednio, używany jest główny rejestrator, podczas gdy getLogger()możesz mieć różne rejestratory, z różnymi nazwami i poziomami.
sox z Monicą

8

Przykład z obsługą strumienia, programem obsługi plików, obrotowym programem obsługi plików i programem obsługi SMTP

from logging.config import dictConfig

LOGGING_CONFIG = {
    'version': 1,
    'loggers': {
        '': {  # root logger
            'level': 'NOTSET',
            'handlers': ['debug_console_handler', 'info_rotating_file_handler', 'error_file_handler', 'critical_mail_handler'],
        },
        'my.package': { 
            'level': 'WARNING',
            'propagate': False,
            'handlers': ['info_rotating_file_handler', 'error_file_handler' ],
        },
    },
    'handlers': {
        'debug_console_handler': {
            'level': 'DEBUG',
            'formatter': 'info',
            'class': 'logging.StreamHandler',
            'stream': 'ext://sys.stdout',
        },
        'info_rotating_file_handler': {
            'level': 'INFO',
            'formatter': 'info',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': 'info.log',
            'mode': 'a',
            'maxBytes': 1048576,
            'backupCount': 10
        },
        'error_file_handler': {
            'level': 'WARNING',
            'formatter': 'error',
            'class': 'logging.FileHandler',
            'filename': 'error.log',
            'mode': 'a',
        },
        'critical_mail_handler': {
            'level': 'CRITICAL',
            'formatter': 'error',
            'class': 'logging.handlers.SMTPHandler',
            'mailhost' : 'localhost',
            'fromaddr': 'monitoring@domain.com',
            'toaddrs': ['dev@domain.com', 'qa@domain.com'],
            'subject': 'Critical error with application name'
        }
    },
    'formatters': {
        'info': {
            'format': '%(asctime)s-%(levelname)s-%(name)s::%(module)s|%(lineno)s:: %(message)s'
        },
        'error': {
            'format': '%(asctime)s-%(levelname)s-%(name)s-%(process)d::%(module)s|%(lineno)s:: %(message)s'
        },
    },

}

dictConfig(LOGGING_CONFIG)

4

Znalazłem domyślną konfigurację Django v1.11.15 poniżej, mam nadzieję, że to pomoże

DEFAULT_LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse',
        },
        'require_debug_true': {
            '()': 'django.utils.log.RequireDebugTrue',
        },
    },
    'formatters': {
        'django.server': {
            '()': 'django.utils.log.ServerFormatter',
            'format': '[%(server_time)s] %(message)s',
        }
    },
    'handlers': {
        'console': {
            'level': 'INFO',
            'filters': ['require_debug_true'],
            'class': 'logging.StreamHandler',
        },
        'django.server': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'django.server',
        },
        'mail_admins': {
            'level': 'ERROR',
            'filters': ['require_debug_false'],
            'class': 'django.utils.log.AdminEmailHandler'
        }
    },
    'loggers': {
        'django': {
            'handlers': ['console', 'mail_admins'],
            'level': 'INFO',
        },
        'django.server': {
            'handlers': ['django.server'],
            'level': 'INFO',
            'propagate': False,
        },
    }
}

4
Ten przykład jest w porządku, ale myślę, że aby wyróżnić się poza akceptowaną odpowiedzią, pomocne byłoby pewne wyjaśnienie.
Mike Williamson

-7
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import logging
import logging.handlers
from logging.config import dictConfig

logger = logging.getLogger(__name__)

DEFAULT_LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
}
def configure_logging(logfile_path):
    """
    Initialize logging defaults for Project.

    :param logfile_path: logfile used to the logfile
    :type logfile_path: string

    This function does:

    - Assign INFO and DEBUG level to logger file handler and console handler

    """
    dictConfig(DEFAULT_LOGGING)

    default_formatter = logging.Formatter(
        "[%(asctime)s] [%(levelname)s] [%(name)s] [%(funcName)s():%(lineno)s] [PID:%(process)d TID:%(thread)d] %(message)s",
        "%d/%m/%Y %H:%M:%S")

    file_handler = logging.handlers.RotatingFileHandler(logfile_path, maxBytes=10485760,backupCount=300, encoding='utf-8')
    file_handler.setLevel(logging.INFO)

    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.DEBUG)

    file_handler.setFormatter(default_formatter)
    console_handler.setFormatter(default_formatter)

    logging.root.setLevel(logging.DEBUG)
    logging.root.addHandler(file_handler)
    logging.root.addHandler(console_handler)



[31/10/2015 22:00:33] [DEBUG] [yourmodulename] [yourfunction_name():9] [PID:61314 TID:140735248744448] this is logger infomation from hello module
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.