logger.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. # copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. import os
  15. import sys
  16. import logging
  17. import datetime
  18. import paddle.distributed as dist
  19. _logger = None
  20. def init_logger(name='root', log_file=None, log_level=logging.INFO):
  21. """Initialize and get a logger by name.
  22. If the logger has not been initialized, this method will initialize the
  23. logger by adding one or two handlers, otherwise the initialized logger will
  24. be directly returned. During initialization, a StreamHandler will always be
  25. added. If `log_file` is specified a FileHandler will also be added.
  26. Args:
  27. name (str): Logger name.
  28. log_file (str | None): The log filename. If specified, a FileHandler
  29. will be added to the logger.
  30. log_level (int): The logger level. Note that only the process of
  31. rank 0 is affected, and other processes will set the level to
  32. "Error" thus be silent most of the time.
  33. Returns:
  34. logging.Logger: The expected logger.
  35. """
  36. global _logger
  37. assert _logger is None, "logger should not be initialized twice or more."
  38. _logger = logging.getLogger(name)
  39. formatter = logging.Formatter(
  40. '[%(asctime)s] %(name)s %(levelname)s: %(message)s',
  41. datefmt="%Y/%m/%d %H:%M:%S")
  42. stream_handler = logging.StreamHandler(stream=sys.stdout)
  43. stream_handler.setFormatter(formatter)
  44. _logger.addHandler(stream_handler)
  45. if log_file is not None and dist.get_rank() == 0:
  46. log_file_folder = os.path.split(log_file)[0]
  47. os.makedirs(log_file_folder, exist_ok=True)
  48. file_handler = logging.FileHandler(log_file, 'a')
  49. file_handler.setFormatter(formatter)
  50. _logger.addHandler(file_handler)
  51. if dist.get_rank() == 0:
  52. _logger.setLevel(log_level)
  53. else:
  54. _logger.setLevel(logging.ERROR)
  55. def log_at_trainer0(log):
  56. """
  57. logs will print multi-times when calling Fleet API.
  58. Only display single log and ignore the others.
  59. """
  60. def wrapper(fmt, *args):
  61. if dist.get_rank() == 0:
  62. log(fmt, *args)
  63. return wrapper
  64. @log_at_trainer0
  65. def info(fmt, *args):
  66. _logger.info(fmt, *args)
  67. @log_at_trainer0
  68. def debug(fmt, *args):
  69. _logger.debug(fmt, *args)
  70. @log_at_trainer0
  71. def warning(fmt, *args):
  72. _logger.warning(fmt, *args)
  73. @log_at_trainer0
  74. def error(fmt, *args):
  75. _logger.error(fmt, *args)
  76. def scaler(name, value, step, writer):
  77. """
  78. This function will draw a scalar curve generated by the visualdl.
  79. Usage: Install visualdl: pip3 install visualdl==2.0.0b4
  80. and then:
  81. visualdl --logdir ./scalar --host 0.0.0.0 --port 8830
  82. to preview loss corve in real time.
  83. """
  84. if writer is None:
  85. return
  86. writer.add_scalar(tag=name, step=step, value=value)
  87. def advertise():
  88. """
  89. Show the advertising message like the following:
  90. ===========================================================
  91. == PaddleClas is powered by PaddlePaddle ! ==
  92. ===========================================================
  93. == ==
  94. == For more info please go to the following website. ==
  95. == ==
  96. == https://github.com/PaddlePaddle/PaddleClas ==
  97. ===========================================================
  98. """
  99. copyright = "PaddleClas is powered by PaddlePaddle !"
  100. ad = "For more info please go to the following website."
  101. website = "https://github.com/PaddlePaddle/PaddleClas"
  102. AD_LEN = 6 + len(max([copyright, ad, website], key=len))
  103. info("\n{0}\n{1}\n{2}\n{3}\n{4}\n{5}\n{6}\n{7}\n".format(
  104. "=" * (AD_LEN + 4),
  105. "=={}==".format(copyright.center(AD_LEN)),
  106. "=" * (AD_LEN + 4),
  107. "=={}==".format(' ' * AD_LEN),
  108. "=={}==".format(ad.center(AD_LEN)),
  109. "=={}==".format(' ' * AD_LEN),
  110. "=={}==".format(website.center(AD_LEN)),
  111. "=" * (AD_LEN + 4), ))