LeonidasFett
LeonidasFett

Reputation: 3132

Skip logs from imported modules

Trying to create a logger class for my package and I am close to banging my head against the wall. No matter what I do, the logger will also log messages from external modules. Here's my class:

import logging
import os
import sys
from pathlib import Path
from datetime import date


class Logger:

    # Variables
    log_path = ''
    log_format = '%(asctime)s %(levelname)-8s %(message)s'
    date_format = '%Y-%m-%d'
    datetime_format = '%Y-%m-%d %H:%M:%S'
    logger = None

    # CTOR
    def __init__(self, base_path):
        self.log_path = os.path.join(base_path, "logs/")
        Path(self.log_path).mkdir(parents=True, exist_ok=True)
        logfile = os.path.join(self.log_path, date.today().strftime(self.date_format) + ".log")
        logging.basicConfig(
            filename=logfile,
            level=logging.WARNING,
            filemode='a',
            format=self.log_format,
            datefmt=self.datetime_format)
        self.logger = logging.getLogger('bleservice')
        self.logger.setLevel(logging.INFO)

    # Methods
    def log_information(self, message):
        self.logger.info(message)
        print('logged info')

    def log_error(self, message):
        self.logger.error(message)
        print('logged error into')

    def log_exception(self, exception):
        self.logger.exception(message)
        print('logged exception into')

Basically, I want to log warnings and errors from external modules and everything from info from my package into the same file. Yet it also logs info messages from external modules, making my log file grow to several GB in size. What am I doing wrong here?

EDIT: To make it more clear, what I need to do is:

  1. All logs from my own module starting at level INFO should log into the file
  2. All logs from external modules starting at level WARNING should also log into the file.

Currently, all logs starting from INFO from my module AND external modules are logged into the file.

Upvotes: 0

Views: 258

Answers (1)

blues
blues

Reputation: 5185

First let me explain why you see the behaviour that you are getting. When you call basicConfig with a level and a filename argument it will do two things for you. It will set the level of the root logger to the provided level and it will create a logging.FileHandler with a level of NOTSET that will be attached to the root logger.

Now when some modules logger creates a log and has propagate set to true (which is the default) it will send it's logs directly to it's ancestors handlers. It's important to understand that this bypasses the ancestor loggers and their level. So the modules see the root as their ancestor and send their logs directly to the attached handler which doesn't have a level set and will therefore allow all logs.

What you need to do is either set the level of the handler that basicConfig creates to WARNING and add another handler with level INFO to your bleservice logger, or you should set the level of the module loggers to WARNING.

Upvotes: 1

Related Questions