# Buggy code
def _init_file(self, ti):
    """
    Create log directory and give it correct permissions.

    :param ti: task instance object
    :return: relative log path of the given task instance
    """
    # To handle log writing when tasks are impersonated, the log files need to
    # be writable by the user that runs the Airflow command and the user
    # that is impersonated. This is mainly to handle corner cases with the
    # SubDagOperator. When the SubDagOperator is run, all of the operators
    # run under the impersonated user and create appropriate log files
    # as the impersonated user. However, if the user manually runs tasks
    # of the SubDagOperator through the UI, then the log files are created
    # by the user that runs the Airflow command. For example, the Airflow
    # run command may be run by the `airflow_sudoable` user, but the Airflow
    # tasks may be run by the `airflow` user. If the log files are not
    # writable by both users, then it's possible that re-running a task
    # via the UI (or vice versa) results in a permission error as the task
    # tries to write to a log file created by the other user.
    relative_path = self._render_filename(ti, ti.try_number)
    full_path = os.path.join(self.local_base, relative_path)
    directory = os.path.dirname(full_path)
    # Create the log file and give it group writable permissions
    # TODO(aoen): Make log dirs and logs globally readable for now since the SubDag
    # operator is not compatible with impersonation (e.g. if a Celery executor is used
    # for a SubDag operator and the SubDag operator has a different owner than the
    # parent DAG)
    if not os.path.exists(directory):
        # Create the directory as globally writable using custom mkdirs
        # as os.makedirs doesn't set mode properly.
        mkdirs(directory, 0o777)

    if not os.path.exists(full_path):
        open(full_path, "a").close()
        # TODO: Investigate using 444 instead of 666.
        os.chmod(full_path, 0o666)

    return full_path


# Traceback (PermissionError)
Traceback (most recent call last):
File "/home/airflow/.local/bin/airflow", line 8, in <module>
sys.exit(main())
File "/home/airflow/.local/lib/python3.8/site-packages/airflow/__main__.py", line 40, in main
args.func(args)
File "/home/airflow/.local/lib/python3.8/site-packages/airflow/cli/cli_parser.py", line 50, in command
return func(*args, **kwargs)
File "/home/airflow/.local/lib/python3.8/site-packages/airflow/utils/cli.py", line 86, in wrapper
return f(*args, **kwargs)
File "/home/airflow/.local/lib/python3.8/site-packages/airflow/cli/commands/task_command.py", line 179, in task_run
ti.init_run_context(raw=args.raw)
File "/home/airflow/.local/lib/python3.8/site-packages/airflow/models/taskinstance.py", line 1922, in init_run_context
self._set_context(self)
File "/home/airflow/.local/lib/python3.8/site-packages/airflow/utils/log/logging_mixin.py", line 54, in _set_context
set_context(self.log, context)
File "/home/airflow/.local/lib/python3.8/site-packages/airflow/utils/log/logging_mixin.py", line 173, in set_context
handler.set_context(value)
File "/home/airflow/.local/lib/python3.8/site-packages/airflow/utils/log/file_task_handler.py", line 54, in set_context
local_loc = self._init_file(ti)
File "/home/airflow/.local/lib/python3.8/site-packages/airflow/utils/log/file_task_handler.py", line 256, in _init_file
os.chmod(full_path, 0o666)
PermissionError: [Errno 1] Operation not permitted: '/opt/airflow/logs/dagname/jobname/2020-11-27T20:57:00+00:00/1.log'

# Fixed code
def _init_file(self, ti):
    """
    Create log directory and give it correct permissions.

    :param ti: task instance object
    :return: relative log path of the given task instance
    """
    # To handle log writing when tasks are impersonated, the log files need to
    # be writable by the user that runs the Airflow command and the user
    # that is impersonated. This is mainly to handle corner cases with the
    # SubDagOperator. When the SubDagOperator is run, all of the operators
    # run under the impersonated user and create appropriate log files
    # as the impersonated user. However, if the user manually runs tasks
    # of the SubDagOperator through the UI, then the log files are created
    # by the user that runs the Airflow command. For example, the Airflow
    # run command may be run by the `airflow_sudoable` user, but the Airflow
    # tasks may be run by the `airflow` user. If the log files are not
    # writable by both users, then it's possible that re-running a task
    # via the UI (or vice versa) results in a permission error as the task
    # tries to write to a log file created by the other user.
    relative_path = self._render_filename(ti, ti.try_number)
    full_path = os.path.join(self.local_base, relative_path)
    directory = os.path.dirname(full_path)
    # Create the log file and give it group writable permissions
    # TODO(aoen): Make log dirs and logs globally readable for now since the SubDag
    # operator is not compatible with impersonation (e.g. if a Celery executor is used
    # for a SubDag operator and the SubDag operator has a different owner than the
    # parent DAG)
    if not os.path.exists(directory):
        # Create the directory as globally writable using custom mkdirs
        # as os.makedirs doesn't set mode properly.
        mkdirs(directory, 0o777)

    if not os.path.exists(full_path):
        open(full_path, "a").close()
        # TODO: Investigate using 444 instead of 666.
        try:
            os.chmod(full_path, 0o666)
        except OSError:
            logging.warning("OSError while change ownership of the log file")

    return full_path