-
Notifications
You must be signed in to change notification settings - Fork 84
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
refactor: Improved logger usage #1373
Conversation
8d7ce2b
to
b48acf3
Compare
convert2rhel/main.py
Outdated
@@ -136,6 +136,7 @@ def main_locked(): | |||
initialize_file_logging("convert2rhel.log", logger_module.LOG_DIR) | |||
|
|||
try: | |||
logger_module.ConversionStage.set_stage("prepare") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about using ConversionPhase
for this? I think it could be really good to map the phases in that class to the ConversionStage
you created
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@r0x0d That's a good point. Though that made me dig down a rabbit hole of refactoring to be a bit nicer to use for more scenarios. What do you think of this?
class ConversionPhase:
"""Conversion phase to hold name and logging-friendly name.
"""
def __init__(self, name, log_name=None): # type: (str, str|None) -> None
self.name = name
self.log_name = log_name
def __str__(self):
return self.log_name
def __repr__(self):
return self.name
def __hash__(self) -> int:
return hash(self.name)
class ConversionPhases(dict):
"""During conversion we will be in different states depending on
where we are in the execution. This class establishes the different phases
that we have as well as what the current phase is set to.
"""
_phases = [
ConversionPhase(name="POST_CLI", log_name="Prepare"),
ConversionPhase(name="PRE_PONR_CHANGES", log_name="Prepare")
]
current_phase = None # type: ConversionPhase|None
def __getitem__(self, key): # type: (str) -> ConversionPhase|None
return next(phase for phase in self._phases if phase.name == key )
@classmethod
def set_stage(cls, phase): # type: (str) -> None
if phase is None or phase in cls._phases:
cls.current_phase = cls._phases[phase]
raise NotImplementedError("The stage {} is not implemented in the ConversionStage class".format(phase))
test = ConversionPhases()
print(test["POST_CLI"].__repr__)
$ python test.py
<bound method ConversionPhase.__repr__ of POST_CLI>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm, this work as well, but it is easy to introduce an error if we miss the correct naming in other parts of the code or introduce a new phase and forget about it.
I was thinking in something more simple, like this:
class ConversionPhase:
POST_CLI = 1
# PONR means Point Of No Return
PRE_PONR_CHANGES = 2
# Phase to exit the Analyze SubCommand early
ANALYZE_EXIT = 3
POST_PONR_CHANGES = 4
class ConversionStage:
stages = {
ConversionPhase.PRE_PONR_CHANGES: "Prepare",
ConversionPhase.POST_PONR_CHANGES: "Final",
...
}
current = None # type: str|None
@classmethod
def set_stage(cls, stage): # type: (str) -> None
if stage == None or stage in cls.stages:
cls.current = cls.stages[stage]
raise NotImplementedError("The stage {} is not implemented in the ConversionStage class".format(stage))
Then, when we initialize the ConversionStage
, we could just simply:
logger_module.ConversionStage.set_stage(ConversionPhase.PRE_PONR_CHANGES)
And then we have it mapped everywhere that PRE_PONR_CHANGES
matches the Prepare
or something else. The interface will still look clean enough in the new class, and we will make sure that if someone changes the meaning for any of those phases, we will catch somewhere as well.
Since our use case is so small for now, I think that reusing the phases from ConversionPhase
should be good enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think our ConversionPhase
class should hold the information where we are in the process at all times, being our source of truth for many different operations. It is true that logging phases may differ from execution phases, but if that's really the case, then we could come up with an intermediate class that will hold the logging phases for us, tied to the conversion phase if necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I didn't see this as I got hyperfocused on overcomplicating the solution... but anyhow I did change it now to be a bit safer but in a way that means we still rely on strings. But given exceptions being raised we should catch it in tests if we do a mistake
b48acf3
to
8002f6a
Compare
8002f6a
to
034d54a
Compare
034d54a
to
ba181c1
Compare
convert2rhel/utils/phase.py
Outdated
# Phase to exit the Analyze SubCommand early | ||
ANALYZE_EXIT = ConversionPhase(name="ANALYZE_EXIT") | ||
POST_PONR_CHANGES = ConversionPhase(name="POST_PONR_CHANGES", log_name="Convert") | ||
ROLLBACK = (ConversionPhase(name="ROLLBACK", log_name="Rollback"),) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ROLLBACK = (ConversionPhase(name="ROLLBACK", log_name="Rollback"),) | |
ROLLBACK = ConversionPhase(name="ROLLBACK", log_name="Rollback") |
ba181c1
to
183d94a
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1373 +/- ##
==========================================
- Coverage 96.59% 96.09% -0.51%
==========================================
Files 71 72 +1
Lines 5113 5174 +61
Branches 883 896 +13
==========================================
+ Hits 4939 4972 +33
- Misses 98 119 +21
- Partials 76 83 +7
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
e272c18
to
3c97895
Compare
/packit test --labels sanity |
2 similar comments
/packit test --labels sanity |
/packit test --labels sanity |
00ec140
to
e7f77f1
Compare
/packit test --labels sanity |
/packit build |
/packit test --labels sanity |
/packit test --labels sanity |
""" | ||
|
||
POST_CLI = ConversionPhase(name="POST_CLI") | ||
PREPARE = ConversionPhase(name="PREPARE", log_name="Prepare") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just wonder, when we are changing the logging and the final is renamed to convert (which makes sense to me) - what about changing the Prepare
to Analysis
(or something like that)? I think it would be nice to have it matching the subcommands (analyze and convert).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed and I had that before, but I wanted minimal changes in this PR to the actual logs so wanted it to remain the same. We can change it in a follow-up PR but requires a bit more discussion IMO
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay. Maybe if we want minimal changes, then I would change the name of the post_conversion to the Final
to be consistent
/packit test --labels sanity |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, just wait till the infrastructure problems are resolved and try the sanity tests.
/packit test --labels sanity |
/packit test |
/packit test |
1 similar comment
/packit test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changes look great!
I see the integration tests are failing and some of them related to the expected messages, maybe something got messed up? I can't see it. For example in integration tests in CentOS7 it expects to see CUSTOM_REPOSITORIES_ARE_VALID::UNABLE_TO_ACCESS_REPOSITORIES but instead C2R fails with:
convert2rhel("-y --no-rhsm --enablerepo fake-rhel-8-for-x86_64-baseos-rpms --debug", unregister=True)
(ERROR) REMOVE_SPECIAL_PACKAGES::SPECIAL_PACKAGE_REMOVAL_FAILED - Failed to
remove some packages necessary for the conversion.
Description: The cause of this error is unknown, please look at the
diagnosis for more information.
Diagnosis: Couldn't download the centos-
release-7-9.2009.2.el7.centos.x86_64 package. This means we will not be able to
do a complete rollback and may put the system in a broken state.
Check to make sure that the CentOS Linux repositories are enabled and the
package is updated to its latest version.
@SerCantus is it occurring in other PRs or in main? |
Signed-off-by: Freya Gustavsson <[email protected]>
This refactors the logging stages that we output when we log in specific files depending on what we are doing. Meaning that any changes that has to do with preparing or rollback will now output the stage within the logger formatter rather than leaving it up to each class E.g. any logs with "Prepare: text" or "Rollback: text" will now be handled at the log-level Signed-off-by: Freya Gustavsson <[email protected]>
Signed-off-by: Freya Gustavsson <[email protected]>
Signed-off-by: Freya Gustavsson <[email protected]>
Signed-off-by: Freya Gustavsson <[email protected]>
This removes all the different task log calls that include the stage it should be in and instead relies on the logger to take care of it e.g. `.task("Convert: ...")` will now have `Convert:` removed Signed-off-by: Freya Gustavsson <[email protected]>
ConversionPhases is now moved outside of utils module so that it doesn't cause a circular import with logger module Signed-off-by: Freya Gustavsson <[email protected]>
Signed-off-by: Freya Gustavsson <[email protected]>
Signed-off-by: Freya Gustavsson <[email protected]> Signed-off-by: Freya Gustavsson <[email protected]>
Signed-off-by: Freya Gustavsson <[email protected]>
Signed-off-by: Freya Gustavsson <[email protected]>
We didn't know what phase we were on before going into rollback. With this change it now keeps a (soft) linear history where each phase points to the previous one
03f291c
to
943cec0
Compare
/packit test |
@Venefilyn I commented after reviewing this PR checks but I see other PRs have similar failures so it might not be caused by this one. After discussing, it might be related to some infra. |
Ack, feel free to approve and merge with squash |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test failures unrelated.
There is a regression caused by #1288 reported under RHELC-1753
This refactor of the usage of our logging is to get away from custom
functions that causes attribute errors in editors and IDEs. This will
also standarize the usage of logger and the loglevels.
In future PRs we can include changes to include prepare, rollback, and
final specific message styles.
Jira Issues:
Depends on
Checklist
[RHELC-]
or[HMS-]
is part of the PR titleRelease Pending
if relevant