diff --git a/.pylintrc b/.pylintrc index 40f89e8708..1da1dad0d4 100644 --- a/.pylintrc +++ b/.pylintrc @@ -44,3 +44,5 @@ disable = # Appears to be https://github.com/PyCQA/pylint/issues/2981 W0201, + # Using the global statement + W0603, diff --git a/gym-unity/gym_unity/envs/__init__.py b/gym-unity/gym_unity/envs/__init__.py index b95af6d842..390e44182b 100644 --- a/gym-unity/gym_unity/envs/__init__.py +++ b/gym-unity/gym_unity/envs/__init__.py @@ -1,4 +1,3 @@ -import logging import itertools import numpy as np from typing import Any, Dict, List, Optional, Tuple, Union @@ -8,6 +7,7 @@ from mlagents_envs.environment import UnityEnvironment from mlagents_envs.base_env import BatchedStepResult +from mlagents_envs import logging_util class UnityGymException(error.Error): @@ -18,9 +18,8 @@ class UnityGymException(error.Error): pass -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger("gym_unity") - +logger = logging_util.get_logger(__name__) +logging_util.set_log_level(logging_util.INFO) GymSingleStepResult = Tuple[np.ndarray, float, bool, Dict] GymMultiStepResult = Tuple[List[np.ndarray], List[float], List[bool], Dict] diff --git a/ml-agents-envs/mlagents_envs/environment.py b/ml-agents-envs/mlagents_envs/environment.py index 8d4daebdd9..2428557db4 100644 --- a/ml-agents-envs/mlagents_envs/environment.py +++ b/ml-agents-envs/mlagents_envs/environment.py @@ -1,13 +1,14 @@ import atexit import glob import uuid -import logging import numpy as np import os import subprocess from typing import Dict, List, Optional, Any import mlagents_envs + +from mlagents_envs.logging_util import get_logger from mlagents_envs.side_channel.side_channel import SideChannel, IncomingMessage from mlagents_envs.base_env import ( @@ -47,7 +48,7 @@ import struct -logger = logging.getLogger("mlagents_envs") +logger = get_logger(__name__) class UnityEnvironment(BaseEnv): diff --git a/ml-agents-envs/mlagents_envs/logging_util.py b/ml-agents-envs/mlagents_envs/logging_util.py new file mode 100644 index 0000000000..b768fc28ca --- /dev/null +++ b/ml-agents-envs/mlagents_envs/logging_util.py @@ -0,0 +1,46 @@ +import logging # noqa I251 + +CRITICAL = logging.CRITICAL +FATAL = logging.FATAL +ERROR = logging.ERROR +WARNING = logging.WARNING +INFO = logging.INFO +DEBUG = logging.DEBUG +NOTSET = logging.NOTSET + +_loggers = set() +_log_level = NOTSET +DATE_FORMAT = "%Y-%m-%d %H:%M:%S" +LOG_FORMAT = "%(asctime)s %(levelname)s [%(filename)s:%(lineno)d] %(message)s" + + +def get_logger(name: str) -> logging.Logger: + """ + Create a logger with the specified name. The logger will use the log level + specified by set_log_level() + """ + logger = logging.getLogger(name=name) + + # If we've already set the log level, make sure new loggers use it + if _log_level != NOTSET: + logger.setLevel(_log_level) + + # Keep track of this logger so that we can change the log level later + _loggers.add(logger) + return logger + + +def set_log_level(log_level: int) -> None: + """ + Set the ML-Agents logging level. This will also configure the logging format (if it hasn't already been set). + """ + global _log_level + _log_level = log_level + + # Configure the log format. + # In theory, this would be sufficient, but if another library calls logging.basicConfig + # first, it doesn't have any effect. + logging.basicConfig(level=_log_level, format=LOG_FORMAT, datefmt=DATE_FORMAT) + + for logger in _loggers: + logger.setLevel(log_level) diff --git a/ml-agents-envs/mlagents_envs/side_channel/outgoing_message.py b/ml-agents-envs/mlagents_envs/side_channel/outgoing_message.py index 835349cbd2..83bbe3446c 100644 --- a/ml-agents-envs/mlagents_envs/side_channel/outgoing_message.py +++ b/ml-agents-envs/mlagents_envs/side_channel/outgoing_message.py @@ -1,9 +1,9 @@ from typing import List import struct -import logging +from mlagents_envs.logging_util import get_logger -logger = logging.getLogger(__name__) +logger = get_logger(__name__) class OutgoingMessage: diff --git a/ml-agents-envs/mlagents_envs/side_channel/side_channel.py b/ml-agents-envs/mlagents_envs/side_channel/side_channel.py index 52f2a106f1..469cb51eab 100644 --- a/ml-agents-envs/mlagents_envs/side_channel/side_channel.py +++ b/ml-agents-envs/mlagents_envs/side_channel/side_channel.py @@ -1,11 +1,11 @@ from abc import ABC, abstractmethod from typing import List import uuid -import logging from mlagents_envs.side_channel import IncomingMessage, OutgoingMessage +from mlagents_envs.logging_util import get_logger -logger = logging.getLogger(__name__) +logger = get_logger(__name__) class SideChannel(ABC): diff --git a/ml-agents/mlagents/logging_util.py b/ml-agents/mlagents/logging_util.py deleted file mode 100644 index a9478023d7..0000000000 --- a/ml-agents/mlagents/logging_util.py +++ /dev/null @@ -1,10 +0,0 @@ -import logging - - -def create_logger(name, log_level): - date_format = "%Y-%m-%d %H:%M:%S" - log_format = "%(asctime)s %(levelname)s [%(filename)s:%(lineno)d] %(message)s" - - logging.basicConfig(level=log_level, format=log_format, datefmt=date_format) - logger = logging.getLogger(name=name) - return logger diff --git a/ml-agents/mlagents/model_serialization.py b/ml-agents/mlagents/model_serialization.py index 04cdc27647..c95b776da4 100644 --- a/ml-agents/mlagents/model_serialization.py +++ b/ml-agents/mlagents/model_serialization.py @@ -1,6 +1,5 @@ from distutils.util import strtobool import os -import logging from typing import Any, List, Set, NamedTuple from distutils.version import LooseVersion @@ -19,14 +18,16 @@ from tensorflow.python.platform import gfile from tensorflow.python.framework import graph_util + +from mlagents_envs.logging_util import get_logger from mlagents.trainers import tensorflow_to_barracuda as tf2bc if LooseVersion(tf.__version__) < LooseVersion("1.12.0"): # ONNX is only tested on 1.12.0 and later ONNX_EXPORT_ENABLED = False +logger = get_logger(__name__) -logger = logging.getLogger("mlagents.trainers") POSSIBLE_INPUT_NODES = frozenset( [ diff --git a/ml-agents/mlagents/trainers/components/reward_signals/__init__.py b/ml-agents/mlagents/trainers/components/reward_signals/__init__.py index 72c719e64f..9c721b4d64 100644 --- a/ml-agents/mlagents/trainers/components/reward_signals/__init__.py +++ b/ml-agents/mlagents/trainers/components/reward_signals/__init__.py @@ -1,4 +1,3 @@ -import logging from typing import Any, Dict, List from collections import namedtuple import numpy as np @@ -6,11 +5,13 @@ from mlagents.tf_utils import tf +from mlagents_envs.logging_util import get_logger from mlagents.trainers.exception import UnityTrainerException from mlagents.trainers.policy.tf_policy import TFPolicy from mlagents.trainers.buffer import AgentBuffer -logger = logging.getLogger("mlagents.trainers") + +logger = get_logger(__name__) RewardSignalResult = namedtuple( "RewardSignalResult", ["scaled_reward", "unscaled_reward"] diff --git a/ml-agents/mlagents/trainers/curriculum.py b/ml-agents/mlagents/trainers/curriculum.py index 0eba472265..12eaa7a5e7 100644 --- a/ml-agents/mlagents/trainers/curriculum.py +++ b/ml-agents/mlagents/trainers/curriculum.py @@ -4,9 +4,9 @@ from .exception import CurriculumConfigError, CurriculumLoadingError -import logging +from mlagents_envs.logging_util import get_logger -logger = logging.getLogger("mlagents.trainers") +logger = get_logger(__name__) class Curriculum: diff --git a/ml-agents/mlagents/trainers/env_manager.py b/ml-agents/mlagents/trainers/env_manager.py index cee446dab7..bb30bde953 100644 --- a/ml-agents/mlagents/trainers/env_manager.py +++ b/ml-agents/mlagents/trainers/env_manager.py @@ -1,5 +1,4 @@ from abc import ABC, abstractmethod -import logging from typing import List, Dict, NamedTuple, Iterable, Tuple from mlagents_envs.base_env import BatchedStepResult, AgentGroupSpec, AgentGroup from mlagents_envs.side_channel.stats_side_channel import StatsAggregationMethod @@ -7,11 +6,13 @@ from mlagents.trainers.policy.tf_policy import TFPolicy from mlagents.trainers.agent_processor import AgentManager, AgentManagerQueue from mlagents.trainers.action_info import ActionInfo +from mlagents_envs.logging_util import get_logger AllStepResult = Dict[AgentGroup, BatchedStepResult] AllGroupSpec = Dict[AgentGroup, AgentGroupSpec] -logger = logging.getLogger("mlagents.trainers") + +logger = get_logger(__name__) class EnvironmentStep(NamedTuple): diff --git a/ml-agents/mlagents/trainers/ghost/trainer.py b/ml-agents/mlagents/trainers/ghost/trainer.py index 7a500d5ae0..9042f693c1 100644 --- a/ml-agents/mlagents/trainers/ghost/trainer.py +++ b/ml-agents/mlagents/trainers/ghost/trainer.py @@ -4,8 +4,8 @@ from typing import Deque, Dict, List, Any, cast import numpy as np -import logging +from mlagents_envs.logging_util import get_logger from mlagents.trainers.brain import BrainParameters from mlagents.trainers.policy import Policy from mlagents.trainers.policy.tf_policy import TFPolicy @@ -16,7 +16,8 @@ from mlagents.trainers.stats import StatsPropertyType from mlagents.trainers.behavior_id_utils import BehaviorIdentifiers -logger = logging.getLogger("mlagents.trainers") + +logger = get_logger(__name__) class GhostTrainer(Trainer): diff --git a/ml-agents/mlagents/trainers/learn.py b/ml-agents/mlagents/trainers/learn.py index 8c912c9cda..b1f93637ad 100644 --- a/ml-agents/mlagents/trainers/learn.py +++ b/ml-agents/mlagents/trainers/learn.py @@ -1,5 +1,4 @@ # # Unity ML-Agents Toolkit -import logging import argparse import os @@ -30,7 +29,9 @@ from mlagents_envs.side_channel.engine_configuration_channel import EngineConfig from mlagents_envs.exception import UnityEnvironmentException from mlagents_envs.timers import hierarchical_timer, get_timer_tree -from mlagents.logging_util import create_logger +from mlagents_envs import logging_util + +logger = logging_util.get_logger(__name__) def _create_parser(): @@ -315,7 +316,7 @@ def write_timing_tree(summaries_dir: str, run_id: str) -> None: with open(timing_path, "w") as f: json.dump(get_timer_tree(), f, indent=4) except FileNotFoundError: - logging.warning( + logger.warning( f"Unable to save to {timing_path}. Make sure the directory exists" ) @@ -412,16 +413,16 @@ def run_cli(options: RunOptions) -> None: print(get_version_string()) if options.debug: - log_level = logging.DEBUG + log_level = logging_util.DEBUG else: - log_level = logging.INFO + log_level = logging_util.INFO # disable noisy warnings from tensorflow tf_utils.set_warnings_enabled(False) - trainer_logger = create_logger("mlagents.trainers", log_level) + logging_util.set_log_level(log_level) - trainer_logger.debug("Configuration for this run:") - trainer_logger.debug(json.dumps(options._asdict(), indent=4)) + logger.debug("Configuration for this run:") + logger.debug(json.dumps(options._asdict(), indent=4)) run_seed = options.seed if options.cpu: diff --git a/ml-agents/mlagents/trainers/meta_curriculum.py b/ml-agents/mlagents/trainers/meta_curriculum.py index 60ea9cc5c5..699890359f 100644 --- a/ml-agents/mlagents/trainers/meta_curriculum.py +++ b/ml-agents/mlagents/trainers/meta_curriculum.py @@ -3,9 +3,9 @@ from typing import Dict, Set from mlagents.trainers.curriculum import Curriculum -import logging +from mlagents_envs.logging_util import get_logger -logger = logging.getLogger("mlagents.trainers") +logger = get_logger(__name__) class MetaCurriculum: diff --git a/ml-agents/mlagents/trainers/policy/tf_policy.py b/ml-agents/mlagents/trainers/policy/tf_policy.py index 428ba19796..9d0c02a57a 100644 --- a/ml-agents/mlagents/trainers/policy/tf_policy.py +++ b/ml-agents/mlagents/trainers/policy/tf_policy.py @@ -1,10 +1,10 @@ -import logging from typing import Any, Dict, List, Optional import abc import numpy as np from mlagents.tf_utils import tf from mlagents import tf_utils from mlagents_envs.exception import UnityException +from mlagents_envs.logging_util import get_logger from mlagents.trainers.policy import Policy from mlagents.trainers.action_info import ActionInfo from mlagents.trainers.trajectory import SplitObservations @@ -13,7 +13,7 @@ from mlagents.trainers.models import ModelUtils -logger = logging.getLogger("mlagents.trainers") +logger = get_logger(__name__) class UnityPolicyException(UnityException): diff --git a/ml-agents/mlagents/trainers/ppo/trainer.py b/ml-agents/mlagents/trainers/ppo/trainer.py index 134e8d0000..b1e270186b 100644 --- a/ml-agents/mlagents/trainers/ppo/trainer.py +++ b/ml-agents/mlagents/trainers/ppo/trainer.py @@ -2,11 +2,11 @@ # ## ML-Agent Learning (PPO) # Contains an implementation of PPO as described in: https://arxiv.org/abs/1707.06347 -import logging from collections import defaultdict import numpy as np +from mlagents_envs.logging_util import get_logger from mlagents.trainers.policy.nn_policy import NNPolicy from mlagents.trainers.trainer.rl_trainer import RLTrainer from mlagents.trainers.brain import BrainParameters @@ -16,7 +16,7 @@ from mlagents.trainers.exception import UnityTrainerException -logger = logging.getLogger("mlagents.trainers") +logger = get_logger(__name__) class PPOTrainer(RLTrainer): diff --git a/ml-agents/mlagents/trainers/sac/optimizer.py b/ml-agents/mlagents/trainers/sac/optimizer.py index 0265fe1599..72494f4fe9 100644 --- a/ml-agents/mlagents/trainers/sac/optimizer.py +++ b/ml-agents/mlagents/trainers/sac/optimizer.py @@ -1,9 +1,9 @@ -import logging import numpy as np from typing import Dict, List, Optional, Any, Mapping from mlagents.tf_utils import tf +from mlagents_envs.logging_util import get_logger from mlagents.trainers.sac.network import SACPolicyNetwork, SACTargetNetwork from mlagents.trainers.models import LearningRateSchedule, EncoderType, ModelUtils from mlagents.trainers.optimizer.tf_optimizer import TFOptimizer @@ -13,7 +13,7 @@ EPSILON = 1e-6 # Small value to avoid divide by zero -logger = logging.getLogger("mlagents.trainers") +logger = get_logger(__name__) POLICY_SCOPE = "" TARGET_SCOPE = "target_network" diff --git a/ml-agents/mlagents/trainers/sac/trainer.py b/ml-agents/mlagents/trainers/sac/trainer.py index 31977e84a8..d9121f2db5 100644 --- a/ml-agents/mlagents/trainers/sac/trainer.py +++ b/ml-agents/mlagents/trainers/sac/trainer.py @@ -2,7 +2,6 @@ # Contains an implementation of SAC as described in https://arxiv.org/abs/1801.01290 # and implemented in https://github.com/hill-a/stable-baselines -import logging from collections import defaultdict from typing import Dict import os @@ -10,6 +9,7 @@ import numpy as np +from mlagents_envs.logging_util import get_logger from mlagents_envs.timers import timed from mlagents.trainers.policy.tf_policy import TFPolicy from mlagents.trainers.policy.nn_policy import NNPolicy @@ -20,7 +20,8 @@ from mlagents.trainers.exception import UnityTrainerException -logger = logging.getLogger("mlagents.trainers") +logger = get_logger(__name__) + BUFFER_TRUNCATE_PERCENT = 0.8 diff --git a/ml-agents/mlagents/trainers/stats.py b/ml-agents/mlagents/trainers/stats.py index 7a579f7355..c13e6c5256 100644 --- a/ml-agents/mlagents/trainers/stats.py +++ b/ml-agents/mlagents/trainers/stats.py @@ -6,12 +6,13 @@ import csv import os import time -import logging -from mlagents.tf_utils import tf, generate_session_config +from mlagents_envs.logging_util import get_logger from mlagents_envs.timers import set_gauge +from mlagents.tf_utils import tf, generate_session_config + -logger = logging.getLogger("mlagents.trainers") +logger = get_logger(__name__) class StatsSummary(NamedTuple): diff --git a/ml-agents/mlagents/trainers/subprocess_env_manager.py b/ml-agents/mlagents/trainers/subprocess_env_manager.py index efabef0ecb..f744bc0e60 100644 --- a/ml-agents/mlagents/trainers/subprocess_env_manager.py +++ b/ml-agents/mlagents/trainers/subprocess_env_manager.py @@ -1,4 +1,3 @@ -import logging from typing import Dict, NamedTuple, List, Any, Optional, Callable, Set, Tuple import cloudpickle import enum @@ -13,6 +12,7 @@ from multiprocessing.connection import Connection from queue import Empty as EmptyQueueException from mlagents_envs.base_env import BaseEnv, AgentGroup +from mlagents_envs.logging_util import get_logger from mlagents.trainers.env_manager import EnvManager, EnvironmentStep, AllStepResult from mlagents_envs.timers import ( TimerNode, @@ -35,7 +35,8 @@ from mlagents_envs.side_channel.side_channel import SideChannel from mlagents.trainers.brain_conversion_utils import group_spec_to_brain_parameters -logger = logging.getLogger("mlagents.trainers") + +logger = get_logger(__name__) class EnvironmentCommand(enum.Enum): diff --git a/ml-agents/mlagents/trainers/trainer/trainer.py b/ml-agents/mlagents/trainers/trainer/trainer.py index c01764b899..ee84803961 100644 --- a/ml-agents/mlagents/trainers/trainer/trainer.py +++ b/ml-agents/mlagents/trainers/trainer/trainer.py @@ -1,10 +1,10 @@ # # Unity ML-Agents Toolkit -import logging from typing import Dict, List, Deque, Any import abc from collections import deque +from mlagents_envs.logging_util import get_logger from mlagents.model_serialization import export_policy_model, SerializationSettings from mlagents.trainers.policy.tf_policy import TFPolicy from mlagents.trainers.stats import StatsReporter @@ -14,7 +14,8 @@ from mlagents.trainers.policy import Policy from mlagents.trainers.exception import UnityTrainerException -logger = logging.getLogger("mlagents.trainers") + +logger = get_logger(__name__) class Trainer(abc.ABC): diff --git a/ml-agents/mlagents/trainers/trainer_controller.py b/ml-agents/mlagents/trainers/trainer_controller.py index 7d87b110b8..fdba2a4312 100644 --- a/ml-agents/mlagents/trainers/trainer_controller.py +++ b/ml-agents/mlagents/trainers/trainer_controller.py @@ -4,13 +4,13 @@ import os import sys -import logging from typing import Dict, Optional, Set from collections import defaultdict import numpy as np from mlagents.tf_utils import tf +from mlagents_envs.logging_util import get_logger from mlagents.trainers.env_manager import EnvManager from mlagents_envs.exception import ( UnityEnvironmentException, @@ -55,7 +55,7 @@ def __init__( self.trainer_factory = trainer_factory self.model_path = model_path self.summaries_dir = summaries_dir - self.logger = logging.getLogger("mlagents.trainers") + self.logger = get_logger(__name__) self.run_id = run_id self.save_freq = save_freq self.train_model = train diff --git a/ml-agents/mlagents/trainers/trainer_util.py b/ml-agents/mlagents/trainers/trainer_util.py index a112da05c5..87849cbdcb 100644 --- a/ml-agents/mlagents/trainers/trainer_util.py +++ b/ml-agents/mlagents/trainers/trainer_util.py @@ -1,8 +1,8 @@ import os import yaml from typing import Any, Dict, TextIO -import logging +from mlagents_envs.logging_util import get_logger from mlagents.trainers.meta_curriculum import MetaCurriculum from mlagents.trainers.exception import TrainerConfigError from mlagents.trainers.trainer import Trainer @@ -11,7 +11,8 @@ from mlagents.trainers.sac.trainer import SACTrainer from mlagents.trainers.ghost.trainer import GhostTrainer -logger = logging.getLogger("mlagents.trainers") + +logger = get_logger(__name__) class TrainerFactory: diff --git a/setup.cfg b/setup.cfg index e728ceb30e..ecd551bdd7 100644 --- a/setup.cfg +++ b/setup.cfg @@ -20,3 +20,4 @@ ignore = I200, banned-modules = tensorflow = use mlagents.tf_utils instead (it handles tf2 compat). + logging = use mlagents_envs.logging_util instead