-
Notifications
You must be signed in to change notification settings - Fork 3
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
Moved logger to common #45
Conversation
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.
reviewed
read_yaml/yaml.py
Outdated
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.
rename to read_yaml.py
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.
Added comments. Also, would need to rebase to main after Python 3.11 fix is merged.
logger/modules/logger_setup_main.py
Outdated
logging_path = pathlib.Path(log_directory_path, start_time) | ||
|
||
# Create logging directory | ||
pathlib.Path(log_directory_path).mkdir(exist_ok=True) |
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.
Perhaps we want to have parent=True in case parent directories need to be created as well
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.
Edit: Just set parent=True in the next line, and delete this one
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.
*reminder
logger/modules/logger.py
Outdated
# pylint: disable-next=unused-import | ||
import types | ||
|
||
from read_yaml.modules import read_yaml |
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.
This warrants some discussion. Since common is meant to be imported as a submodule, everything needs to be a relative import. This code will fail when being used as a submodule. However, because Python does not support sibling module imports, (ie you cannot import read_yaml from logger since they're both at the root level) this causes some problems. We must ensure that all top-level modules (like logger) are independent and do not depend upon anything other top-level modules. So we must put yaml_tools inside of logger. Then there is the question "what if another modules wants to use yaml tools?". (eg. camera_qr_example.py
would not work if you tried to do py -m modules.common.camera_qr_example
after importing common into airside)
- You can keep it as it is and manually edit all the imports when you use common in another project (since now common is no longer the root). (eg changing
from camera.modules import ...
tofrom .camera.modules import ...
after initializing the common submodule, seems annoying and lot of effort) - We can put everything in another folder (like common/tools), but then all of our imports will have an extra .tools, which may look ugly. (eg
py -m modules.common.tools.camera_qr_example
) - We copy yaml_tools in all of the modules that needs it (this is sort of how dronekit is implemented currently, except only one of the modules, mavlink, needs dronekit)
Feel free to discuss, but this is an organizational issue we need to resolve
logger/test_logger_integration.py
Outdated
from read_yaml.modules import read_yaml | ||
|
||
|
||
def main() -> int: |
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.
Can this not be tested with pytest? If all logger does is write to stdout and stderr, you should be able to test that using pytest. If so, I would recommend making this a pytest because at least I would be too lazy to manually run all these tests lmao. (I'm not too familiar with python's logging module)
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.
Reviewed some more
config_logger.yaml
Outdated
@@ -0,0 +1,5 @@ | |||
logger: |
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.
It would be nice to have a link to documentation on the format strings
logger/modules/logger.py
Outdated
from read_yaml.modules import read_yaml | ||
|
||
|
||
CONFIG_FILE_PATH = pathlib.Path("config_logger.yaml") |
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 have not checked, but I believe relative paths like this depend on where the command is executed. So similar to the relative imports issue, this would work if run from py -m common...
(since you are in common folder) but will probably fail when running from py -m modules.common...
(since you are in airside folder). Someone should test this, and I think using the __file__
variable can help in this situation.
logger/modules/logger_setup_main.py
Outdated
logging_path = pathlib.Path(log_directory_path, start_time) | ||
|
||
# Create logging directory | ||
pathlib.Path(log_directory_path).mkdir(exist_ok=True) |
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.
Edit: Just set parent=True in the next line, and delete this one
logger/modules/logger.py
Outdated
entries = os.listdir(log_directory_path) | ||
|
||
if len(entries) == 0: | ||
print("ERROR: Must create a new log directory for this run before starting logger") |
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.
Rather than "log directory", which is confusing with the base "directory_path" from the yaml, we can say "No previous logging sessions available"
logger/test_logger_unit.py
Outdated
import inspect | ||
import pytest | ||
|
||
from logger.modules import logger |
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.
Same: relative path
read_yaml/test_read_yaml.py
Outdated
|
||
import pathlib | ||
|
||
from read_yaml.modules import read_yaml |
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.
Same: relative path
b7c4a8f
to
57233f5
Compare
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.
Reviewed
logger/modules/logger_setup_main.py
Outdated
assert main_logger is not None | ||
|
||
frame = inspect.currentframe() | ||
main_logger.info(f"{MAIN_LOGGER_NAME} logger initialized", frame) |
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.
Do we still not want to use the custom name? If so I'd rather just write "main" straight into the string so it's less confusing, because this looks like the default name if the user didn't provide one.
logger/test_logger.py
Outdated
@pytest.fixture | ||
def logger_instance_to_file_enabled() -> logger.Logger: # type: ignore | ||
""" | ||
Returns a logger with logging to file disabled. |
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.
Typo in docstring: enabled not disabled?
logger/modules/logger_setup_main.py
Outdated
def setup_main_logger( | ||
config: "dict", main_logger_name: str = MAIN_LOGGER_NAME | ||
) -> "tuple[bool, logger.Logger | None, pathlib.Path | None]": |
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.
Why do we choose to force main logger to log to a file? It should be fine as long as the directory exists, and not the specific main log file?
logger/modules/logger.py
Outdated
def debug(self, message: str, frame: "types.FrameType | None") -> None: | ||
""" | ||
Logs a debug level message. | ||
""" | ||
message = self.message_and_metadata(message, frame) | ||
self.logger.debug(message) | ||
|
||
def info(self, message: str, frame: "types.FrameType | None") -> None: | ||
""" | ||
Logs an info level message. | ||
""" | ||
message = self.message_and_metadata(message, frame) | ||
self.logger.info(message) | ||
|
||
def warning(self, message: str, frame: "types.FrameType | None") -> None: | ||
""" | ||
Logs a warning level message. | ||
""" | ||
message = self.message_and_metadata(message, frame) | ||
self.logger.warning(message) | ||
|
||
def error(self, message: str, frame: "types.FrameType | None") -> None: | ||
""" | ||
Logs an error level message. | ||
""" | ||
message = self.message_and_metadata(message, frame) | ||
self.logger.error(message) | ||
|
||
def critical(self, message: str, frame: "types.FrameType | None") -> None: | ||
""" | ||
Logs a critical level message. | ||
""" | ||
message = self.message_and_metadata(message, frame) | ||
self.logger.critical(message) |
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 propose that rather than asking the user to pass in a frame, we use inspect in the Logger itself, and we can use frame.f_back to find the caller's frame, which is the one we are interested in. Then we can just have frame be a boolean option that defaults to true, since it seems to be enabled by default on most stack traces and loggers.
logger/test_logger.py
Outdated
test_message = "test message" | ||
logger_instance_to_file_enabled.debug(test_message, None) | ||
logger_instance_to_file_enabled.info(test_message, None) | ||
logger_instance_to_file_enabled.warning(test_message, None) | ||
logger_instance_to_file_enabled.error(test_message, None) | ||
logger_instance_to_file_enabled.critical(test_message, None) |
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.
It would be nice if one had no frame and this one does have frame info
logger/test_logger.py
Outdated
""" | ||
test_message = "test message" | ||
|
||
logger_instance_to_file_disabled.debug(test_message, None) |
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.
Same for all of these, would be nice to log twice, one with frame and one without
requirements.txt
Outdated
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.
Also could you please remove line 17-18 (the pymavlink) since it's now moved to the submodule. Thanks!
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.
Reviewed
logger/modules/logger_setup_main.py
Outdated
assert main_logger is not None | ||
|
||
frame = inspect.currentframe() | ||
main_logger.info(f"{main_logger_name} logger initialized", frame) |
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.
frame should be true/false, since we changed that.
logger/modules/logger.py
Outdated
def debug(self, message: str, log_with_frame_info: bool) -> None: | ||
""" | ||
Logs a debug level message. | ||
""" | ||
if log_with_frame_info: | ||
logger_frame = inspect.currentframe() | ||
caller_frame = logger_frame.f_back | ||
message = self.message_and_metadata(message, caller_frame) | ||
self.logger.debug(message) | ||
|
||
def info(self, message: str, log_with_frame_info: bool) -> None: | ||
""" | ||
Logs an info level message. | ||
""" | ||
if log_with_frame_info: | ||
logger_frame = inspect.currentframe() | ||
caller_frame = logger_frame.f_back | ||
message = self.message_and_metadata(message, caller_frame) | ||
self.logger.info(message) | ||
|
||
def warning(self, message: str, log_with_frame_info: bool) -> None: | ||
""" | ||
Logs a warning level message. | ||
""" | ||
if log_with_frame_info: | ||
logger_frame = inspect.currentframe() | ||
caller_frame = logger_frame.f_back | ||
message = self.message_and_metadata(message, caller_frame) | ||
self.logger.warning(message) | ||
|
||
def error(self, message: str, log_with_frame_info: bool) -> None: | ||
""" | ||
Logs an error level message. | ||
""" | ||
if log_with_frame_info: | ||
logger_frame = inspect.currentframe() | ||
caller_frame = logger_frame.f_back | ||
message = self.message_and_metadata(message, caller_frame) | ||
self.logger.error(message) | ||
|
||
def critical(self, message: str, log_with_frame_info: bool) -> None: | ||
""" | ||
Logs a critical level message. | ||
""" | ||
if log_with_frame_info: | ||
logger_frame = inspect.currentframe() | ||
caller_frame = logger_frame.f_back | ||
message = self.message_and_metadata(message, caller_frame) | ||
self.logger.critical(message) |
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 it would be nicer to have log_with_frame_info
default to True? Up to you tho
logger/modules/logger_setup_main.py
Outdated
logging_path = pathlib.Path(log_directory_path, start_time) | ||
|
||
# Create logging directory | ||
pathlib.Path(log_directory_path).mkdir(exist_ok=True) |
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.
*reminder
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.
Approved!
Moved logger to common.
PR must be merged before the PR in computer-vision-python UWARG/computer-vision-python#194.