class_docstr: Logs are first collected in each environment worker,
  and then aggregated to stream at the central thread in vector env.
  
  In :class:`LogCollector`, every metric is added to a dict, which needs to be ``reset()`` at each step.
  The dict is sent via the ``info`` in ``env.step()``, and decoded by the :class:`LogWriter` at vector env.
  
  ``min_loglevel`` is for optimization purposes: to avoid too much traffic on networks / in pipe.
class_docstr_tok: ["Logs","are","first","collected","in","each","environment","worker",",","and","then","aggregated","to","stream","at","the","central","thread","in","vector","env",".","In",":","class",":","`","LogCollector","`",",","every","metric","is","added","to","a","dict",",","which","needs","to","be","``","reset","(",")","``","at","each","step",".","The","dict","is","sent","via","the","``","info","``","in","``","env.step","(",")","``",",","and","decoded","by","the",":","class",":","`","LogWriter","`","at","vector","env",".","``","min_loglevel","``","is","for","optimization","purposes",":","to","avoid","too","much","traffic","on","networks","\/","in","pipe","."]
docstr: Add a scalar with name into logged contents.
  Scalar will be converted into a float.
code: def add_scalar(
      self,
      name: str,
      scalar: Any,
      loglevel: int | LogLevel = LogLevel.PERIODIC,
  ) -> None:
      """Add a scalar with name into logged contents.
      Scalar will be converted into a float.
      """
      if loglevel < self._min_loglevel:
          return
  
      if hasattr(scalar, "item"):
          # could be single-item number
          scalar = scalar.item()
      if not isinstance(scalar, (float, int)):
          raise TypeError(
              f"{scalar} is not and can not be converted into float or integer."
          )
      scalar = float(scalar)
      self._add_metric(name, scalar, loglevel)
  
imports: from __future__ import annotations
  import logging
  from collections import defaultdict
  from enum import IntEnum
  from pathlib import Path
  from typing import TYPE_CHECKING, Any, Callable, Dict, Generic, List, Sequence, Set, Tuple, TypeVar
  import numpy
  import pandas
  from qlib.log import get_module_logger
label_desc: Use image node_id 5 for calling the LogCollector obj's underlying member method code with example usage: obj.add_scalar(name, scalar, loglevel) without return types