Skip to content

Commit fc76b3e

Browse files
Rebase changes
1 parent a5e88cb commit fc76b3e

File tree

3 files changed

+5
-101
lines changed

3 files changed

+5
-101
lines changed

autosklearn/util/backend.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,6 @@ def __init__(self,
8989
# call the setup_logger with this port and update self.logger
9090
self.logger = None # type: Optional[PicklableClientLogger]
9191
self.create_directories()
92-
# This is the first place the logger gets created.
93-
# We want to make sure any logging forward sets the correct directory
94-
# were all files should be created
95-
logging.setup_logger(output_dir=self._temporary_directory)
96-
self._logger = logging.get_logger(__name__)
9792

9893
def setup_logger(self, port: int) -> None:
9994
self._logger = get_named_client_logger(

autosklearn/util/logging_.py

Lines changed: 5 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import socketserver
1111
import struct
1212
import threading
13+
import uuid
1314
from typing import Any, Dict, Optional, Type
1415

1516
import yaml
@@ -39,61 +40,7 @@ def setup_logger(
3940
output_dir, distributedlog_filename
4041
)
4142

42-
# Applying the configuration is expensive, because logging.config.dictConfig
43-
# reconstruct the logging singletons each time it is called. We only call it when
44-
# needed, and to do so, we created a initialized attributed to control if a logger
45-
# was created
46-
if not is_logging_config_applied(logging_config):
47-
logging.config.dictConfig(logging_config)
48-
for logger_name in list(logging_config['loggers'].keys()) + ['root']:
49-
if logger_name == 'root':
50-
logger = logging.getLogger()
51-
else:
52-
logger = logging.getLogger(logger_name)
53-
setattr(logger, 'initialized', True)
54-
55-
56-
def is_logging_config_applied(logging_config: Dict) -> bool:
57-
"""
58-
This functions check if the provided logging config is already applied to the environment.
59-
if it is not the case, it returns false.
60-
61-
The motivation towards this checking is that in multiprocessing the loggers might be lost,
62-
because a new worker in a new node might not have the logger configuration setup.
63-
64-
Parameters
65-
----------
66-
logging_config: (Dict)
67-
A logging configuration following the format specified in
68-
https://docs.python.org/3/library/logging.config.html
69-
70-
Returns
71-
-------
72-
(bool)
73-
True if a configuration has already been applied to the environment
74-
"""
75-
76-
# The logging config is a dictionary with
77-
# dict_keys(['version', 'disable_existing_loggers', 'formatters', 'handlers',
78-
# 'root', 'loggers']) . There are 2 things to check. Whether the logger changed
79-
# or whether the handlers changed
80-
81-
# Check the loggers
82-
for logger_name in list(logging_config['loggers'].keys()) + ['root']:
83-
84-
if logger_name == 'root':
85-
logger = logging.getLogger()
86-
else:
87-
logger = logging.getLogger(logger_name)
88-
89-
# Checking for the contents of the logging config is not feasible as the
90-
# logger uses a hierarchical structure, so depending on where this function is
91-
# called, the logger_name requires the full hierarchy (like autosklearn.automl)
92-
# But because loggers are singletons we can rely on the initialized attribute we
93-
# set on them on creation
94-
if not hasattr(logger, 'initialized'):
95-
return False
96-
return True
43+
logging.config.dictConfig(logging_config)
9744

9845

9946
def _create_logger(name: str) -> logging.Logger:
@@ -240,13 +187,7 @@ def _get_named_client_logger(
240187

241188
# local_logger is mainly used to create a TCP record which is going to be formatted
242189
# and handled by the main logger server. The main logger server sets up the logging format
243-
# that is desired, so we just make sure of two things.
244-
# First the local_logger below should not have extra handlers, or else we will be unecessarily
245-
# dumping more messages, in addition to the Socket handler we create below
246-
# Second, during each multiprocessing spawn, a logger is created
247-
# via the logger __setstate__, which is expensive. This is better handled with using
248-
# the multiprocessing logger
249-
local_logger = multiprocessing.get_logger()
190+
local_logger = _create_logger(str(uuid.uuid4()))
250191

251192
# Under this perspective, we print every msg (DEBUG) and let the server decide what to
252193
# dump. Also, the no propagate disable the root setup to interact with the client
@@ -257,7 +198,8 @@ def _get_named_client_logger(
257198
# The logger is a singleton, but the logger.handlers is a list. So we need to
258199
# check if it already has a socket handler on it
259200
socketHandler = logging.handlers.SocketHandler(host, port)
260-
if not any([handler for handler in local_logger.handlers if 'SocketHandler' in str(handler)]):
201+
registered_ports = [hdr.port for hdr in local_logger.handlers if 'SocketHandler' in str(hdr)]
202+
if port not in registered_ports:
261203
local_logger.addHandler(socketHandler)
262204

263205
return local_logger

test/test_util/test_logging.py

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@
1212

1313

1414
class LoggingTest(unittest.TestCase):
15-
def setUp(self):
16-
# We need a clean start for the logging
17-
logging.shutdown()
18-
reload(logging)
1915

2016
def test_setup_logger(self):
2117
# Test that setup_logger function correctly configures the logger
@@ -42,8 +38,6 @@ def test_setup_logger(self):
4238
self.assertEqual(logging.getLogger().getEffectiveLevel(), 10)
4339

4440
# Make sure we log to the desired directory
45-
# We have to call setup again, to clean the past logging
46-
self.setUp()
4741
logging_.setup_logger(output_dir=os.path.dirname(__file__),
4842
filename='test.log'
4943
)
@@ -53,30 +47,3 @@ def test_setup_logger(self):
5347
with open(os.path.join(os.path.dirname(__file__), 'test.log')) as fh:
5448
self.assertIn('test_setup_logger', ''.join(fh.readlines()))
5549
os.remove(os.path.join(os.path.dirname(__file__), 'test.log'))
56-
57-
def test_setup_logger_called_when_needed(self):
58-
59-
# Create the testing configuration
60-
with open(os.path.join(os.path.dirname(__file__), 'example_config.yaml'), 'r') as fh:
61-
example_config = yaml.safe_load(fh)
62-
63-
logging_config = copy.deepcopy(example_config)
64-
output_dir = tempfile.gettempdir()
65-
filename = logging_config['handlers']['file_handler']['filename']
66-
logging_config['handlers']['file_handler']['filename'] = os.path.join(
67-
output_dir, filename
68-
)
69-
distributedlog_filename = logging_config['handlers']['distributed_logfile']['filename']
70-
logging_config['handlers']['distributed_logfile']['filename'] = os.path.join(
71-
output_dir, distributedlog_filename
72-
)
73-
74-
# We have not yet sourced any configuration
75-
self.assertFalse(logging_.is_logging_config_applied(logging_config=logging_config))
76-
77-
# Then setup the logging config
78-
logging_.setup_logger(logging_config=example_config,
79-
output_dir=tempfile.gettempdir())
80-
81-
# Then here we do not expect the configuration to change
82-
self.assertTrue(logging_.is_logging_config_applied(logging_config=logging_config))

0 commit comments

Comments
 (0)