气流-如何从ECS运营商推送XCOM?

时间:2019-12-17 10:45:08

标签: airflow amazon-ecs apache-airflow-xcom

在气流控制中,我有一个ecs_operator任务,其后是python运算符任务。我想使用xcom将一些消息从ECS任务推送到python任务。我尝试了选项do_xcom_push=True,但没有结果。查找以下示例dag。

dag = DAG(
    dag_name, default_args=default_args, schedule_interval=None)
start = DummyOperator(task_id = 'start'
                   ,dag =dag)
end = DummyOperator(task_id = 'end'
                   ,dag =dag)
ecs_operator_args = {
    'launch_type': 'FARGATE',
    'task_definition': 'task-def:2',
    'cluster': 'cluster-name',
    'region_name': 'region',
    'network_configuration': {
        'awsvpcConfiguration':
            {}
    }
}
ecs_task = ECSOperator(
    task_id='x_com_test'
    ,**ecs_operator_args
    ,do_xcom_push=True
    ,params={'my_param': 'Parameter-1'}
    ,dag=dag)


def pull_function(**kwargs):
    ti = kwargs['ti']
    msg = ti.xcom_pull(task_ids='x_com_test',key='the_message')
    print("received message: '%s'" % msg)

pull_task = PythonOperator(
    task_id='pull_task',
    python_callable=pull_function,
    provide_context=True,
    dag=dag)

start >> ecs_task >> pull_task >> end

2 个答案:

答案 0 :(得分:0)

您需要为容器设置一个cloudwatch日志组。

ECSOperator需要扩展以支持推送到xcom:

from collections import deque
from airflow.utils import apply_defaults
from airflow.contrib.operators.ecs_operator import ECSOperator


class MyECSOperator(ECSOperator):
    @apply_defaults
    def __init__(self, xcom_push=False, **kwargs):
        super(CLECSOperator, self).__init__(**kwargs)
        self.xcom_push_flag = xcom_push

    def execute(self, context):
        super().execute(context)
        if self.xcom_push_flag:
            return self._last_log_event()

    def _last_log_event(self):
        if self.awslogs_group and self.awslogs_stream_prefix:
            task_id = self.arn.split("/")[-1]
            stream_name = "{}/{}".format(self.awslogs_stream_prefix, task_id)
            events = self.get_logs_hook().get_log_events(self.awslogs_group, stream_name)
            last_event = deque(events, maxlen=1).pop()
            return last_event["message"]


dag = DAG(
    dag_name, default_args=default_args, schedule_interval=None)
start = DummyOperator(task_id = 'start'
                   ,dag =dag)
end = DummyOperator(task_id = 'end'
                   ,dag =dag)
ecs_operator_args = {
    'launch_type': 'FARGATE',
    'task_definition': 'task-def:2',
    'cluster': 'cluster-name',
    'region_name': 'region',
    'awslogs_group': '/aws/ecs/myLogGroup',
    'awslogs_stream_prefix': 'myStreamPrefix',
    'network_configuration': {
        'awsvpcConfiguration':
            {}
    }
}
ecs_task = MyECSOperator(
    task_id='x_com_test'
    ,**ecs_operator_args
    ,xcom_push=True
    ,params={'my_param': 'Parameter-1'}
    ,dag=dag)


def pull_function(**kwargs):
    ti = kwargs['ti']
    msg = ti.xcom_pull(task_ids='x_com_test',key='return_value')
    print("received message: '%s'" % msg)

pull_task = PythonOperator(
    task_id='pull_task',
    python_callable=pull_function,
    provide_context=True,
    dag=dag)

start >> ecs_task >> pull_task >> end

ecs_task将在完成执行之前获取日志组中的最后一个事件,并将其推送到xcom。

答案 1 :(得分:0)

Apache-AWS 有一个 How to Upload File from Angular to ASP.NET Core Web API,它几​​乎实现了上面提到的@Бојан-Аџиевски,因此您无需编写自定义 ECSOperator。从版本 1.1.0

开始可用

您只需在调用 do_xcom_push=True 时提供 ECSOperator 并提供正确的 awslogs_groupawslogs_stream_prefix

确保您的 awslogs_stream_prefix 遵循以下格式:

prefix-name/container-name

因为这是 ECS 将日志定向到的。