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


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


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

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': '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

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

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.