Repository: kedro-org/kedro

Issue:
Make sure project logs of INFO level are shown
> **Note**. Technically this is non-breaking, but best to do this following https://github.com/kedro-org/kedro/issues/2426, which is a breaking change. Hence this is for 0.19.0.

We are removing logging.yml from the project template (see https://github.com/kedro-org/kedro/issues/2281). However, there's a subtle piece of functionality that exists in project-side logging.yml that's not easily reproduced in the framework-side one: the project-side logging.yml has something like this:
```
loggers:
  kedro:
    level: INFO

  iris:
    level: INFO
```

It's not possible to put this in the framework-side logging.yml because you don't know what the project name is there. We can achieve this by adding it in the Python code in `framework/project/__init__.py` though by using `PACKAGE_NAME` (defined in `configure_project`), something like this:

```
logging_config["loggers"].append(PACKAGE_NAME: {"level": "INFO"})
```

_Originally posted by @AntonyMilneQB in https://github.com/kedro-org/kedro/issues/2281#issuecomment-1419040400_
            


Discussion:

Resolving patch:
diff --git a/kedro/framework/project/__init__.py b/kedro/framework/project/__init__.py
--- a/kedro/framework/project/__init__.py
+++ b/kedro/framework/project/__init__.py
@@ -226,6 +226,14 @@ def configure(self, logging_config: dict[str, Any]) -> None:
         logging.config.dictConfig(logging_config)
         self.data = logging_config
 
+    def set_project_logging(self, package_name: str):
+        """Add the project level logging to the loggers upon provision of a package name.
+        Checks if project logger already exists to prevent overwriting, if none exists
+        it defaults to setting project logs at INFO level."""
+        if package_name not in self.data["loggers"]:
+            self.data["loggers"][package_name] = {"level": "INFO"}
+            self.configure(self.data)
+
 
 PACKAGE_NAME = None
 LOGGING = _ProjectLogging()
@@ -252,6 +260,9 @@ def configure_project(package_name: str):
     global PACKAGE_NAME
     PACKAGE_NAME = package_name
 
+    if PACKAGE_NAME:
+        LOGGING.set_project_logging(PACKAGE_NAME)
+
 
 def configure_logging(logging_config: dict[str, Any]) -> None:
     """Configure logging according to ``logging_config`` dictionary."""


Test patch:
diff --git a/tests/framework/conftest.py b/tests/framework/conftest.py
new file mode 100644
--- /dev/null
+++ b/tests/framework/conftest.py
@@ -0,0 +1,26 @@
+import pytest
+
+from kedro.framework.project import configure_logging
+
+
+@pytest.fixture
+def default_logging_config():
+    logging_config = {
+        "version": 1,
+        "disable_existing_loggers": False,
+        "handlers": {
+            "rich": {"class": "kedro.logging.RichHandler", "rich_tracebacks": True}
+        },
+        "loggers": {"kedro": {"level": "INFO"}},
+        "root": {"handlers": ["rich"]},
+    }
+    return logging_config
+
+
+@pytest.fixture(autouse=True)
+def reset_logging(request, default_logging_config):
+    yield
+    if "nologreset" in request.keywords:
+        return
+
+    configure_logging(default_logging_config)
diff --git a/tests/framework/project/test_logging.py b/tests/framework/project/test_logging.py
--- a/tests/framework/project/test_logging.py
+++ b/tests/framework/project/test_logging.py
@@ -6,35 +6,36 @@
 import pytest
 import yaml
 
-from kedro.framework.project import LOGGING, configure_logging
+from kedro.framework.project import LOGGING, configure_logging, configure_project
 
 
 @pytest.fixture
-def default_logging_config():
+def default_logging_config_with_project():
     logging_config = {
         "version": 1,
         "disable_existing_loggers": False,
         "handlers": {
             "rich": {"class": "kedro.logging.RichHandler", "rich_tracebacks": True}
         },
-        "loggers": {"kedro": {"level": "INFO"}},
+        "loggers": {"kedro": {"level": "INFO"}, "test_project": {"level": "INFO"}},
         "root": {"handlers": ["rich"]},
     }
     return logging_config
 
 
-@pytest.fixture(autouse=True)
-def reset_logging(default_logging_config):
-    yield
-    configure_logging(default_logging_config)
-
-
 def test_default_logging_config(default_logging_config):
     assert LOGGING.data == default_logging_config
     assert "rich" in {handler.name for handler in logging.getLogger().handlers}
     assert logging.getLogger("kedro").level == logging.INFO
 
 
+def test_project_logging_in_default_logging_config(default_logging_config_with_project):
+    configure_project("test_project")
+    assert LOGGING.data == default_logging_config_with_project
+    assert logging.getLogger("kedro").level == logging.INFO
+    assert logging.getLogger("test_project").level == logging.INFO
+
+
 def test_environment_variable_logging_config(monkeypatch, tmp_path):
     config_path = Path(tmp_path) / "logging.yml"
     monkeypatch.setenv("KEDRO_LOGGING_CONFIG", config_path.absolute())
diff --git a/tests/framework/session/test_session_hook_manager.py b/tests/framework/session/test_session_hook_manager.py
--- a/tests/framework/session/test_session_hook_manager.py
+++ b/tests/framework/session/test_session_hook_manager.py
@@ -36,11 +36,13 @@ class MockSettings(_ProjectSettings):
 class TestSessionHookManager:
     """Test the process of registering hooks with the hook manager in a session."""
 
+    @pytest.mark.nologreset
     def test_assert_register_hooks(self, project_hooks, mock_session):
         hook_manager = mock_session._hook_manager
         assert hook_manager.is_registered(project_hooks)
 
     @pytest.mark.usefixtures("mock_session")
+    @pytest.mark.nologreset
     def test_calling_register_hooks_twice(self, project_hooks, mock_session):
         """Calling hook registration multiple times should not raise"""
         hook_manager = mock_session._hook_manager
@@ -51,6 +53,7 @@ def test_calling_register_hooks_twice(self, project_hooks, mock_session):
         assert hook_manager.is_registered(project_hooks)
 
     @pytest.mark.parametrize("num_plugins", [0, 1])
+    @pytest.mark.nologreset
     def test_hooks_registered_when_session_created(
         self, mocker, request, caplog, project_hooks, num_plugins
     ):
@@ -81,6 +84,7 @@ def test_hooks_registered_when_session_created(
             assert expected_msg in log_messages
 
     @pytest.mark.usefixtures("mock_settings_with_disabled_hooks")
+    @pytest.mark.nologreset
     def test_disabling_auto_discovered_hooks(
         self,
         mocker,