Skip to content

Commit 1d6e956

Browse files
diningPhilosopher64Prabhakar Kumar
authored andcommitted
Fixes bug which prevented users from setting log level to DEBUG on Windows. matlab-proxy now logs to matlab_logs.txt or to the file pointed to by MWI_LOG_FILE when log level is set to DEBUG.
1 parent 3483d9f commit 1d6e956

File tree

5 files changed

+97
-26
lines changed

5 files changed

+97
-26
lines changed

matlab_proxy/app_state.py

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,15 @@
1111
from typing import Final
1212

1313
from matlab_proxy import util
14-
from matlab_proxy.settings import get_process_startup_timeout
15-
from matlab_proxy.constants import CONNECTOR_SECUREPORT_FILENAME, VERSION_INFO_FILE_NAME
14+
from matlab_proxy.settings import (
15+
get_process_startup_timeout,
16+
get_default_mwi_log_file_path,
17+
)
18+
from matlab_proxy.constants import (
19+
CONNECTOR_SECUREPORT_FILENAME,
20+
MATLAB_LOGS_FILE_NAME,
21+
VERSION_INFO_FILE_NAME,
22+
)
1623
from matlab_proxy.util import mw, mwi, system, windows
1724
from matlab_proxy.util.mwi import environment_variables as mwi_env
1825
from matlab_proxy.util.mwi import token_auth
@@ -663,7 +670,23 @@ async def __setup_env_for_matlab(self) -> dict:
663670
# Env setup related to logging
664671
# Very verbose logging in debug mode
665672
if logger.isEnabledFor(logging.getLevelName("DEBUG")):
666-
matlab_env["MW_DIAGNOSTIC_DEST"] = "stdout"
673+
mwi_log_file = self.settings.get("mwi_log_file", None)
674+
# If a log file is supplied to write matlab-proxy server logs,
675+
# use it to write MATLAB logs too.
676+
if mwi_log_file:
677+
# Append MATLAB logs to matlab-proxy logs
678+
matlab_env["MW_DIAGNOSTIC_DEST"] = f"file,append={mwi_log_file}"
679+
680+
elif system.is_posix():
681+
matlab_env["MW_DIAGNOSTIC_DEST"] = "stdout"
682+
683+
else:
684+
# On windows stdout is not supported yet.
685+
# So, use the default log file for MATLAB logs
686+
default_matlab_logs_file = get_default_mwi_log_file_path()
687+
# Write MATLAB logs
688+
matlab_env["MW_DIAGNOSTIC_DEST"] = f"file={default_matlab_logs_file}"
689+
667690
matlab_env[
668691
"MW_DIAGNOSTIC_SPEC"
669692
] = "connector::http::server=all;connector::lifecycle=all"

matlab_proxy/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
CONNECTOR_SECUREPORT_FILENAME: Final[str] = "connector.securePort"
77
VERSION_INFO_FILE_NAME: Final[str] = "VersionInfo.xml"
88
MAX_HTTP_REQUEST_SIZE: Final[int] = 500_000_000 # 500MB
9+
MATLAB_LOGS_FILE_NAME: Final[str] = "matlab_logs.txt"
910

1011
# Max startup duration in seconds for processes launched by matlab-proxy
1112
# This constant is meant for internal use within matlab-proxy

matlab_proxy/settings.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,10 @@ def get_mwi_config_folder(dev=False):
150150
return config_folder_path
151151

152152

153+
def get_default_mwi_log_file_path():
154+
return get_mwi_config_folder() / constants.MATLAB_LOGS_FILE_NAME
155+
156+
153157
def get_mwi_logs_root_dir(dev=False):
154158
return get_mwi_config_folder(dev) / "ports"
155159

@@ -283,6 +287,10 @@ def get_server_settings(config_name):
283287
os.getenv(mwi_env.get_env_name_ssl_key_file(), None),
284288
os.getenv(mwi_env.get_env_name_ssl_cert_file(), None),
285289
)
290+
291+
# log file validation check is already done in logger.py
292+
mwi_log_file = os.getenv(mwi_env.get_env_name_log_file(), None)
293+
286294
return {
287295
"create_xvfb_cmd": create_xvfb_cmd,
288296
"base_url": mwi.validators.validate_base_url(
@@ -302,6 +310,7 @@ def get_server_settings(config_name):
302310
# This directory will be used to store connector.securePort(matlab_ready_file) and its corresponding files. This will be
303311
# a central place to store logs of all the running instances of MATLAB launched by matlab-proxy
304312
"mwi_logs_root_dir": get_mwi_logs_root_dir(),
313+
"mwi_log_file": mwi_log_file,
305314
"mw_context_tags": get_mw_context_tags(config_name),
306315
# The url where the matlab-proxy server is accessible at
307316
"mwi_server_url": None,

matlab_proxy/util/mwi/logger.py

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44

55
import logging
66
import os
7+
import sys
8+
from pathlib import Path
79

810
from . import environment_variables as mwi_env
911

12+
1013
logging.getLogger("aiohttp_session").setLevel(logging.ERROR)
1114

1215

@@ -47,19 +50,35 @@ def __set_logging_configuration():
4750
Logger: Logger object with the set configuration.
4851
"""
4952
# query for user specified environment variables
50-
log_level, log_file = __query_environment()
53+
log_level = os.getenv(
54+
mwi_env.get_env_name_logging_level(), __get_default_log_level()
55+
)
56+
log_file = os.getenv(mwi_env.get_env_name_log_file(), None)
5157

5258
## Set logging object
5359
logger = __get_mw_logger()
54-
if log_file is not None:
55-
logger.info(f"Initializing logger with log_file:{log_file}")
56-
file_handler = logging.FileHandler(filename=log_file)
57-
formatter = logging.Formatter(
58-
fmt="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
59-
)
60-
file_handler.setFormatter(formatter)
61-
file_handler.setLevel(log_level)
62-
logger.addHandler(file_handler)
60+
try:
61+
if log_file:
62+
log_file = Path(log_file)
63+
# Need to create the file if it doesn't exist or else logging.FileHandler
64+
# would open it in 'write' mode instead of 'append' mode.
65+
log_file.touch(exist_ok=True)
66+
logger.info(f"Initializing logger with log file:{log_file}")
67+
file_handler = logging.FileHandler(filename=log_file, mode="a")
68+
formatter = logging.Formatter(
69+
fmt="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
70+
)
71+
file_handler.setFormatter(formatter)
72+
file_handler.setLevel(log_level)
73+
logger.addHandler(file_handler)
74+
75+
except PermissionError:
76+
print(f"PermissionError: Permission denied to create log file at: {log_file}")
77+
sys.exit(1)
78+
79+
except Exception as err:
80+
print(f"Failed to use log file: {log_file} with error: {err}")
81+
sys.exit(1)
6382

6483
# log_level is either set by environment or is the default value.
6584
logger.info(f"Initializing logger with log_level: {log_level}")
@@ -91,16 +110,3 @@ def __get_default_log_level():
91110
String: The default logging level
92111
"""
93112
return "INFO"
94-
95-
96-
def __query_environment():
97-
"""Private function to query environment variables
98-
to control logging
99-
100-
Returns:
101-
tuple: Log level & Log file as found in the environment
102-
"""
103-
env_var_log_level, env_var_log_file = get_environment_variable_names()
104-
log_level = os.environ.get(env_var_log_level, __get_default_log_level())
105-
log_file = os.environ.get(env_var_log_file)
106-
return log_level, log_file

tests/unit/test_app_state.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,3 +395,35 @@ def test_env_variables_filtration_for_xvfb_process(
395395

396396
# Assert
397397
assert filtered_env_vars.get(env_var) == is_filtered
398+
399+
400+
@pytest.mark.parametrize("platform", [("linux"), ("windows"), ("mac")])
401+
async def test_setup_env_for_matlab(
402+
mocker_os_patching_fixture, platform, app_state_fixture, tmp_path
403+
):
404+
"""Test to check MW_DIAGNOSTIC_DEST is set appropriately for posix and non-posix systems
405+
406+
Args:
407+
mocker_os_patching_fixture (mocker): Custom pytest fixture for mocking
408+
platform (str): string describing a platform
409+
app_state_fixture (AppState): Object of AppState class with defaults set
410+
tmp_path (Path): Built-in pytest fixture for temporary paths
411+
"""
412+
413+
# Arrange
414+
expected_log_file_path = tmp_path / "matlab_logs.txt"
415+
app_state_fixture.licensing = {"type": "existing_license"}
416+
app_state_fixture.settings = {"mwapikey": None, "matlab_display": ":1"}
417+
app_state_fixture.mwi_logs_dir = tmp_path
418+
mocker_os_patching_fixture.patch(
419+
"matlab_proxy.app_state.logger.isEnabledFor", return_value=True
420+
)
421+
422+
# Act
423+
matlab_env = await app_state_fixture._AppState__setup_env_for_matlab()
424+
425+
# Assert
426+
if "linux" or "mac" in platform:
427+
assert matlab_env["MW_DIAGNOSTIC_DEST"] == "stdout"
428+
else:
429+
assert matlab_env["MW_DIAGNOSTIC_DEST"] == expected_log_file_path

0 commit comments

Comments
 (0)