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

Prevent bootlooping due to a failed plugin load. #73

Merged
merged 1 commit into from
Jul 16, 2024

Conversation

aduane
Copy link
Collaborator

@aduane aduane commented Jul 16, 2024

We already skip plugins that fail to load due to an ImportError, this change increases the types of errors that would skip a plugin considerably. It is extremely important to prevent the process from crashing on load, as circus will immediately attempt to resurrect it, causing a bootloop.

We already skip plugins that fail to load due to an ImportError, this
change increases the types of errors that would skip a plugin
considerably. It is extremely important to prevent the process from
crashing on load, as circus will immediately attempt to resurrect it,
causing a bootloop.
@aduane aduane self-assigned this Jul 16, 2024
log.error(f"Error importing module '{name_and_class}': {err}")
for error_line in traceback.format_exception(err):
Copy link
Member

Choose a reason for hiding this comment

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

hmm why not just pass the whole exception to log.error?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It was a design goal to accomplish this in the most silly way possible. (I will fix)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Well wait, we do that above in the string interpolation. It doesn't show the whole stack. I would like the log output to show the line number of the offending class.

Copy link
Member

Choose a reason for hiding this comment

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

you would still call format_exception, but just pass the output to log.error directly rather than every line... let me test real quick if it actually does what I think

Copy link
Member

Choose a reason for hiding this comment

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

ok I stand corrected, how about this:

log.error('\n'.join(traceback.format_exception(err))

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This might just be a preference thing, but yours messes with the indent due to the single log timestamp vs one per line.

yours:

ERROR 2024-07-16 10:54:10,033 Error importing module 'search:search.protocols.condition:Protocol': EnumTypeWrapper.Name() takes 2 positional arguments but 3 were given
ERROR 2024-07-16 10:54:10,034 Traceback (most recent call last):

  File "/Users/andrew/src/canvas-plugins/plugin_runner/plugin_runner.py", line 198, in load_or_reload_plugin
    result = sandbox_from_module_name(protocol_module)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/Users/andrew/src/canvas-plugins/plugin_runner/plugin_runner.py", line 139, in sandbox_from_module_name
    return sandbox.execute()
           ^^^^^^^^^^^^^^^^^

  File "/Users/andrew/src/canvas-plugins/plugin_runner/sandbox.py", line 267, in execute
    exec(self.compile_result.code, self.scope)

  File "<string>", line 1, in <module>

  File "<string>", line 14, in Protocol

TypeError: EnumTypeWrapper.Name() takes 2 positional arguments but 3 were given

mine:

ERROR 2024-07-16 10:25:40,695 Error importing module 'search:search.protocols.condition:Protocol': EnumTypeWrapper.Name() takes 2 positional arguments but 3 were given
ERROR 2024-07-16 10:25:40,696 Traceback (most recent call last):

ERROR 2024-07-16 10:25:40,696   File "/Users/andrew/src/canvas-plugins/plugin_runner/plugin_runner.py", line 198, in load_or_reload_plugin
    result = sandbox_from_module_name(protocol_module)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

ERROR 2024-07-16 10:25:40,696   File "/Users/andrew/src/canvas-plugins/plugin_runner/plugin_runner.py", line 139, in sandbox_from_module_name
    return sandbox.execute()
           ^^^^^^^^^^^^^^^^^

ERROR 2024-07-16 10:25:40,696   File "/Users/andrew/src/canvas-plugins/plugin_runner/sandbox.py", line 267, in execute
    exec(self.compile_result.code, self.scope)

ERROR 2024-07-16 10:25:40,696   File "<string>", line 1, in <module>

ERROR 2024-07-16 10:25:40,696   File "<string>", line 14, in Protocol

ERROR 2024-07-16 10:25:40,696 TypeError: EnumTypeWrapper.Name() takes 2 positional arguments but 3 were given

Which do you prefer? I don't feel strongly.

Copy link
Member

Choose a reason for hiding this comment

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

i have a very slight preference for mine because it's easier to read i think... on the flip side it would be impossible to search for in kibana (whereas with your method you could search for all lines that start with ERROR) so maybe that's the more important criteria

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

You know, now that I think about it a bit more, having the individual error lines will be more important when the hostname is also included on the line so we can separate out overlapping logs in multi-container deployments.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

So if we keep it as-is, I'll just need a ✅

Copy link
Contributor

Choose a reason for hiding this comment

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

It doesn't help here if you want ERROR on every line, but I just wanted to note that log.exception('error message') formats and logs the traceback automatically without a need to call format_exception.

@aduane aduane merged commit 978eae8 into main Jul 16, 2024
2 checks passed
@aduane aduane deleted the ad/prevent-boot-looping branch July 16, 2024 18:28
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.

3 participants