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

Add logs on docker build failure #7675

Merged
merged 7 commits into from
Dec 13, 2024

Conversation

palfrey
Copy link
Contributor

@palfrey palfrey commented Nov 13, 2024

Which issue(s) does this change fix?

#7671

Why is this change necessary?

So we can actually debug Docker build issues

How does it address the issue?

By adding logs :)

What side effects does this change have?

None

Mandatory Checklist

PRs will only be reviewed after checklist is complete

  • Add input/output type hints to new functions/methods
  • Write design document if needed (Do I need to write a design document?)
  • Write/update unit tests
  • Write/update integration tests
  • Write/update functional tests if needed
  • make pr passes
  • make update-reproducible-reqs if dependencies were changed
  • Write documentation

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@palfrey palfrey changed the base branch from main to develop November 13, 2024 10:57
@palfrey palfrey requested a review from a team as a code owner November 13, 2024 10:57
@palfrey palfrey requested review from mndeveci and sidhujus November 13, 2024 10:57
@@ -430,6 +430,11 @@ def _build_lambda_image(self, function_name: str, metadata: Dict, architecture:
LOG.debug("%s image is built for %s function", build_image, function_name)
except docker.errors.BuildError as ex:
LOG.error("Failed building function %s", function_name)
for log in ex.build_log:
if "stream" in log:
self._stream_writer.write_str(log["stream"])
Copy link
Contributor

@jonife jonife Nov 15, 2024

Choose a reason for hiding this comment

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

When writing to _stream_writer, I think checking it should be clear what type of output is shown. I think we should include context to indicate whether it is part of a standard log or an error message, such as prepending "[Error]: " when writing log["error"]. I was thinking

except docker.errors.BuildError as ex:
    LOG.error("Failed building function %s", function_name)
    for log in ex.build_log:
        if "stream" in log:
            self._stream_writer.write_str(f"Log: {log['stream']}")
        elif "error" in log:
            self._stream_writer.write_str(f"[Error]: {log['error']}")
        else:
            LOG.warning("Unexpected log entry format: %s", log)

Comment on lines 433 to 437
for log in ex.build_log:
if "stream" in log:
self._stream_writer.write_str(log["stream"])
elif "error" in log:
self._stream_writer.write_str(log["error"])
Copy link
Member

Choose a reason for hiding this comment

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

Seems we have a very similar function here

self._stream_lambda_image_build_logs(build_logs, function_name)

I wonder if it's possible to reuse this function in this place

Suggested change
for log in ex.build_log:
if "stream" in log:
self._stream_writer.write_str(log["stream"])
elif "error" in log:
self._stream_writer.write_str(log["error"])
self._stream_lambda_image_build_logs(ex.build_log, function_name)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Looked at that initially, but rejected because the _stream_lambda_image_build_logs uses LogStreamer._stream_write which will throw a LogStreamError if it sees an error rather than logging it. Provided the logs are always of the form <several 'stream' errors>,<one 'error' log> this will work, otherwise not.

This is incompatible with @jonife's suggestion from above BTW. Which one should I build?

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for the clarification. Yes you are right. This function won't work on logs that has multiple error. Maybe we can consider adding a param in LogStreamer to suppress the error. In this way it will also address @jonife concerns

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Adding the param would work, I'll have a look at that. It won't address @jonife's concerns though, as LogStreamer doesn't write anything about what sort of log it is. My experiments with it so far indicate that for the usual Docker log patterns it literally does what my patch did (minus the error problems).

@palfrey palfrey requested a review from roger-zhangg November 18, 2024 13:44
@roger-zhangg
Copy link
Member

@palfrey Thanks for implementing the change! FYI here I believe this is a vaild test failure in CI, please check

FAILED tests/unit/lib/build_module/test_app_builder.py::TestApplicationBuilder_build_lambda_image_function::test_can_raise_build_error - AssertionError: [call('Some earlier log'), call(''), call('Build failed'), call('\r\n')] != [call('Some earlier log'), call(''), call('Build failed'), call('\n')]

@palfrey
Copy link
Contributor Author

palfrey commented Nov 18, 2024

@palfrey Thanks for implementing the change! FYI here I believe this is a vaild test failure in CI, please check

FAILED tests/unit/lib/build_module/test_app_builder.py::TestApplicationBuilder_build_lambda_image_function::test_can_raise_build_error - AssertionError: [call('Some earlier log'), call(''), call('Build failed'), call('\r\n')] != [call('Some earlier log'), call(''), call('Build failed'), call('\n')]

Looks like a Windows-specific line-ending failure. Got a probable fix, but no local Windows machine so will have to rely on CI to test this one.

Comment on lines -76 to +81
raise LogStreamError(msg=error)
if self._throw_on_error:
raise LogStreamError(msg=error)
else:
self._stream.write_str(error)
return
Copy link
Contributor

Choose a reason for hiding this comment

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

When we write this to the error stream, shouldn't we also throw it again? Changing this variable into opposite boolean to indicate whether an error should be written into stream or not could be better 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, because you might have multiple error lines. Also the throw in this features case is with the whole Docker build exception as the content vs just an individual error line.

Copy link
Member

@roger-zhangg roger-zhangg left a comment

Choose a reason for hiding this comment

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

LGTM ❤️

Copy link
Contributor

@jonife jonife left a comment

Choose a reason for hiding this comment

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

Thank you for your contribution

@mndeveci mndeveci removed their request for review November 27, 2024 19:47
@palfrey
Copy link
Contributor Author

palfrey commented Dec 8, 2024

So how does this get final approval? Anyone have any sense of the timelines on this one?

@roger-zhangg roger-zhangg added this pull request to the merge queue Dec 13, 2024
Merged via the queue into aws:develop with commit 59abce3 Dec 13, 2024
55 checks passed
@palfrey palfrey deleted the add-docker-build-logs branch December 13, 2024 23:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants