code: def set_logger(self):
          
          # Higher or lesser argument values are also mapped to DEBUG or CRITICAL
          effective_level = max(logging.DEBUG, logging.CRITICAL - self.args.loglevel * 10)
          logger.setLevel(effective_level)
  
          # Add an handler if missing
          if not logger.handlers:
              if sys.stdout.isatty():
                  handler = logging.StreamHandler()
              else:
                  try:
                      handler = logging.FileHandler(self.config.get('main', 'logfile'))
                  except (IOError, OSError, TypeError, AttributeError):
                      handler = logging.StreamHandler()
              logger.addHandler(handler)
  
          # Set the formatter of each handler (normally there is only one handler)
          for handler in logger.handlers:
              if effective_level <= logging.DEBUG:
                  formatter = logging.Formatter("[%(levelname)s:%(module)s:%(funcName)s: %(lineno)s] %(message)s")
              else:
                  formatter = logging.Formatter("%(levelname)s: %(message)s")
              handler.setLevel(effective_level)
              handler.setFormatter(formatter)
docs: Setup lograptor logger with an handler and a formatter. The logging
          level is defined by a [0..4] range, where an higher value means a
          more verbose logging. The loglevel value is mapped to correspondent
          logging module's value:
  
          LOG_CRIT=0 (syslog.h value is 2) ==> logging.CRITICAL
          LOG_ERR=1 (syslog.h value is 3) ==> logging.ERROR
          LOG_WARNING=2 (syslog.h value is 4) ==> logging.WARNING
          LOG_INFO=3 (syslog.h value is 6) ==> logging.INFO
          LOG_DEBUG=4 (syslog.h value is 7) ==> logging.DEBUG
  
          If the stdout is a tty the log is sent to stderr, otherwise is sent
          to the configured logfile.