You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

logger.py 7.5 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. # -*- coding: utf-8 -*-
  2. # MegEngine is Licensed under the Apache License, Version 2.0 (the "License")
  3. #
  4. # Copyright (c) 2014-2020 Megvii Inc. All rights reserved.
  5. #
  6. # Unless required by applicable law or agreed to in writing,
  7. # software distributed under the License is distributed on an
  8. # "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9. import contextlib
  10. import logging
  11. import os
  12. import sys
  13. _all_loggers = []
  14. _default_level_name = os.getenv("MEGENGINE_LOGGING_LEVEL", "INFO")
  15. _default_level = logging.getLevelName(_default_level_name.upper())
  16. def set_log_file(fout, mode="a"):
  17. r"""Sets log output file.
  18. :type fout: str or file-like
  19. :param fout: file-like object that supports write and flush, or string for
  20. the filename
  21. :type mode: str
  22. :param mode: specify the mode to open log file if *fout* is a string
  23. """
  24. if isinstance(fout, str):
  25. fout = open(fout, mode)
  26. MegEngineLogFormatter.log_fout = fout
  27. class MegEngineLogFormatter(logging.Formatter):
  28. log_fout = None
  29. date_full = "[%(asctime)s %(lineno)d@%(filename)s:%(name)s] "
  30. date = "%(asctime)s "
  31. msg = "%(message)s"
  32. max_lines = 256
  33. def _color_exc(self, msg):
  34. r"""Sets the color of message as the execution type.
  35. """
  36. return "\x1b[34m{}\x1b[0m".format(msg)
  37. def _color_dbg(self, msg):
  38. r"""Sets the color of message as the debugging type.
  39. """
  40. return "\x1b[36m{}\x1b[0m".format(msg)
  41. def _color_warn(self, msg):
  42. r"""Sets the color of message as the warning type.
  43. """
  44. return "\x1b[1;31m{}\x1b[0m".format(msg)
  45. def _color_err(self, msg):
  46. r"""Sets the color of message as the error type.
  47. """
  48. return "\x1b[1;4;31m{}\x1b[0m".format(msg)
  49. def _color_omitted(self, msg):
  50. r"""Sets the color of message as the omitted type.
  51. """
  52. return "\x1b[35m{}\x1b[0m".format(msg)
  53. def _color_normal(self, msg):
  54. r"""Sets the color of message as the normal type.
  55. """
  56. return msg
  57. def _color_date(self, msg):
  58. r"""Sets the color of message the same as date.
  59. """
  60. return "\x1b[32m{}\x1b[0m".format(msg)
  61. def format(self, record):
  62. if record.levelno == logging.DEBUG:
  63. mcl, mtxt = self._color_dbg, "DBG"
  64. elif record.levelno == logging.WARNING:
  65. mcl, mtxt = self._color_warn, "WRN"
  66. elif record.levelno == logging.ERROR:
  67. mcl, mtxt = self._color_err, "ERR"
  68. else:
  69. mcl, mtxt = self._color_normal, ""
  70. if mtxt:
  71. mtxt += " "
  72. if self.log_fout:
  73. self.__set_fmt(self.date_full + mtxt + self.msg)
  74. formatted = super(MegEngineLogFormatter, self).format(record)
  75. nr_line = formatted.count("\n") + 1
  76. if nr_line >= self.max_lines:
  77. head, body = formatted.split("\n", 1)
  78. formatted = "\n".join(
  79. [
  80. head,
  81. "BEGIN_LONG_LOG_{}_LINES{{".format(nr_line - 1),
  82. body,
  83. "}}END_LONG_LOG_{}_LINES".format(nr_line - 1),
  84. ]
  85. )
  86. self.log_fout.write(formatted)
  87. self.log_fout.write("\n")
  88. self.log_fout.flush()
  89. self.__set_fmt(self._color_date(self.date) + mcl(mtxt + self.msg))
  90. formatted = super(MegEngineLogFormatter, self).format(record)
  91. if record.exc_text or record.exc_info:
  92. # handle exception format
  93. b = formatted.find("Traceback ")
  94. if b != -1:
  95. s = formatted[b:]
  96. s = self._color_exc(" " + s.replace("\n", "\n "))
  97. formatted = formatted[:b] + s
  98. nr_line = formatted.count("\n") + 1
  99. if nr_line >= self.max_lines:
  100. lines = formatted.split("\n")
  101. remain = self.max_lines // 2
  102. removed = len(lines) - remain * 2
  103. if removed > 0:
  104. mid_msg = self._color_omitted(
  105. "[{} log lines omitted (would be written to output file "
  106. "if set_log_file() has been called;\n"
  107. " the threshold can be set at "
  108. "MegEngineLogFormatter.max_lines)]".format(removed)
  109. )
  110. formatted = "\n".join(lines[:remain] + [mid_msg] + lines[-remain:])
  111. return formatted
  112. if sys.version_info.major < 3:
  113. def __set_fmt(self, fmt):
  114. self._fmt = fmt
  115. else:
  116. def __set_fmt(self, fmt):
  117. self._style._fmt = fmt
  118. def get_logger(name=None, formatter=MegEngineLogFormatter):
  119. r"""Gets megengine logger with given name.
  120. """
  121. logger = logging.getLogger(name)
  122. if getattr(logger, "_init_done__", None):
  123. return logger
  124. logger._init_done__ = True
  125. logger.propagate = False
  126. logger.setLevel(_default_level)
  127. handler = logging.StreamHandler()
  128. handler.setFormatter(formatter(datefmt="%d %H:%M:%S"))
  129. handler.setLevel(0)
  130. del logger.handlers[:]
  131. logger.addHandler(handler)
  132. _all_loggers.append(logger)
  133. return logger
  134. def set_log_level(level, update_existing=True):
  135. """Sets default logging level.
  136. :type level: int e.g. logging.INFO
  137. :param level: loggin level given by python :mod:`logging` module
  138. :param update_existing: whether to update existing loggers
  139. """
  140. global _default_level # pylint: disable=global-statement
  141. _default_level = level
  142. if update_existing:
  143. for i in _all_loggers:
  144. i.setLevel(level)
  145. _logger = get_logger(__name__)
  146. try:
  147. if sys.version_info.major < 3:
  148. raise ImportError()
  149. from .core._imperative_rt.utils import Logger as _imperative_rt_logger
  150. class MegBrainLogFormatter(MegEngineLogFormatter):
  151. date = "%(asctime)s[mgb] "
  152. def _color_date(self, msg):
  153. return "\x1b[33m{}\x1b[0m".format(msg)
  154. _megbrain_logger = get_logger("megbrain", MegBrainLogFormatter)
  155. _imperative_rt_logger.set_log_handler(_megbrain_logger)
  156. if _default_level == logging.getLevelName("ERROR"):
  157. _imperative_rt_logger.set_log_level(_imperative_rt_logger.LogLevel.Error)
  158. elif _default_level == logging.getLevelName("INFO"):
  159. _imperative_rt_logger.set_log_level(_imperative_rt_logger.LogLevel.Info)
  160. else:
  161. _imperative_rt_logger.set_log_level(_imperative_rt_logger.LogLevel.Debug)
  162. def set_mgb_log_level(level):
  163. r"""Sets megbrain log level
  164. :type level: int e.g. logging.INFO
  165. :param level: new log level
  166. :return: original log level
  167. """
  168. logger = _megbrain_logger
  169. rst = logger.getEffectiveLevel()
  170. logger.setLevel(level)
  171. return rst
  172. except ImportError as exc:
  173. def set_mgb_log_level(level):
  174. raise NotImplementedError("imperative_rt has not been imported")
  175. @contextlib.contextmanager
  176. def replace_mgb_log_level(level):
  177. r"""Replaces megbrain log level in a block and restore after exiting.
  178. :type level: int e.g. logging.INFO
  179. :param level: new log level
  180. """
  181. old = set_mgb_log_level(level)
  182. try:
  183. yield
  184. finally:
  185. set_mgb_log_level(old)
  186. def enable_debug_log():
  187. r"""Sets logging level to debug for all components.
  188. """
  189. set_log_level(logging.DEBUG)
  190. set_mgb_log_level(logging.DEBUG)

MegEngine 安装包中集成了使用 GPU 运行代码所需的 CUDA 环境,不用区分 CPU 和 GPU 版。 如果想要运行 GPU 程序,请确保机器本身配有 GPU 硬件设备并安装好驱动。 如果你想体验在云端 GPU 算力平台进行深度学习开发的感觉,欢迎访问 MegStudio 平台