每当我的DAG中的任务无法运行或重试运行时,我都会尝试让Airflow通过AWS SES向我发送电子邮件。我使用的是AWS SES凭证,而不是我的一般AWS凭证。
我目前 airflow.cfg
[email]
email_backend = airflow.utils.email.send_email_smtp
[smtp]
# If you want airflow to send emails on retries, failure, and you want to use
# the airflow.utils.email.send_email_smtp function, you have to configure an
# smtp server here
smtp_host = emailsmtpserver.region.amazonaws.com
smtp_starttls = True
smtp_ssl = False
# Uncomment and set the user/pass settings if you want to use SMTP AUTH
smtp_user = REMOVEDAWSACCESSKEY
smtp_password = REMOVEDAWSSECRETACCESSKEY
smtp_port = 25
smtp_mail_from = myemail@myjob.com
我的DAG中的当前任务旨在故意失败并重试:
testfaildag_library_install_jar_jdbc = PythonOperator(
task_id='library_install_jar',
retries=3,
retry_delay=timedelta(seconds=15),
python_callable=add_library_to_cluster,
params={'_task_id': 'cluster_create', '_cluster_name': CLUSTER_NAME, '_library_path':s3000://fakepath.jar},
dag=dag,
email_on_failure=True,
email_on_retry=True,
email=’myname@myjob.com’,
provide_context=True
)
除了没有发送电子邮件外,一切都按设计工作,重试设定的次数并最终失败。我也检查了上面提到的任务中的日志,并且从未提及过smtp。
我看过类似的问题here,但唯一的解决办法对我不起作用。此外,Airflow的文档(例如示例here)似乎也不适用于我。
SES是否可以使用Airflow的email_on_failure和email_on_retry功能?
我目前正在考虑的是使用on_failure_callback
函数调用AWS here提供的python脚本来发送失败的电子邮件,但这不是此时的首选路径。
谢谢你,感谢任何帮助。
答案 0 :(得分:5)
- 通过工作SES更新6/8
这是我写的关于我们如何完成所有工作的文章。这个答案的底部有一个小摘要。
几点重点:
email_on_failure
和email_on_retry
功能提供服务。在Dag运行期间,您可以journalctl –u airflow-worker –f
进行监控。在生产服务器上,在使用新的smtp设置更改airflow.cfg
后,您无需重新启动气流工作人员 - 应自动选择它。无需担心搞乱当前正在运行的Dags。以下是有关如何使用sendmail的技术说明:
由于我们在localhost上从ses更改为sendmail,因此我们必须更改airflow.cfg
中的smtp设置。
新配置为:
[email]
email_backend = airflow.utils.email.send_email_smtp
[smtp]
# If you want airflow to send emails on retries, failure, and you want to use
# the airflow.utils.email.send_email_smtp function, you have to configure an
# smtp server here
smtp_host = localhost
smtp_starttls = False
smtp_ssl = False
# Uncomment and set the user/pass settings if you want to use SMTP AUTH
#smtp_user = not used
#smtp_password = not used
smtp_port = 25
smtp_mail_from = myjob@mywork.com
这适用于生产和本地气流实例。
如果他们的配置与我的配置不同,可能会收到一些常见错误:
socket.error: [Errno 111] Connection refused
- 您必须将smtp_host
中的airflow.cfg
行更改为localhost
smtplib.SMTPException: STARTTLS extension not supported by server.
- 您必须将smtp_starttls
中的airflow.cfg
更改为False
在我的本地测试中,我试图简单地强制气流显示尝试发送电子邮件时发生的事情的日志 - 我创建了一个虚假的dag,如下所示:
# Airflow imports
from airflow import DAG
from airflow.operators.python_operator import PythonOperator
from airflow.operators.bash_operator import BashOperator
from airflow.operators.dummy_operator import DummyOperator
# General imports
from datetime import datetime,timedelta
def throwerror():
raise ValueError("Failure")
SPARK_V_2_2_1 = '3.5.x-scala2.11'
args = {
'owner': ‘me’,
'email': ['me@myjob'],
'depends_on_past': False,
'start_date': datetime(2018, 5,24),
'end_date':datetime(2018,6,28)
}
dag = DAG(
dag_id='testemaildag',
default_args=args,
catchup=False,
schedule_interval="* 18 * * *"
)
t1 = DummyOperator(
task_id='extract_data',
dag=dag
)
t2 = PythonOperator(
task_id='fail_task',
dag=dag,
python_callable=throwerror
)
t2.set_upstream(t1)
如果您执行journalctl -u airflow-worker -f
,您可以看到该工作人员说它已向您的DAG中的电子邮件发送了一封警告电子邮件,但我们仍然没有收到该电子邮件。然后,我们决定通过cat /var/log/maillog
查看sendmail的邮件日志。我们看到了这样的日志:
Jun 5 14:10:25 production-server-ip-range postfix/smtpd[port]: connect from localhost[127.0.0.1]
Jun 5 14:10:25 production-server-ip-range postfix/smtpd[port]: ID: client=localhost[127.0.0.1]
Jun 5 14:10:25 production-server-ip-range postfix/cleanup[port]: ID: message-id=<randomMessageID@production-server-ip-range-ec2-instance>
Jun 5 14:10:25 production-server-ip-range postfix/smtpd[port]: disconnect from localhost[127.0.0.1]
Jun 5 14:10:25 production-server-ip-range postfix/qmgr[port]: MESSAGEID: from=<myjob@mycompany.com>, size=1297, nrcpt=1 (queue active)
Jun 5 14:10:55 production-server-ip-range postfix/smtp[port]: connect to aspmx.l.google.com[smtp-ip-range]:25: Connection timed out
Jun 5 14:11:25 production-server-ip-range postfix/smtp[port]: connect to alt1.aspmx.l.google.com[smtp-ip-range]:25: Connection timed out
所以这可能是最大的“哦对决”时刻。在这里,我们可以看到我们的smtp服务实际发生了什么。我们使用telnet确认我们无法连接到gmail的目标IP范围。
我们确定该电子邮件正在尝试发送,但sendmail服务无法成功连接到ip范围。
我们决定允许AWS中端口25上的所有出站流量(因为我们的气流生产环境是ec2实例),现在它可以成功运行。我们现在能够接收有关失败和重试的电子邮件(提示:email_on_failure
和email_on_retry
在您的DAG API Reference中默认为True
- 您无需将其放入如果你不愿意,你的args,但在它中明确地陈述正确或错误仍然是好的做法。)
SES现在有效。这是气流配置:
[email]
email_backend = airflow.utils.email.send_email_smtp
[smtp]
# If you want airflow to send emails on retries, failure, and you want to use
# the airflow.utils.email.send_email_smtp function, you have to configure an
# smtp server here
smtp_host = emailsmtpserver.region.amazonaws.com
smtp_starttls = True
smtp_ssl = False
# Uncomment and set the user/pass settings if you want to use SMTP AUTH
smtp_user = REMOVEDAWSACCESSKEY
smtp_password = REMOVEDAWSSECRETACCESSKEY
smtp_port = 587
smtp_mail_from = myemail@myjob.com (Verified SES email)
谢谢!
答案 1 :(得分:0)
这里有类似的情况,我尝试遵循相同的调试过程,但没有日志输出。另外,我的airflow ec2 实例的出站规则对所有端口和ips 都是开放的,所以应该是其他一些原因。
我注意到,当您从 SES 创建 SMTP 凭证时,它还会创建一个 IAM 用户。我不确定您的案例中的气流如何运行(ec2 实例上的裸机或包装在容器中),以及如何设置用户访问权限。