class_docstr: A statistics logging wrapper for :class:`~maze.core.env.base_env.BaseEnv`.
  
  :param env: The environment to wrap.
class_docstr_tok: ["A","statistics","logging","wrapper","for",":","class",":","`","~maze.core.env.base_env.BaseEnv","`",".",":","param","env",":","The","environment","to","wrap","."]
docstr: Avoid calling this constructor directly, use :method:`wrap` instead.
code: def __init__(
      self, env: MazeEnv, logging_prefix: Optional[str] = None
  ):
      """Avoid calling this constructor directly, use :method:`wrap` instead."""
      # BaseEnv is a subset of gym.Env
      super().__init__(env)
  
      # initialize step aggregator
      self.epoch_stats = LogStatsAggregator(LogStatsLevel.EPOCH)
      self.episode_stats = LogStatsAggregator(
          LogStatsLevel.EPISODE, self.epoch_stats
      )
      self.step_stats = LogStatsAggregator(
          LogStatsLevel.STEP, self.episode_stats
      )
  
      self.stats_map = {
          LogStatsLevel.EPOCH: self.epoch_stats,
          LogStatsLevel.EPISODE: self.episode_stats,
          LogStatsLevel.STEP: self.step_stats,
      }
  
      if logging_prefix is not None:
          self.epoch_stats.register_consumer(
              get_stats_logger(logging_prefix)
          )
  
      self.last_env_time: Optional[int] = None
      self.reward_events = EventCollection()
      self.episode_event_log: Optional[EpisodeEventLog] = None
  
      self.step_stats_renderer = EventStatsRenderer()
  
      # register a post-step callback, so stats are recorded even in case that a wrapper
      # in the middle of the stack steps the environment (as done e.g. during step-skipping)
      if hasattr(env, "context") and isinstance(
          env.context, EnvironmentContext
      ):
          env.context.register_post_step(self._record_stats_if_ready)
  
imports: import uuid
  from typing import Callable, Optional, Iterable
  from typing import TypeVar, Union, Any, Tuple, Dict
  from maze.core.annotations import override
  from maze.core.env.base_env import BaseEnv
  from maze.core.env.base_env_events import BaseEnvEvents
  from maze.core.env.environment_context import EnvironmentContext
  from maze.core.env.event_env_mixin import EventEnvMixin
  from maze.core.env.maze_action import MazeActionType
  from maze.core.env.maze_env import MazeEnv
  from maze.core.env.maze_state import MazeStateType
  from maze.core.env.recordable_env_mixin import RecordableEnvMixin
  from maze.core.env.simulated_env_mixin import SimulatedEnvMixin
  from maze.core.env.structured_env import StructuredEnv
  from maze.core.env.time_env_mixin import TimeEnvMixin
  from maze.core.events.event_collection import EventCollection
  from maze.core.events.event_record import EventRecord
  from maze.core.log_events.episode_event_log import EpisodeEventLog
  from maze.core.log_events.log_events_writer_registry import LogEventsWriterRegistry
  from maze.core.log_events.step_event_log import StepEventLog
  from maze.core.log_stats.log_stats import LogStatsAggregator, LogStatsLevel, get_stats_logger, LogStatsValue
  from maze.core.log_stats.log_stats_env import LogStatsEnv
  from maze.core.rendering.events_stats_renderer import EventStatsRenderer
  from maze.core.wrappers.wrapper import Wrapper
label_desc: Use image node_id 1 to create a new LogStatsWrapper object from inherited base classes: Wrapper, LogStatsEnv with example: obj = LogStatsWrapper(env, logging_prefix)