34 output=None, distributed_rank=0, *, color=True, name="fastreid", abbrev_name=None
38 output (str): a file name or a directory to save log. If None, will not save log file.
39 If ends with ".txt" or ".log", assumed to be a file name.
40 Otherwise, logs will be saved to `output/log.txt`.
41 name (str): the root module name of this logger
42 abbrev_name (str): an abbreviation of the module, to avoid long names in logs.
43 Set to "" to not log the root module in logs.
44 By default, will abbreviate "detectron2" to "d2" and leave other
47 logger = logging.getLogger(name)
48 logger.setLevel(logging.DEBUG)
49 logger.propagate =
False
51 if abbrev_name
is None:
52 abbrev_name =
"d2" if name ==
"detectron2" else name
54 plain_formatter = logging.Formatter(
55 "[%(asctime)s] %(name)s %(levelname)s: %(message)s", datefmt=
"%m/%d %H:%M:%S"
58 if distributed_rank == 0:
59 ch = logging.StreamHandler(stream=sys.stdout)
60 ch.setLevel(logging.DEBUG)
63 colored(
"[%(asctime)s %(name)s]: ",
"green") +
"%(message)s",
64 datefmt=
"%m/%d %H:%M:%S",
66 abbrev_name=str(abbrev_name),
69 formatter = plain_formatter
70 ch.setFormatter(formatter)
74 if output
is not None:
75 if output.endswith(
".txt")
or output.endswith(
".log"):
78 filename = os.path.join(output,
"log.txt")
79 if distributed_rank > 0:
80 filename = filename +
".rank{}".format(distributed_rank)
81 PathManager.mkdirs(os.path.dirname(filename))
84 fh.setLevel(logging.DEBUG)
85 fh.setFormatter(plain_formatter)
93@functools.lru_cache(maxsize=None)
128 Log only for the first n times.
130 lvl (int): the logging level
133 name (str): name of the logger to use. Will use the caller's module by default.
134 key (str or tuple[str]): the string(s) can be one of "caller" or
135 "message", which defines how to identify duplicated logs.
136 For example, if called with `n=1, key="caller"`, this function
137 will only log the first call from the same caller, regardless of
139 If called with `n=1, key="message"`, this function will log the
140 same content only once, even if they are called from different places.
141 If called with `n=1, key=("caller", "message")`, this function
142 will not log only if the same caller has logged the same message before.
144 if isinstance(key, str):
151 hash_key = hash_key + caller_key
153 hash_key = hash_key + (msg,)
155 _LOG_COUNTER[hash_key] += 1
156 if _LOG_COUNTER[hash_key] <= n:
157 logging.getLogger(name
or caller_module).log(lvl, msg)
162 Log once per n times.
164 lvl (int): the logging level
167 name (str): name of the logger to use. Will use the caller's module by default.
170 _LOG_COUNTER[key] += 1
171 if n == 1
or _LOG_COUNTER[key] % n == 1:
172 logging.getLogger(name
or caller_module).log(lvl, msg)
177 Log no more than once per n seconds.
179 lvl (int): the logging level
182 name (str): name of the logger to use. Will use the caller's module by default.
185 last_logged = _LOG_TIMER.get(key,
None)
186 current_time = time.time()
187 if last_logged
is None or current_time - last_logged >= n:
188 logging.getLogger(name
or caller_module).log(lvl, msg)
189 _LOG_TIMER[key] = current_time