Di mana contoh lengkap logging.config.dictConfig?

133

Saya ingin menggunakan dictConfig , tetapi dokumentasinya agak abstrak. Di mana saya dapat menemukan contoh konkret, salin + tempel dari kamus yang digunakan dictConfig?

David Wolever
sumber

Jawaban:

201

Bagaimana di sini!

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

Pemakaian:

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

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

Jika Anda melihat terlalu banyak log dari paket pihak ketiga, pastikan untuk menjalankan konfigurasi ini logging.config.dictConfig(LOGGING_CONFIG) sebelum paket pihak ketiga diimpor.

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

Dave
sumber
11
Ada tempat alternatif untuk menentukan rootlogger: di tingkat atas kamus. Ini dijelaskan dalam dokumen , memiliki preferensi daripada ['loggers']['']ketika keduanya hadir, tetapi menurut pendapat saya, ['loggers']['']lebih logis. Lihat juga diskusi di sini
Antony Hatchkins
2
Semua cuplikan singkat YAML yang indah di python logging.config docs tidak dapat dibaca secara langsung. Kekecewaan.
JimB
Bukankah ini khusus Django? Bagaimana jika saya menggunakan kerangka kerja yang berbeda (Labu, Botol, dll), atau bahkan tidak bekerja pada aplikasi web?
Adam Parkin
Rasanya seperti cheat dengan 'disable_existing_loggers': Falsemaka Anda mungkin tidak mengkonfigurasi seluruh kain, tapi mungkin menggunakan kembali sesuatu yang sudah ada di sana .. Jika Anda mengaturnya Truemaka saya sepertinya tidak mendapatkan hasil.
Nick T
Hai @ Dave, bagaimana saya bisa menggunakan kelas kustom formatdari formatters?
Rafa Acioly
40

Jawaban yang diterima bagus! Tetapi bagaimana jika seseorang dapat memulai dengan sesuatu yang kurang kompleks? Modul logging adalah hal yang sangat kuat dan dokumentasinya agak berlebihan terutama bagi pemula. Tetapi untuk awalnya Anda tidak perlu mengkonfigurasi formatters dan handler. Anda dapat menambahkannya ketika Anda mengetahui apa yang Anda inginkan.

Sebagai contoh:

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
sumber
Ini adalah contoh yang lebih relevan / berguna, setidaknya dalam kasus saya. Itu adalah final logging.info('Hello, log')yang membuat segalanya menjadi penting bagi saya. Kebingungan dalam dokumentasi adalah bahwa dengan dictConfig kita tidak perlu lagi melakukan getLoggeratau tindakan-tindakan tersebut.
Mike Williamson
@theotheo Bisakah Anda menjelaskan kunci kosong '': { 'level': 'INFO'...dan mengapa itu tidak berfungsi tanpa itu (mis. ketika mengubah nilai kosong ke nilai yang valid sepertistandard
user9074332
1
@MikeWilliamson: Meskipun demikian, tetap berguna getLogger()jika Anda ingin beberapa penebang dengan nama yang berbeda. Setiap logger ini mewarisi konfigurasi dari logger root.
Elias Strehle
3
@MikeWilliamson getLoggerselalu opsional. Saat menggunakan logging.info()metode ini secara langsung logger root digunakan, sementara dengan getLogger()Anda dapat memiliki logger yang berbeda, dengan nama dan tingkat differents.
sox dengan Monica
8

Contoh dengan Stream Handler, File Handler, Rotating File Handler dan 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
sumber
4

Saya menemukan konfigurasi default Django v1.11.15 di bawah ini, semoga membantu

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,
        },
    }
}
天才 小飞 猫
sumber
4
Contoh ini baik-baik saja, tetapi saya pikir untuk menonjol di luar jawaban yang diterima, beberapa penjelasan akan membantu.
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
sumber