Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion airflow/bin/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ def run(args, dag=None):
hostname = socket.getfqdn()
log.info("Running %s on host %s", ti, hostname)

with redirect_stdout(log, logging.INFO), redirect_stderr(log, logging.WARN):
with redirect_stdout(ti.log, logging.INFO), redirect_stderr(ti.log, logging.WARN):
if args.local:
run_job = jobs.LocalTaskJob(
task_instance=ti,
Expand Down
4 changes: 2 additions & 2 deletions airflow/config_templates/airflow_local_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@
},
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'class': 'airflow.utils.log.logging_mixin.RedirectStdHandler',
'formatter': 'airflow.task',
'stream': 'ext://sys.stdout'
'stream': 'sys.stdout'
},
'file.task': {
'class': 'airflow.utils.log.file_task_handler.FileTaskHandler',
Expand Down
29 changes: 29 additions & 0 deletions airflow/utils/log/logging_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@
import sys
import warnings

import six

from builtins import object
from contextlib import contextmanager
from logging import Handler, StreamHandler


class LoggingMixin(object):
Expand Down Expand Up @@ -103,6 +106,32 @@ def isatty(self):
return False


class RedirectStdHandler(StreamHandler):
"""
This class is like a StreamHandler using sys.stderr/stdout, but always uses
whatever sys.stderr/stderr is currently set to rather than the value of
sys.stderr/stdout at handler construction time.
"""
def __init__(self, stream):
if not isinstance(stream, six.string_types):
raise Exception("Cannot use file like objects. Use 'stdout' or 'stderr'"
" as a str and without 'ext://'.")

self._use_stderr = True
if 'stdout' in stream:
self._use_stderr = False

# StreamHandler tries to set self.stream
Handler.__init__(self)

@property
def stream(self):
if self._use_stderr:
return sys.stderr

return sys.stdout


@contextmanager
def redirect_stdout(logger, level):
writer = StreamLogWriter(logger, level)
Expand Down