code: def create_loggers(
      log_dir: str,
      params: List[Dict[str, Any]],
      logger_config: Optional[Dict[str, Any]] = None,
      disable_existing_loggers: bool = False,
  ):
      """Create loggers from configuration"""
      if logger_config is None:
          config = {}
      else:
          config = logger_config
  
      config.setdefault("loggers", {})
      config.setdefault("handlers", {})
      config.setdefault("formatters", {})
  
      global_logger_name = "tvm.meta_schedule"
      global_logger = logging.getLogger(global_logger_name)
      if global_logger.level is logging.NOTSET:
          global_logger.setLevel(logging.DEBUG)
      console_logging_level = (
          logging._levelToName[  # pylint: disable=protected-access
              global_logger.level
          ]
      )
  
      config["loggers"].setdefault(
          global_logger_name,
          {
              "level": logging.DEBUG,
              "handlers": [
                  handler.get_name()
                  for handler in global_logger.handlers
              ]
              + [
                  global_logger_name + ".console",
                  global_logger_name + ".file",
              ],
              "propagate": False,
          },
      )
      config["loggers"].setdefault(
          "{logger_name}",
          {
              "level": "DEBUG",
              "handlers": [
                  "{logger_name}.file",
              ],
              "propagate": False,
          },
      )
      config["handlers"].setdefault(
          global_logger_name + ".console",
          {
              "class": "logging.StreamHandler",
              "stream": "ext://sys.stdout",
              "formatter": "tvm.meta_schedule.standard_formatter",
              "level": console_logging_level,
          },
      )
      config["handlers"].setdefault(
          global_logger_name + ".file",
          {
              "class": "logging.FileHandler",
              "filename": "{log_dir}/"
              + __name__
              + ".task_scheduler.log",
              "mode": "a",
              "level": "DEBUG",
              "formatter": "tvm.meta_schedule.standard_formatter",
          },
      )
      config["handlers"].setdefault(
          "{logger_name}.file",
          {
              "class": "logging.FileHandler",
              "filename": "{log_dir}/{logger_name}.log",
              "mode": "a",
              "level": "DEBUG",
              "formatter": "tvm.meta_schedule.standard_formatter",
          },
      )
      config["formatters"].setdefault(
          "tvm.meta_schedule.standard_formatter",
          {
              "format": "%(asctime)s [%(levelname)s] %(message)s",
              "datefmt": "%Y-%m-%d %H:%M:%S",
          },
      )
  
      # set up dictConfig loggers
      p_config = {
          "version": 1,
          "disable_existing_loggers": disable_existing_loggers,
      }
      for k, v in config.items():
          if k in ["formatters", "handlers", "loggers"]:
              p_config[k] = _batch_parameterize_config(v, params)  # type: ignore
          else:
              p_config[k] = v
      logging.config.dictConfig(p_config)
  
      # check global logger
      if global_logger.level not in [logging.DEBUG, logging.INFO]:
          global_logger.warning(
              "Logging level set to %s, please set to logging.INFO"
              " or logging.DEBUG to view full log.",
              logging._levelToName[
                  global_logger.level
              ],  # pylint: disable=protected-access
          )
      global_logger.info("Logging directory: %s", log_dir)
  
file_path: tvm/python/tvm/meta_schedule/logging.py
imports: import logging
  import logging.config
  import os
  import os.path
  from logging import Logger
  from typing import Any, Callable, Dict, List, Optional
label_desc: Use image node_id 3 for calling a global function with example usage: create_loggers(log_dir, params, logger_config, disable_existing_loggers) without return types