Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure logging.yml is optional and tidy logging config #1543

Merged
merged 21 commits into from
May 20, 2022

Conversation

antonymilne
Copy link
Contributor

@antonymilne antonymilne commented May 16, 2022

Description

Closes #1469.

In short, you no longer need to supply a project-side logging.yml file.

Sorry it's a bit of a huge PR to review, but the changes here are actually quite small. I've left lots of comments in the files that hopefully make it easier! Almost all the files changed are just updating tests. These are much simpler now because we don't have to provide a mock logging.yml file for them to run 🎉

Equivalent changes to starters templates are in kedro-org/kedro-starters#90.

Testing

Tested with and without a logging.yml the following commands:

  • kedro run
  • kedro run --runner=ParallelRunner
  • kedro info
  • kedro ipython
  • kedro jupyter lab
  • kedro run with an exception thrown in the pipeline
  • kedro package and then run packaged project

All work as expected, but it turns out there's actually always been a problem with the parallel runner not using the framework-side logging config. This problem is now more prominent because it means that if you don't have a project-side logging.yml the logging will disappear completely (because there's effectively no logging config at all in the runner any more). I'm going to make a separate issue to fix this as part of the point we already have in #1461 to try and improve the parallel runner's logging handling.

TODO

  • Update release notes
  • Make parallel runner logging ticket

Checklist

  • Read the contributing guidelines
  • Opened this PR as a 'Draft Pull Request' if it is work-in-progress
  • Updated the documentation to reflect the code changes
  • Added a description of this change in the RELEASE.md file
  • Added tests to cover my changes

Signed-off-by: Antony Milne <antony.milne@quantumblack.com>
Signed-off-by: Antony Milne <antony.milne@quantumblack.com>
Signed-off-by: Antony Milne <antony.milne@quantumblack.com>
Signed-off-by: Antony Milne <antony.milne@quantumblack.com>
Signed-off-by: Antony Milne <antony.milne@quantumblack.com>
Signed-off-by: Antony Milne <antony.milne@quantumblack.com>
…to feature/optional-logging-yml

Signed-off-by: Antony Milne <antony.milne@quantumblack.com>

# Conflicts:
#	features/steps/test_starter/{{ cookiecutter.repo_name }}/conf/base/logging.yml
#	kedro/templates/project/{{ cookiecutter.repo_name }}/conf/base/logging.yml
@@ -1,44 +1,21 @@
version: 1
Copy link
Contributor Author

@antonymilne antonymilne May 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of these changes are just formatting. What's actually changed here is:

  • removed info_file_handler and error_file_handler. These are now only defined on the project-side logging config
  • removed special case kedro.framework.cli.hooks.manager logger (which was the same as the default, just without the file-based handlers enabled. Now there's no file-based handlers it's exactly the same as the default, so no need to define it separately)

@@ -1,55 +1,44 @@
version: 1
Copy link
Contributor Author

@antonymilne antonymilne May 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes here are the same as to the template file - see explanation there.

@@ -1,55 +1,44 @@
version: 1
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of these changes are just formatting. What's actually changed here is:

  • removed json_formatter which was never used anywhere
  • removed the special case kedro.x loggers in favour of the generic kedro one, which did the same thing anyway
  • altered root logger so it no longer shows all INFO level messages (it's now the same as the framework-side logging config and doesn't specify this explicitly, so defaults to Python's WARNING level)
  • added a special logger for {{ cookiecutter.python_package }}. This is to ensure that calls like this still emit logs

antonymilne and others added 5 commits May 18, 2022 21:38
Signed-off-by: Antony Milne <antony.milne@quantumblack.com>
Signed-off-by: Antony Milne <antony.milne@quantumblack.com>
Signed-off-by: Antony Milne <antony.milne@quantumblack.com>
Signed-off-by: Antony Milne <antony.milne@quantumblack.com>
Comment on lines +80 to +87
class TestDefaultLogging:
def test_setup_root_logger(self):
root_logger = logging.getLogger()
assert "console" in {handler.name for handler in root_logger.handlers}

def test_setup_kedro_logger(self):
kedro_logger = logging.getLogger("kedro")
assert kedro_logger.level == logging.INFO
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are updated versions of tests that used to be in test_cli_logging_setup.py (tests were in the wrong place before, now that file is deleted).

Comment on lines +349 to +366
def test_no_logging_config(self, fake_project, caplog, mock_package_name, mocker):
caplog.set_level(logging.DEBUG, logger="kedro")

mocker.patch("subprocess.check_output")
session = KedroSession.create(mock_package_name, fake_project)
session.close()

expected_log_messages = [
"No project logging configuration loaded; "
"Kedro's default logging configuration will be used."
]
actual_log_messages = [
rec.getMessage()
for rec in caplog.records
if rec.name == SESSION_LOGGER_NAME and rec.levelno == logging.DEBUG
]
assert actual_log_messages == expected_log_messages

Copy link
Contributor Author

@antonymilne antonymilne May 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only vaguely interesting new test.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is specifically checking that we get that debug message, but the other tests aren't actually using logging config either right? So in theory they would all show that message in debug mode?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes indeed! Though some of the other tests have mocker.patch("kedro.framework.session.KedroSession._setup_logging") so the debug message won't be emitted there anyway.

Signed-off-by: Antony Milne <antony.milne@quantumblack.com>
Signed-off-by: Antony Milne <antony.milne@quantumblack.com>
Signed-off-by: Antony Milne <antony.milne@quantumblack.com>
Signed-off-by: Antony Milne <antony.milne@quantumblack.com>
from contextlib import contextmanager
from pathlib import Path
from time import sleep, time
from typing import Any, Callable, Iterator, List

import pandas as pd
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated to the logging changes. Just removing some unused code from e2e tests while I spotted it.

@@ -185,8 +185,15 @@ def _get_logging_config(self) -> Dict[str, Any]:

def _setup_logging(self) -> None:
"""Register logging specified in logging directory."""
conf_logging = self._get_logging_config()
configure_logging(conf_logging)
try:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the key change: we now allow there to be no logging.yml on the project-side.

@@ -1,19 +0,0 @@
"""This module contains unit tests for methods in the Kedro __init__.py
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These were in the wrong place and are now (in updated form) in test_cli.py.

Signed-off-by: Antony Milne <antony.milne@quantumblack.com>
@antonymilne antonymilne marked this pull request as ready for review May 19, 2022 09:26
@antonymilne antonymilne requested a review from idanov as a code owner May 19, 2022 09:26
@antonymilne antonymilne self-assigned this May 19, 2022
Copy link
Contributor

@AhdraMeraliQB AhdraMeraliQB left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nicely done! Great work on the description too, super helpful 🌟

Copy link
Member

@merelcht merelcht left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work @AntonyMilneQB ! 🤩 This has cleaned up the logging so much!

One minor question around testing, do we have any tests now that check stuff works correctly when the user has a custom project level logging.yml? I couldn't completely figure it out from the changes made to the tests.

Comment on lines +37 to +38
kedro:
level: INFO
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just so I understand correctly, what handlers is this logger now using? The ones specified for root?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, exactly! There's no handlers explicitly specified here, so it will propagate to root and use those.

Comment on lines +349 to +366
def test_no_logging_config(self, fake_project, caplog, mock_package_name, mocker):
caplog.set_level(logging.DEBUG, logger="kedro")

mocker.patch("subprocess.check_output")
session = KedroSession.create(mock_package_name, fake_project)
session.close()

expected_log_messages = [
"No project logging configuration loaded; "
"Kedro's default logging configuration will be used."
]
actual_log_messages = [
rec.getMessage()
for rec in caplog.records
if rec.name == SESSION_LOGGER_NAME and rec.levelno == logging.DEBUG
]
assert actual_log_messages == expected_log_messages

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is specifically checking that we get that debug message, but the other tests aren't actually using logging config either right? So in theory they would all show that message in debug mode?

@antonymilne
Copy link
Contributor Author

Great work @AntonyMilneQB ! 🤩 This has cleaned up the logging so much!

One minor question around testing, do we have any tests now that check stuff works correctly when the user has a custom project level logging.yml? I couldn't completely figure it out from the changes made to the tests.

Thank you! This is covered by test_setup_logging_using_absolute_path and also the e2e tests but it's not very explicit at the moment. I will change this so it's better.

antonymilne and others added 3 commits May 19, 2022 12:17
Signed-off-by: Antony Milne <antony.milne@quantumblack.com>
Signed-off-by: Antony Milne <antony.milne@quantumblack.com>
@antonymilne antonymilne merged commit 3560063 into main May 20, 2022
@antonymilne antonymilne deleted the feature/optional-logging-yml branch May 20, 2022 10:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Ensure logging.yml is optional and tidy logging config
3 participants