Add target_path flag option for edr files and logs#747
Conversation
ELE-407 edr should have a target folder for all outputs
"It seems quite messy for to have the 3 files created for the report in the main project folder e.g. In most other packages where documentation has been built, all the artifacts created from the build have been added to a separate sub-folder (e.g. docs or build or dist or something along those lines). What I would like to be able to do is define within my project folder where the three edr files are built, so that I can ensure that is not included in source control, and to ensure that folder is consistent across all developers. Slack thread: |
|
👋 @noaKurman |
cfc280b to
f0467d8
Compare
|
Looks good, added one small comment |
eb701e7 to
dbac505
Compare
@noaKurman |
@Maayan-s @RoiTabach |
| ``` | ||
|
|
||
| - **Configuration target directory path** | ||
| The path where all output files will be saved, default will create "edr_files" directory in your path |
There was a problem hiding this comment.
@noaKurman
Can they change the default?
If not I would change to:
The path where edr should create an edr_files directory where all output files will be saved.
There was a problem hiding this comment.
Not completely sure what you meant:
You can either run --target-path ./noa-target and it would create noa-target in the current directory and save all files there, or you can ignore the flag and it would create edr_files in your current directory and save all files there, so should I change it to the phrase you suggested?
Also should I mention it's an absolute path in the doc?
@Maayan-s
There was a problem hiding this comment.
Ok I get it now! @noaKurman
So I would write like this:
The absolute path where all output files such as logs and reports will be saved. If not configured, the default is ./edr_files.
dbac505 to
93530e2
Compare
RoiTabach
left a comment
There was a problem hiding this comment.
Looks good. Found 2 small typos, amazingly both don't have bad side effects but still best to remove them. Also wondering if we should rename Customer->Custom .
Afterwards - Yalla merge (Also write something in slack #tech so the team knows since it's a behavioural change)
| config = self._load_configuration() | ||
|
|
||
| self.target_dir = self._first_not_none( | ||
| self.target_dir = self.target_dir = self._first_not_none( |
There was a problem hiding this comment.
Typo without side effects but still - let's fix:
| self.target_dir = self.target_dir = self._first_not_none( | |
| self.target_dir = self._first_not_none( |
| except Exception: | ||
| pass | ||
| finally: | ||
| os.makedirs(os.path.abspath(os.path.abspath(file_path)), exist_ok=True) |
There was a problem hiding this comment.
we don't need to double abspath , right?
| os.makedirs(os.path.abspath(os.path.abspath(file_path)), exist_ok=True) | |
| os.makedirs(os.path.abspath(file_path), exist_ok=True) |
| LOG_FILE = os.getcwd() + "/edr_files/edr.log" | ||
|
|
||
|
|
||
| class CustomerFileHandler(logging.FileHandler): |
There was a problem hiding this comment.
Is this customer and not custom intentionaly? I don't know English well enough to be sure
9c874fc to
c7ac650
Compare
|
|
||
| DEFAULT_CONFIG_DIR = str(Path.home() / ".edr") | ||
|
|
||
| DEFAULT_FILES_PATH = os.getcwd() + "/edr_files" |
There was a problem hiding this comment.
Maybe edr_outputs would be a better name?
Not sure
There was a problem hiding this comment.
Or asked for "edr_target" since it's compliant with dbt target dir
| "-tp", | ||
| type=str, | ||
| default=Config.DEFAULT_FILES_PATH, | ||
| help="Absolut target path for saving edr files such as logs and reports", |
There was a problem hiding this comment.
| help="Absolut target path for saving edr files such as logs and reports", | |
| help="Absolute target path for saving edr files such as logs and reports", |
| target_path_flag = "--target-path" | ||
| ctx = click.get_current_context() | ||
| ctx_args = ctx.args | ||
| if target_path_flag in ctx_args: |
There was a problem hiding this comment.
Why do we need to check by both the flag and the param?
There was a problem hiding this comment.
Because in the context of the cli/cli.py it's an arg, but in the context of some other files it's in the params. I guess its based on if it's before or after the get_cli_properties function @haritamar
| file_path = os.getcwd() + "/edr_files" | ||
| try: | ||
| target_path_param = "target_path" | ||
| target_path_flag = "--target-path" |
There was a problem hiding this comment.
What if the user passes it as -tp rather than --target-path
There was a problem hiding this comment.
That's a good point
I think I'll remove the -tp, it felt redundant from the start and also kind of confusing with the -t option
Is that ok? @haritamar
| LOG_FILE = os.getcwd() + "/edr_files/edr.log" | ||
|
|
||
|
|
||
| class CustomerFileHandler(logging.FileHandler): |
There was a problem hiding this comment.
We normally use the term User rather than Customer in OSS, so let's do that here as well :)
There was a problem hiding this comment.
Should have been Custom 😅
|
|
||
| def get_file_handler(): | ||
| file_handler = logging.FileHandler(LOG_FILE) | ||
| file_handler = CustomFileHandler(LOG_FILE, delay=True) |
There was a problem hiding this comment.
I think we should add the file handler dynamically with the correct log file output, initializing it with LOG_FILE and then changing it in emit feels a bit hacky...
I think it's better that we'll add a line of the format:
logger.addHandler(get_file_handler(log_path))
to elementary/monitor/cli.py (where log_path is constructed from the target path parameter.
There was a problem hiding this comment.
Writing here too -
Basically we're initializing a different logger in every file we have - (Which is a best practice in python),
So we need to somehow from every file to set the file handler to be ontarget_path - at that point I thought about getting the context in the log file itself, but then realized we're initializing it in the imports of the cli.py - which is before they have the context.
Resolution after huddle with Itamar I'll remove the custom handler and use the root logger (remove the "propagate = False") and set it's handler after the context is already set (this can happen even after the rest of the loggers are already initialized and they would be updated)
| full_refresh_dbt_package = params.get("full_refresh_dbt_package") | ||
|
|
||
| return { | ||
| "target_path": target_path, |
There was a problem hiding this comment.
Is this necessary?
What does it affect?
There was a problem hiding this comment.
Are you asking if we need it in the return or if we need the "target_path": target_path instead of just returning target_path itself?
For the first question - I'm pretty sure that's how we set the params (instead of it being in the args)
| return logger | ||
|
|
||
|
|
||
| def set_root_logger_file_handler(logger_name): |
There was a problem hiding this comment.
I think you should add both handlers only to the root logger, otherwise you'll get duplicate console outputs (outcome of removing propagate=False).
So maybe we can have set_root_logger_handlers that handles both?
There was a problem hiding this comment.
I actually don't see it log twice to the console so it's interesting
But anyway I'll move the console handler to the root as well, I agree it's more sorted that way
| self.format_epilog(ctx, formatter) | ||
|
|
||
| def invoke(self, ctx: click.Context) -> Any: | ||
| set_root_logger_file_handler("elementary") |
There was a problem hiding this comment.
I think it may be good that set_root_logger_file_handler will explicitly get the target path rather than relying on the click context.
WDYT about moving the call to config.py below and then doing set_root_logger_file_handler("elementary", target_path)?
I think it makes sense to do it right after you're creating the directory there.
There was a problem hiding this comment.
Hmm I see at that point in the code the config still points to the default edr_files path, maybe you can show me why
but I can also get it from the click context in the cli.py instead of the log (unless what you dislike here is the context itself and not the location of it)
| return console_handler | ||
|
|
||
|
|
||
| def get_log_path(): |
There was a problem hiding this comment.
See my note above regarding getting the target_path as a parameter, in that case I think this function can simply be joining it with "edr.log" :)
| file_path = ctx_args[ctx_args.index(target_path_flag) + 1] | ||
| finally: | ||
| os.makedirs(os.path.abspath(file_path), exist_ok=True) | ||
| return file_path + "/edr.log" |
There was a problem hiding this comment.
it's a good practice in python usually to use os.path.join(file_path, "edr.log") rather than adding strings
(handles well edge cases, like if the path ends or doesn't end with "/")
There was a problem hiding this comment.
Ha good to know, I saw both in the code so just used one of them 👍
| with: | ||
| name: edr.log | ||
| path: edr.log | ||
| path: edr_files/edr.log |
There was a problem hiding this comment.
Should this be changed to edr_target? (also for other cases below)
e10b1ee to
75bc7e4
Compare
No description provided.