Wo ist ein vollständiges Beispiel für logging.config.dictConfig?

132

Ich würde gerne dictConfig verwenden , aber die Dokumentation ist etwas abstrakt. Wo finde ich ein konkretes Beispiel für das verwendete Wörterbuch, das kopiert und eingefügt werden kann dictConfig?

David Wolever
quelle

Antworten:

200

Wie wäre es hier!

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

Verwendung:

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

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

Wenn Sie zu viele Protokolle von Paketen von Drittanbietern sehen, führen Sie diese Konfiguration unbedingt aus, logging.config.dictConfig(LOGGING_CONFIG) bevor Sie die Pakete von Drittanbietern importieren.

Referenz: https://docs.python.org/3/library/logging.config.html#configuration-dictionary-schema

Dave
quelle
11
Es gibt einen alternativen Ort für die Angabe des rootLoggers: auf der obersten Ebene des Wörterbuchs. Es wird in den Dokumenten beschrieben , hat Vorrang vor dem ['loggers']['']Vorhandensein beider, ist aber meiner Meinung ['loggers']['']nach logischer. Siehe auch Diskussion hier
Antony Hatchkins
2
All diese prägnanten, schönen YAML-Schnipsel in den python logging.config-Dokumenten können einfach nicht direkt gelesen werden. Schade.
JimB
Ist das nicht Django-spezifisch? Was ist, wenn ich ein anderes Framework (Flasche, Flasche usw.) verwende oder nicht einmal an einer Webanwendung arbeite?
Adam Parkin
Es fühlt sich wie ein Betrüger an, 'disable_existing_loggers': Falseda Sie dann vielleicht nicht das ganze Tuch konfigurieren, sondern vielleicht etwas wiederverwenden, das bereits vorhanden ist. Wenn Sie es einstellen True, bekomme ich anscheinend keine Ausgabe.
Nick T
Hallo @ Dave, wie kann ich eine benutzerdefinierte Klasse formatab verwenden formatters?
Rafa Acioly
40

Die akzeptierte Antwort ist nett! Aber was wäre, wenn man mit etwas weniger Komplexem beginnen könnte? Das Protokollierungsmodul ist sehr leistungsfähig und die Dokumentation ist ein bisschen überwältigend, besonders für Anfänger. Zu Beginn müssen Sie jedoch keine Formatierer und Handler konfigurieren. Sie können es hinzufügen, wenn Sie herausfinden, was Sie wollen.

Beispielsweise:

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')
theotheo
quelle
Dies ist zumindest in meinem Fall das relevantere / nützlichere Beispiel. Es war das Finale logging.info('Hello, log'), das die Dinge für mich zum Klicken brachte. Die Verwirrung in der Dokumentation ist, dass wir mit dictConfig keine getLoggerdieser Aktionen mehr ausführen müssen .
Mike Williamson
@theotheo Können Sie den leeren Schlüssel erklären '': { 'level': 'INFO'...und warum er ohne ihn nicht funktioniert (z. B. wenn Sie den leeren Wert in einen gültigen Wert standard
ändern,
1
@ MikeWilliamson: Es kann jedoch nützlich sein, trotzdem anzurufen, getLogger()wenn Sie mehrere Logger mit unterschiedlichen Namen möchten. Jeder dieser Logger erbt die Konfiguration vom Root-Logger.
Elias Strehle
3
@ MikeWilliamson getLoggerist immer optional. Wenn Sie die logging.info()Methode direkt verwenden, wird der Root-Logger verwendet, während getLogger()Sie verschiedene Logger mit unterschiedlichen Namen und Ebenen verwenden können.
Sox mit Monica
7

Beispiel mit Stream Handler, File Handler, Rotating File Handler und SMTP Handler

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': '[email protected]',
            'toaddrs': ['[email protected]', '[email protected]'],
            '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)
Yogesh Yadav
quelle
4

Ich habe unten die Standardkonfiguration für Django v1.11.15 gefunden , hoffe, es hilft

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,
        },
    }
}
天才 小飞 猫
quelle
4
Dieses Beispiel ist in Ordnung, aber ich denke, um über die akzeptierte Antwort hinauszugehen, würde eine Erklärung helfen.
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
wcc526
quelle