class_docstr: A MazeEnv monitoring wrapper logging events for observations, actions and rewards.
  
  :param env: The environment to wrap.
  :param observation_logging: If True observation events are logged.
  :param action_logging: If True action events are logged.
  :param reward_logging: If True additional reward events are logged.
class_docstr_tok: ["A","MazeEnv","monitoring","wrapper","logging","events","for","observations",",","actions","and","rewards",".",":","param","env",":","The","environment","to","wrap",".",":","param","observation_logging",":","If","True","observation","events","are","logged",".",":","param","action_logging",":","If","True","action","events","are","logged",".",":","param","reward_logging",":","If","True","additional","reward","events","are","logged","."]
code: def _log_action(
      self,
      substep_name: Union[str, int],
      agent_name: str,
      action: ActionType,
  ) -> None:
      assert isinstance(
          action, Dict
      ), "The action space of your env has to be a dict action space."
  
      for (
          actor_name,
          actor_action_space,
      ) in self._action_space.spaces.items():
          # If actor_name is not in action, cycle loop
          if actor_name not in action:
              continue
          # Check for discrete sub-action space
          if isinstance(actor_action_space, spaces.Discrete):
              # For some policies, the action is a np.ndarray, for others the action is an int. To support both cases,
              # transform the actions to int (done via v.item() below)
              actor_action = action[actor_name]
              if isinstance(actor_action, np.ndarray):
                  actor_action = actor_action.item()
              self.action_events.discrete_action(
                  step_key=substep_name,
                  name=actor_name,
                  agent_name=agent_name,
                  value=actor_action,
                  action_dim=actor_action_space.n,
              )
  
          # Check for multi-discrete sub-action space
          elif isinstance(actor_action_space, spaces.MultiDiscrete):
              for sub_actor_idx, sub_action_space in enumerate(
                  actor_action_space.nvec
              ):
                  # a multi-discrete action space consists of several discrete action spaces
                  self.action_events.discrete_action(
                      step_key=substep_name,
                      agent_name=agent_name,
                      name=f"{actor_name}_{sub_actor_idx}",
                      value=action[actor_name][..., sub_actor_idx],
                      action_dim=actor_action_space.nvec[sub_actor_idx],
                  )
  
          elif isinstance(actor_action_space, spaces.MultiBinary):
              actor_action = action[actor_name]
              assert isinstance(actor_action, np.ndarray)
              self.action_events.multi_binary_action(
                  step_key=substep_name,
                  name=actor_name,
                  agent_name=agent_name,
                  value=actor_action,
                  num_binary_actions=actor_action_space.n,
              )
  
          # Check for box sub-action space
          elif isinstance(actor_action_space, spaces.Box):
              actor_action = action[actor_name]
              self.action_events.continuous_action(
                  step_key=substep_name,
                  agent_name=agent_name,
                  name=actor_name,
                  value=actor_action,
              )
  
imports: import warnings
  from typing import TypeVar, Union, Any, Tuple, Dict, Optional
  import numpy
  from gym import spaces
  from maze.core.annotations import override
  from maze.core.env.action_conversion import ActionType
  from maze.core.env.base_env import BaseEnv
  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.observation_conversion import ObservationType
  from maze.core.env.simulated_env_mixin import SimulatedEnvMixin
  from maze.core.env.structured_env import StructuredEnv
  from maze.core.log_events.monitoring_events import ActionEvents, RewardEvents, ObservationEvents
  from maze.core.wrappers.wrapper import Wrapper
label_desc: Use image node_id 8 for calling the MazeEnvMonitoringWrapper obj's underlying member method code with example usage: obj._log_action(substep_name, agent_name, action) without return types