Đâu là một ví dụ đầy đủ về log.config.dictConfig?


133

Tôi muốn sử dụng dictConfig , nhưng tài liệu hơi trừu tượng một chút. Tôi có thể tìm một ví dụ cụ thể, sao chép + có thể dán của từ điển được sử dụng ở dictConfigđâu?

Câu trả lời:


201

Làm thế nào về đây!

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

Sử dụng:

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

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

Trong trường hợp bạn thấy quá nhiều nhật ký từ các gói của bên thứ ba, hãy đảm bảo chạy cấu hình này bằng cách sử dụng logging.config.dictConfig(LOGGING_CONFIG) trước khi các gói của bên thứ ba được nhập.

Tham khảo: https://docs.python.org/3/l Library / log.config.html # configuration-dipedia-schema


11
Có một nơi khác để chỉ định rootlogger: ở cấp cao nhất của từ điển. Nó được mô tả trong các tài liệu , có ưu tiên hơn ['loggers']['']khi cả hai có mặt, nhưng theo tôi, ['loggers']['']là hợp lý hơn. Xem thêm thảo luận tại đây
Antony Hatchkins

2
Tất cả những đoạn ngắn YAML ngắn gọn, đẹp đẽ trong tài liệu python log.config không thể đọc trực tiếp. Bummer.
JimB

Đây không phải là django cụ thể? Điều gì xảy ra nếu tôi đang sử dụng một khung khác (Bình, Chai, v.v.) hoặc thậm chí không hoạt động trên ứng dụng web?
Adam Parkin

Cảm giác giống như một trò gian lận 'disable_existing_loggers': Falsekhi bạn có thể không cấu hình toàn bộ trang phục, nhưng có thể sử dụng lại một cái gì đó đã có sẵn .. Nếu bạn đặt nó Truethì tôi dường như không nhận được bất kỳ đầu ra nào.
Nick T

Xin chào @Dave, làm thế nào tôi có thể sử dụng một lớp tùy chỉnh formattừ formatters?
Rafa Acioly

40

Câu trả lời được chấp nhận là tốt đẹp! Nhưng nếu người ta có thể bắt đầu với một cái gì đó ít phức tạp hơn thì sao? Các mô-đun đăng nhập là điều rất mạnh mẽ và tài liệu là một chút áp đảo đặc biệt là cho người mới. Nhưng để bắt đầu, bạn không cần phải cấu hình trình định dạng và trình xử lý. Bạn có thể thêm nó khi bạn tìm ra những gì bạn muốn.

Ví dụ:

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

Đây là ví dụ phù hợp / hữu ích hơn, ít nhất là trong trường hợp của tôi. Đó là trận chung kết logging.info('Hello, log')khiến mọi thứ nhấp cho tôi. Sự nhầm lẫn trong tài liệu là với dictConfig, chúng ta không còn cần phải thực hiện getLoggerhoặc bất kỳ hành động nào trong số đó.
Mike Williamson

@theotheo Bạn có thể giải thích khóa trống không '': { 'level': 'INFO'...và tại sao nó không hoạt động mà không có nó (ví dụ: khi thay đổi giá trị trống thành giá trị hợp lệ, chẳng hạn nhưstandard
user9074332

1
@MikeWilliamson: Tuy nhiên, vẫn có thể hữu ích khi vẫn gọi getLogger()nếu bạn muốn nhiều logger với các tên khác nhau. Mỗi logger này kế thừa cấu hình từ logger gốc.
Elias Stroundle

3
@MikeWilliamson getLoggerluôn là tùy chọn. Khi sử dụng logging.info()phương thức trực tiếp, trình ghi nhật ký gốc được sử dụng, trong khi với getLogger()bạn có thể có các trình ghi nhật ký khác nhau, với các tên và cấp độ khác nhau.
sox với Monica

8

Ví dụ với Trình xử lý luồng, Trình xử lý tệp, Trình xử lý tệp xoay và Trình xử lý 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

Tôi tìm thấy cấu hình mặc định Django v1.11.15 bên dưới, hy vọng nó sẽ giúp

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
Ví dụ này là tốt, nhưng tôi nghĩ để nổi bật hơn câu trả lời được chấp nhận, một số giải thích sẽ giúp.
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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.