[AIRFLOW-1385] Make Airflow task logging configurable#2464
Conversation
|
@allisonwang, thanks for your PR! By analyzing the history of the files in this pull request, we identified @mistercrunch, @aoen and @bolkedebruin to be potential reviewers. |
439735f to
24de2a8
Compare
Codecov Report
@@ Coverage Diff @@
## master #2464 +/- ##
==========================================
+ Coverage 69.95% 70.07% +0.12%
==========================================
Files 146 150 +4
Lines 11448 11538 +90
==========================================
+ Hits 8008 8085 +77
- Misses 3440 3453 +13
Continue to review full report at Codecov.
|
6679101 to
6d07af1
Compare
There was a problem hiding this comment.
does task_instance have this number implicitly?
There was a problem hiding this comment.
Yes but we need to fetch logs given different try_number. task_instance record only has the number of latest attempt.
There was a problem hiding this comment.
From a design point of view this is unclean. task_instance is an instantiation of a task in time. As such it is bound to a try_number, which is now also provides.
I suggest to change the signature of the method to def read(self, task_instance, try_number=None) and the return the latest log if try_number isn't specified or maybe even better all logs. This also makes it easier if we would like to integrate this with the Rest API.
Or, use a different signature all together def read(self, task, execution_date, try_number).
On a side note: the try_number thing still feels a bit off. Properly keeping track of start_dates (i.e. recording each start_date somewhere) seems more logical. try_number in the end is the count of start_dates.
There was a problem hiding this comment.
task_instance signature alone is definitely not enough, as we need to fetch logs from different previous try_number. Using try_number=None and return all logs separated by try_number sounds good.
Regarding the side note, try_number is definitely not ideal, as we need a better way to distinguish each task instance attempt. Right now try_number is used as a supplement to its primary key dag_id, task_id and execution_date to make each task attempt unique. In the future, we might need to change the db schema and use other fields as task_instance primary key.
|
@bolkedebruin Is there major thing in PR that needs to be changed? If not, I will iterate more quickly on this PR and hopefully modify the ElasticSearch PR to use this new logging framework. I will add GCS and make a list of JIRA tasks for subsequent improvements. |
|
No not directly. Please create the Jira to track the the outstanding (particularly GCS as people rely on it). Then squash the commits one into so we can merge it and iterate from there. As mentioned in the other PR I'm getting more and more convinced that I'm really happy with this PR as it lays out the right foundation. It isn't perfect, but a lot better than what we had. So good job ;-), keep it up. |
6d07af1 to
0331f0f
Compare
|
@bolkedebruin PTAL. GCS Task handler is added and read method signature is slightly changed. I've created a JIRA AIRFLOW-1454 and several sub-tasks for improving airflow logging. Please feel free to modify and/or add more tasks. |
There was a problem hiding this comment.
Let's use hasattr instead
There was a problem hiding this comment.
https://hynek.me/articles/hasattr This article points out using hasattr in Python 2 can be harmful since it shadows errors in properties. In this case it's probably fine for now to use hasattr but it doesn't seem to be a good practice to use in Python 2.
There was a problem hiding this comment.
Nice catch. Feel free to leave as is
There was a problem hiding this comment.
Why have the catchall? I think if there's an exception we should just let it happen.
"Fail loudly"
There was a problem hiding this comment.
Hmm it should still work if users don't have their own logging config right? Will change the exception to be more specific.
There was a problem hiding this comment.
We should at least say something? Isn't there a default logging config. My worry is that when a config doesn't import correctly it will silently use the default, which is bad.
There was a problem hiding this comment.
better to say is not None
There was a problem hiding this comment.
maybe log something about the exception?
There was a problem hiding this comment.
Thos are all direct copy paste from original code but I will add exception message as it can be really useful.
There was a problem hiding this comment.
also print exception here
There was a problem hiding this comment.
maybe log something?, explain why pass
There was a problem hiding this comment.
This is part of the refactor from the original code. Some of the logic might need to be changed, such as mkdir. I feel it's better to change in a separate PR, but I will definitely make a note here.
There was a problem hiding this comment.
is GCS misplaced text here?
There was a problem hiding this comment.
Multiline comment instead?
There was a problem hiding this comment.
Also part of refactored code. This part, as well as this comment, should be changed in the future.
There was a problem hiding this comment.
either that or make that method exist no matter what and let loggers decide whether to use it or not
There was a problem hiding this comment.
Same as above comment for hasattr. Standard Python handlers won't have set_context so the method can't exist for all methods. It's worth thinking what's the best way to set logger context without breaking the abstraction for python log handlers.
6e60cf7 to
905a28c
Compare
There was a problem hiding this comment.
Why no time pull this from the logging config, can be global (in the dict) but seems to be tight to a Handler
There was a problem hiding this comment.
Oh this specifies the filename of the user defined logging configuration if they do not want to use the default default_airflow_logging.py. It's like specifying the path for this config file.
There was a problem hiding this comment.
Let's pull this from the config dict, you could even template it
There was a problem hiding this comment.
I know this is old code, but why do we check if it exists on the local system while we can just compare host names? I.e. If the local host name is not equal to task instance host name we should pull from remote
There was a problem hiding this comment.
My understanding is that checking hostname is not enough. There is only one task instance record with dag_id, task_id and execution date in DB. Once task re-attempts, the hostname information might be updated. So even if the task instance currently has hostname A, it could still have older logs in machine B or C that got wiped out when DB updates. So this local machine might have older logs.
Direct updating on top of existing DB records in generally makes things much harder to keep track. I would prefer having another table to keep track of task_instance changes.
There was a problem hiding this comment.
For future, I think task_instance and try_number should be enough to pull from remote.
There was a problem hiding this comment.
what exactly does this worker_log_server_port do? If we remove it here would different workers be able to access each other's local disk to fetch logs?
There was a problem hiding this comment.
It is the port the logs will be made available on with a simple web server
There was a problem hiding this comment.
Let's do this with a template for this handler
There was a problem hiding this comment.
I.e. No hardcore .log
46a54c7 to
d7c7581
Compare
|
@bolkedebruin I added some unit tests for dictConfig and file task handler. It's hard to test S3 and/or GCS for correct behaviors. Is there a mock lib for testing those? (maybe I can use moto) |
|
@ronfung can you help out with the GCS part? Or ask Chris? @allisonwang I think you can use boto/boto3 (check which is the current one, the S3 operators use it) for S3. I don't have too much cloud exposure myself as I can't use it. |
|
I'm fine merging the GCS changes into master. We can fix forward when 1.9.0 test/stable is cut. |
|
I took a brief look and everything seems reasonable. @jgao54 do you want to try this patch out and verify that GCS works? |
|
@criccomini we are looking for how to test the logic on Travis. Ie the question is how can we test it without having a GCS account? Can we mock it? |
|
Got it. I looked a long time ago, but couldn't find any good GCS mock solutions. In the absence of that, you're left just mocking the APIs, which really doesn't test much at all. I did some googling, and I still haven't found a Python mock that will let you simulate GCS locally, so traditional mocks would be all we have left. Again, that really doesn't test that match, but it's better than nothing, I suppose. |
887ef78 to
4d7bc56
Compare
|
@bolkedebruin I tried testing using |
2296c1b to
3193e38
Compare
bolkedebruin
left a comment
There was a problem hiding this comment.
Overall looks good and just some minor nits. Can you
:
0. Address the nits and comments
- Make the tests pass so we can have a look at the coverage
- Add documentation on how to configure logging
- Squash your commits
I presume you would like to have
There was a problem hiding this comment.
Why is this not a child of airflow.task? It would not require to repeat the same config
There was a problem hiding this comment.
@bolkedebruin Task runner in current structure is under module Airflow not airflow.task. It uses a LoggingMixin that gets the corresponding logger with the module name. We can make another folder called under airflow/task and put task runner inside if needed. But we can always reorganize the folder structure later.
There was a problem hiding this comment.
Ok. Leave it for now then
There was a problem hiding this comment.
Can you mirror the the logging setup? Ie. The test file should mirror the file you are Testing against.
There was a problem hiding this comment.
Oops need to rebase and fix the test conflicts.
There was a problem hiding this comment.
Can you make this 444 instead? There is no need to have these files executable. (Yes I know it was there before, it is still a security concern)
There was a problem hiding this comment.
This is definitely a concern but I prefer creating another JIRA and make the change in another PR. There are some reasons why 666 is needed (it breaks the system otherwise). Dan can probably explain more. I will add a TODO here.
There was a problem hiding this comment.
Allison's last day will be the 11th but there are some other bits of administrivia that she needs to spend some time on. I'm trying to keep the scope down of this task because I really want to see it ship (there were a couple of other logging refactor attempts that fizzled out). To that effort I think we shouldn't try to keep most of the behavior/functionality the same as it might cause unexpected bugs that need to be fixed (e.g. with subdags).
There was a problem hiding this comment.
@aoen ok fully understood and I agree. Besides I think it won't be required to do this anyway, if we let tasks log to stdout and let the log file be handled by the LocalTaskJob as I mentioned earlier.
390d532 to
a83bfa7
Compare
|
I think this is good to merge. If you still have a bit of time @allisonwang please increase coverage of the FileTaskHandler (the read method seems untested ). @allisonwang really good job on getting this through. You were challenged on the first approach, but took it on nevertheless. I think it got a lot better because of it and it has become a foundation that we can build on. Let me know if you want to spent some time in Amsterdam ;-). +1 ( I can't test the patch myself as I am not in the country, just baby sitting this one through. So I am assuming you guys tested it) |
509d792 to
24dc09f
Compare
|
@bolkedebruin Thanks for reviewing this PR! I've tested the file handler and s3 handler in our staging environment (but not GCS handler). Feel free to pin me if there are issues and I am happy to fix them in the future :) I will add documentations soon in another PR. |
8c8199d to
c15db25
Compare
|
@aoen can you please merge? I cannot from my current location |
|
I would be more than happy to! |
b06551b to
de7dfbe
Compare
de7dfbe to
f175c4a
Compare

Dear Airflow maintainers,
Please accept this PR. I understand that it will not be reviewed until I have checked off all the steps below!
JIRA
Description
This PR adds configurable task logging to Airflow. Please refer to #2422 for previous discussions. This is the first step of making entire Airflow logging configurable (AIRFLOW-1454).
Tests
FileTaskHandler is tested locally and in staging. S3TaskHandler is tested in staging. GCSTaskHandler is not tested.
Commits