14
votes

Write your code with a nice logger

import logging

def init_logging():
     logFormatter = logging.Formatter("[%(asctime)s] %(levelname)s::%(module)s::%(funcName)s() %(message)s")
     rootLogger = logging.getLogger()
     LOG_DIR = os.getcwd() + '/' + 'logs'
     if not os.path.exists(LOG_DIR):
          os.makedirs(LOG_DIR)
     fileHandler = logging.FileHandler("{0}/{1}.log".format(LOG_DIR, "g2"))
     fileHandler.setFormatter(logFormatter)
     rootLogger.addHandler(fileHandler)
     rootLogger.setLevel(logging.DEBUG)
     consoleHandler = logging.StreamHandler()
     consoleHandler.setFormatter(logFormatter)
     rootLogger.addHandler(consoleHandler)
     return rootLogger

logger = init_logging()

works as expected. Logging using logger.debug("Hello! :)") logs to file and console.

In a second step you want to import an external module which is also logging using logging module:

  1. Install it using pip3 install pymisp (or any other external module)
  2. Import it using from pymisp import PyMISP (or any other external module)
  3. Create an object of it using self.pymisp = PyMISP(self.ds_model.api_url, self.ds_model.api_key, False, 'json') (or any other...)

What now happens is, that every debug log output from the imported module is getting logged to the log file and the console. The question now is, how to set a different (higher) log level for the imported module.

2
if google brings you here, it's better to use logging.getLogger('modulename').setLevel(logging.DEBUG) instead of directly manipulating a logging object from a module. - anishtain4

2 Answers

9
votes

Most third party modules that use logging implement a logger and store it in a variable called logger or _log at module level. This means you can extract the logger and adapt it to your needs. In your case:

import logging    
import pymisp

pymisp.logger.setLevel(logging.INFO)
# code of module goes here

As Meet Sinoja pointed out in the comments you can also use a more generic version of the code above by retrieving the logger of the module by name as follows

logging.getLogger("imported_module_name").setLevel(logging.WARNING)

In this case you don't need the name of the logger (e.g. _log, logger) variable as for the first approach.

-1
votes

A colleague of mine helped with this question:

  1. Get a named logger yourLogger = logging.getLogger('your_logger')
  2. Add a filter to each handler prevents them to print/save other logs than yours

    for handler in logging.root.handlers:
        handler.addFilter(logging.Filter('your_logger'))