Skip to content

Commit 28c8ee5

Browse files
GitHKAndrei Neagu
and
Andrei Neagu
authored
🎨 Persistent logs when GC removes services (#6403)
Co-authored-by: Andrei Neagu <[email protected]>
1 parent ec000db commit 28c8ee5

File tree

4 files changed

+71
-2
lines changed

4 files changed

+71
-2
lines changed

packages/service-library/src/servicelib/logging_utils.py

+5
Original file line numberDiff line numberDiff line change
@@ -392,3 +392,8 @@ def guess_message_log_level(message: str) -> LogLevelInt:
392392
):
393393
return logging.WARNING
394394
return logging.INFO
395+
396+
397+
def set_parent_module_log_level(current_module: str, desired_log_level: int) -> None:
398+
parent_module = ".".join(current_module.split(".")[:-1])
399+
logging.getLogger(parent_module).setLevel(desired_log_level)

packages/service-library/tests/test_logging_utils.py

+55
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
log_context,
1515
log_decorator,
1616
log_exceptions,
17+
set_parent_module_log_level,
1718
)
1819

1920
_logger = logging.getLogger(__name__)
@@ -322,3 +323,57 @@ def test_log_exceptions_and_reraise(caplog: pytest.LogCaptureFixture, level: int
322323

323324
assert len(caplog.records) == (1 if level != logging.NOTSET else 0)
324325
assert all(r.levelno == level for r in caplog.records)
326+
327+
328+
def test_set_parent_module_log_level_(caplog: pytest.LogCaptureFixture):
329+
caplog.clear()
330+
# emulates service logger
331+
logging.root.setLevel(logging.WARNING)
332+
333+
parent = logging.getLogger("parent")
334+
child = logging.getLogger("parent.child")
335+
336+
assert parent.level == logging.NOTSET
337+
assert child.level == logging.NOTSET
338+
339+
parent.debug("parent debug")
340+
child.debug("child debug")
341+
342+
parent.info("parent info")
343+
child.info("child info")
344+
345+
parent.warning("parent warning")
346+
child.warning("child warning")
347+
348+
assert "parent debug" not in caplog.text
349+
assert "child debug" not in caplog.text
350+
351+
assert "parent info" not in caplog.text
352+
assert "child info" not in caplog.text
353+
354+
assert "parent warning" in caplog.text
355+
assert "child warning" in caplog.text
356+
357+
caplog.clear()
358+
set_parent_module_log_level("parent.child", logging.INFO)
359+
360+
assert parent.level == logging.INFO
361+
assert child.level == logging.NOTSET
362+
363+
parent.debug("parent debug")
364+
child.debug("child debug")
365+
366+
parent.info("parent info")
367+
child.info("child info")
368+
369+
parent.warning("parent warning")
370+
child.warning("child warning")
371+
372+
assert "parent debug" not in caplog.text
373+
assert "child debug" not in caplog.text
374+
375+
assert "parent info" in caplog.text
376+
assert "child info" in caplog.text
377+
378+
assert "parent warning" in caplog.text
379+
assert "child warning" in caplog.text

services/web/server/src/simcore_service_webserver/garbage_collector/_core_disconnected.py

+3
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,9 @@ async def remove_disconnected_user_resources(
106106
# inform that the project can be closed on the backend side
107107
#
108108
try:
109+
_logger.info(
110+
"Closing services for project '%s'", resource_value
111+
)
109112
await remove_project_dynamic_services(
110113
user_id=user_id,
111114
project_uuid=f"{resource_value}",

services/web/server/src/simcore_service_webserver/garbage_collector/plugin.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
from aiohttp import web
44
from servicelib.aiohttp.application_setup import ModuleCategory, app_module_setup
5+
from servicelib.logging_utils import set_parent_module_log_level
56

7+
from ..application_settings import get_application_settings
68
from ..login.plugin import setup_login_storage
79
from ..projects.db import setup_projects_db
810
from ..socketio.plugin import setup_socketio
@@ -11,14 +13,14 @@
1113
from ._tasks_users import create_background_task_for_trial_accounts
1214
from .settings import get_plugin_settings
1315

14-
logger = logging.getLogger(__name__)
16+
_logger = logging.getLogger(__name__)
1517

1618

1719
@app_module_setup(
1820
"simcore_service_webserver.garbage_collector",
1921
ModuleCategory.ADDON,
2022
settings_name="WEBSERVER_GARBAGE_COLLECTOR",
21-
logger=logger,
23+
logger=_logger,
2224
)
2325
def setup_garbage_collector(app: web.Application) -> None:
2426
# - project-api needs access to db
@@ -32,6 +34,10 @@ def setup_garbage_collector(app: web.Application) -> None:
3234

3335
app.cleanup_ctx.append(run_background_task)
3436

37+
set_parent_module_log_level(
38+
_logger.name, min(logging.INFO, get_application_settings(app).log_level)
39+
)
40+
3541
# NOTE: scaling web-servers will lead to having multiple tasks upgrading the db
3642
# not a huge deal. Instead this task runs in the GC.
3743
# If more tasks of this nature are needed, we should setup some sort of registration mechanism

0 commit comments

Comments
 (0)