Airflow 为什么气流DAG结束日期和持续时间不一致地记录在延迟成功回调警报中?

Airflow 为什么气流DAG结束日期和持续时间不一致地记录在延迟成功回调警报中?,airflow,slack-api,Airflow,Slack Api,我正在尝试创建一个松弛警报,当气流DAG中的任务成功运行时,该警报会将一些基本信息发布到松弛通道中。我的代码如下: import datetime from airflow import models from airflow.contrib.operators.bigquery_operator import BigQueryOperator from airflow.hooks.base_hook import BaseHook from airflow.contrib.operators

我正在尝试创建一个松弛警报,当气流DAG中的任务成功运行时,该警报会将一些基本信息发布到松弛通道中。我的代码如下:

import datetime

from airflow import models
from airflow.contrib.operators.bigquery_operator import BigQueryOperator
from airflow.hooks.base_hook import BaseHook
from airflow.contrib.operators.slack_webhook_operator import SlackWebhookOperator

SLACK_CONN_ID = "slack_test"


def task_success_slack_alert(context):
    """
    Callback task that can be used in DAG to alert of successful task completion
    Args:
        context (dict): Context variable passed in from Airflow
    Returns:
        None: Calls the SlackWebhookOperator execute method internally
    """

    slack_webhook_token = BaseHook.get_connection(SLACK_CONN_ID).password
    slack_msg = """
            :large_blue_circle: Task completed successfully
            *Task*: {task}  
            *Dag*: {dag} 
            *Execution Time*: {exec_date}  
            *Start Time*: {start}
            *End Time*: {end}
            *Duration*: {duration} seconds
            *Try* {try_number} *of max retries* {max_tries}
            *Log Url*: {log_url} 
            """.format(
        task=context.get("task_instance").task_id,
        dag=context.get("task_instance").dag_id,
        ti=context.get("task_instance"),
        exec_date=context.get("execution_date"),
        log_url=context.get("task_instance").log_url,
        start=context.get("task_instance").start_date,
        end=context.get("task_instance").end_date,
        duration=context.get("task_instance").duration,
        try_number=context.get("task_instance")._try_number,
        max_tries=context.get("task_instance").max_tries + 1
        )

    success_alert = SlackWebhookOperator(
        task_id="slack_test",
        http_conn_id=SLACK_CONN_ID,
        webhook_token=slack_webhook_token,
        message=slack_msg,
        username="airflow",
        )

    return success_alert.execute(context=context)

default_dag_args = {'owner': 'TEST',
                    'start_date': datetime.datetime(2021, 3, 29),
                    'retries': 1,
                    'use_legacy_sql': False,
                    'on_success_callback': task_success_slack_alert
                    }

with models.DAG('TESTING',
                schedule_interval='0 9 * * *',
                default_args=default_dag_args) as dag:
然后我有一系列BigQueryOperator任务,将数据写入大查询表。每个任务运行后都会输出slack消息,但有时“结束时间”和“持续时间”为“无”,但当我检查DAG的日志时,我可以看到正确记录了结束时间。有时持续时间/结束时间起作用,有时不起作用,我看不出这是为什么的逻辑模式。我还注意到,有时它会为同一任务发布两次松弛警报,一次持续时间/结束时间为“无”,然后再次填充。有人知道为什么会这样吗


有两点可以调用on\u success\u回调

  • 当任务在执行后成功时。()
  • 当元数据数据库中的任务状态不反映进程当前正在执行的操作时()
  • 在某些情况下,由于任务实例执行和本地任务作业之间的竞争条件,回调会快速连续执行两次。这描述了一个与您类似的场景

    如果不知道延迟消息发送的时间,我不能确定这是同一个问题。如果必须猜测的话,缺少结束时间和持续时间的slack消息来自本地任务作业,而填充元数据的slack消息来自任务实例

    如果您在回调中添加一些调用方检查代码,您就可以知道它来自哪里。请参考上的这篇文章


    您提到,
    local\u task\u job.py
    的回调具有完整的元数据输出集。从代码的角度来看,这是有意义的。在
    on\u success\u之前,在
    taskinstance.py
    中调用回调
    。另一方面,当本地任务作业心跳并看到状态为SUCCESS时,它将在\u SUCCESS\u回调上运行
    ,此时已设置了
    结束日期


    这提醒了我,在过去,我也遇到过这个问题,并使用调用成功回调的当前时间作为结束时间。

    您运行的是哪个版本的Airflow?我还要检查工作日志以寻找线索,因为当任务成功时,工作人员将执行on_success_回调。@AlanMa我使用的是Airflow 1.10.10+版本谢谢,我添加了一些调用方检查代码,看起来on_success_回调名为:1。函数_run_raw_task生成的taskinstance.py:该函数每次运行,但不包括结束时间或持续时间2。函数heartbeat_callback生成的local_task_job.py:这只会有时运行,但当它运行时,它会包含所有必需的信息。您知道为什么会这样吗?发布一个更新!我认为所有的交互都是预期的,我还包括了一个变通方法。