web-dev-qa-db-ja.com

気流のログ用にs3を設定する

Docker-composeを使用して、スケーラブルなエアフロークラスターをセットアップしています。私はこのDockerfileに基づいてアプローチを行いました https://hub.docker.com/r/puckel/docker-airflow/

私の問題は、s3からの書き込み/読み取り用にログを設定することです。 DAGが完了すると、次のようなエラーが表示されます

*** Log file isn't local.
*** Fetching here: http://ea43d4d49f35:8793/log/xxxxxxx/2017-06-26T11:00:00
*** Failed to fetch log file from worker.

*** Reading remote logs...
Could not read logs from s3://buckets/xxxxxxx/airflow/logs/xxxxxxx/2017-06-
26T11:00:00

このようにairflow.cfgファイルに新しいセクションを設定しました

[MyS3Conn]
aws_access_key_id = xxxxxxx
aws_secret_access_key = xxxxxxx
aws_default_region = xxxxxxx

そして、airflow.cfgのリモートログセクションでs3パスを指定しました

remote_base_log_folder = s3://buckets/xxxx/airflow/logs
remote_log_conn_id = MyS3Conn

これを適切に設定しましたが、バグがありますか?ここに私が欠けている成功のレシピがありますか?

-更新

URI形式とJSON形式でエクスポートしようとしましたが、どちらも機能していないようです。次に、aws_access_key_idとaws_secret_access_keyをエクスポートすると、エアフローがそれを拾い始めました。今、私は労働者のログに彼のエラーを取得します

6/30/2017 6:05:59 PMINFO:root:Using connection to: s3
6/30/2017 6:06:00 PMERROR:root:Could not read logs from s3://buckets/xxxxxx/airflow/logs/xxxxx/2017-06-30T23:45:00
6/30/2017 6:06:00 PMERROR:root:Could not write logs to s3://buckets/xxxxxx/airflow/logs/xxxxx/2017-06-30T23:45:00
6/30/2017 6:06:00 PMLogging into: /usr/local/airflow/logs/xxxxx/2017-06-30T23:45:00

-更新

私もこのリンクを見つけました https://www.mail-archive.com/[email protected]/msg00462.html

次に、(ウェブサーバーやスケジューラとは別に)ワーカーマシンの1つにシェルし、Pythonでこのコードを実行しました

import airflow
s3 = airflow.hooks.S3Hook('s3_conn')
s3.load_string('test', airflow.conf.get('core', 'remote_base_log_folder'))

このエラーが表示されます。

boto.exception.S3ResponseError: S3ResponseError: 403 Forbidden

接続セクション https://airflow.incubator.Apache.org/concepts.html およびこの質問に対する他の回答で説明されているように、いくつかの異なるタイプのAIRFLOW_CONN_ envをエクスポートしてみました。

s3://<AWS_ACCESS_KEY_ID>:<AWS_SECRET_ACCESS_KEY>@S3

{"aws_account_id":"<xxxxx>","role_arn":"arn:aws:iam::<xxxx>:role/<xxxxx>"}

{"aws_access_key_id":"<xxxxx>","aws_secret_access_key":"<xxxxx>"}

AWS_ACCESS_KEY_IDとAWS_SECRET_ACCESS_KEYもエクスポートしましたが、成功しませんでした。

これらの資格情報はデータベースに格納されているため、UIに追加すると、ワーカーによって取得されますが、何らかの理由でログの書き込み/読み取りができません。

32
JackStat

エアフローUIを使用してs3接続をセットアップする必要があります。このためには、エアフローUIの[管理]-> [接続]タブに移動して、S3接続の新しい行を作成する必要があります。

構成例は次のとおりです。

接続ID:my_conn_S3

接続タイプ:S3

追加:{"aws_access_key_id": "your_aws_key_id"、 "aws_secret_access_key": "your_aws_secret_key"}

19
Him

UPDATE Airflow 1.10はロギングを行います はるかに簡単です

S3ロギングの場合、 上記の回答 に従って接続フックを設定します

次に、airflow.cfgに次を追加します

    [core]
    # Airflow can store logs remotely in AWS S3. Users must supply a remote
    # location URL (starting with either 's3://...') and an Airflow connection
    # id that provides access to the storage location.
    remote_base_log_folder = s3://my-bucket/path/to/logs
    remote_log_conn_id = MyS3Conn
    # Use server-side encryption for logs stored in S3
    encrypt_s3_logs = False

Gcsロギングの場合、

  1. 最初にgcp_apiパッケージをインストールします(pip install Apache-airflow [gcp_api])。

  2. 上記の答え に従って接続フックを設定します

  3. 以下をairflow.cfgに追加します

    [core]
    # Airflow can store logs remotely in AWS S3. Users must supply a remote
    # location URL (starting with either 's3://...') and an Airflow connection
    # id that provides access to the storage location.
    remote_logging = True
    remote_base_log_folder = gs://my-bucket/path/to/logs
    remote_log_conn_id = MyGCSConn
    

注:Airflow 1.9の時点で、リモートロギングは 大幅に変更されました です。 1.9を使用している場合は、読み進めてください。

参照 ここ

完全な手順:

  1. 構成を保存するディレクトリを作成し、PYTHONPATHで見つけられるように配置します。 1つの例は$ AIRFLOW_HOME/configです

  2. $ AIRFLOW_HOME/config/log_config.pyおよび$ AIRFLOW_HOME/config/__ init__.pyという空のファイルを作成します

  3. airflow/config_templates/airflow_local_settings.py の内容を、上記の手順で作成したばかりのlog_config.pyファイルにコピーします。

  4. テンプレートの次の部分をカスタマイズします。

    #Add this variable to the top of the file. Note the trailing slash.
    S3_LOG_FOLDER = 's3://<bucket where logs should be persisted>/'
    
    Rename DEFAULT_LOGGING_CONFIG to LOGGING CONFIG
    LOGGING_CONFIG = ...
    
    Add a S3TaskHandler to the 'handlers' block of the LOGGING_CONFIG variable
    's3.task': {
        'class': 'airflow.utils.log.s3_task_handler.S3TaskHandler',
        'formatter': 'airflow.task',
        'base_log_folder': os.path.expanduser(BASE_LOG_FOLDER),
        's3_log_folder': S3_LOG_FOLDER,
        'filename_template': FILENAME_TEMPLATE,
    },
    
     Update the airflow.task and airflow.task_runner blocks to be 's3.task' instead >of 'file.task'.
    'loggers': {
        'airflow.task': {
            'handlers': ['s3.task'],
            ...
        },
        'airflow.task_runner': {
            'handlers': ['s3.task'],
            ...
        },
        'airflow': {
            'handlers': ['console'],
            ...
        },
    }
    
  5. 上記の回答 に従って、Airflowでs3接続フックが定義されていることを確認します。フックには、上記のS3_LOG_FOLDERで定義されたs3バケットへの読み取りおよび書き込みアクセスが必要です。

  6. 以下を含むように$ AIRFLOW_HOME/airflow.cfgを更新します。

    task_log_reader = s3.task
    logging_config_class = log_config.LOGGING_CONFIG
    remote_log_conn_id = <name of the s3 platform hook>
    
  7. Airflow Webサーバーとスケジューラを再起動し、新しいタスクの実行をトリガー(または待機)します。

  8. 定義したバケット内の新しく実行されたタスクのログが表示されていることを確認します。

  9. S3ストレージビューアーがUIで機能していることを確認します。新しく実行されたタスクをプルアップし、次のようなものが表示されることを確認します。

    *** Reading remote log from gs://<bucket where logs should be persisted>/example_bash_operator/run_this_last/2017-10-03T00:00:00/16.log.
    [2017-10-03 21:57:50,056] {cli.py:377} INFO - Running on Host chrisr-00532
    [2017-10-03 21:57:50,093] {base_task_runner.py:115} INFO - Running: ['bash', '-c', u'airflow run example_bash_operator run_this_last 2017-10-03T00:00:00 --job_id 47 --raw -sd DAGS_FOLDER/example_dags/example_bash_operator.py']
    [2017-10-03 21:57:51,264] {base_task_runner.py:98} INFO - Subtask: [2017-10-03 21:57:51,263] {__init__.py:45} INFO - Using executor SequentialExecutor
    [2017-10-03 21:57:51,306] {base_task_runner.py:98} INFO - Subtask: [2017-10-03 21:57:51,306] {models.py:186} INFO - Filling up the DagBag from /airflow/dags/example_dags/example_bash_operator.py
    
32
Arne Huang

(Airflow 1.10.2で更新)

以下は、管理UIを使用しない場合の解決策です。

私のAirflowは永続的なサーバーでは実行されません...(HerokuのDockerコンテナーで毎日新しく起動されます。)私は多くの優れた機能を逃していることを知っていますが、最小限の設定では、管理UIまたはcfgファイルには一切触れません。代わりに、.cfgファイルをオーバーライドするbashスクリプトでAirflow固有の環境変数を設定する必要があります。 。

Apache-airflow [s3]

まず、AirflowログをS3に書き込むには、s3サブパッケージをインストールする必要があります。 (boto3は、DAG内のPythonジョブに対して正常に動作しますが、S3Hookはs3サブパッケージに依存します。)

もう1つ注意事項:conda install まだこれを処理しません なので、pip install Apache-airflow[s3]を実行する必要があります。

環境変数

Bashスクリプトでは、これらのcore変数を設定します。 これらの手順 から始まりますが、環境変数にAIRFLOW__{SECTION}__{KEY}という命名規則を使用して、次のことを行います。

export AIRFLOW__CORE__REMOTE_LOGGING=True
export AIRFLOW__CORE__REMOTE_BASE_LOG_FOLDER=s3://bucket/key
export AIRFLOW__CORE__REMOTE_LOG_CONN_ID=s3_uri
export AIRFLOW__CORE__ENCRYPT_S3_LOGS=False

S3接続ID

上記のs3_uriは、私が作成した接続IDです。 Airflowでは、別の環境変数AIRFLOW_CONN_S3_URIに対応します。その値はS3パスであり、URI形式である必要があります。それは

s3://access_key:secret_key@bucket/key

これを保存しますが、他の機密性の高い環境変数を処理します。

この構成により、AirflowはS3にログを書き込むことができます。それらはs3://bucket/key/dag/task_id/timestamp/1.logのパスに従います。


Airflow 1.8からAirflow 1.10へのアップグレードに関する付録

私は最近、実稼働パイプラインをAirflow 1.8から1.9にアップグレードし、次に1.10にアップグレードしました。良いニュースは、変更が非常に小さいことです。残りの作業は、パッケージのインストールのニュアンスを把握するだけでした(S3ログに関する元の質問とは無関係です)。

(1)まず最初に、Python 3.6 with Airflow 1.9にアップグレードする必要がありました。

(2)1.9でパッケージ名がairflowからApache-airflowに変更されました。 pip installthis に遭遇することもあります。

(3)パッケージpsutilは、Airflowの特定のバージョン範囲にある必要があります。 pip install Apache-airflowを実行しているときにこれに遭遇するかもしれません。

(4)python3-devヘッダーはAirflow 1.9+で必要です。

(5)実質的な変更は次のとおりです。export AIRFLOW__CORE__REMOTE_LOGGING=Trueが必要になりました。そして

(6)S3ではログのパスがわずかに異なります。これは回答で更新しました:s3://bucket/key/dag/task_id/timestamp/1.log

しかし、それだけです!ログは1.9では機能しなかったので、利用可能になったので、すぐに1.10に進むことをお勧めします。

8
Niels Joaquin

最近のエアフローの更新でArneの回答を完了するために、task_log_readerをデフォルト値以外の値に設定する必要はありません:task

デフォルトのロギングテンプレート airflow/config_templates/airflow_local_settings.py に従うように、このコミットから を見ることができます (ハンドラーの名前に注意してください) 's3': {'task'...ではなく、s3.taskに変更されます。これは、リモートフォルダー(REMOTE_BASE_LOG_FOLDER)の値で、ハンドラーが正しいものに置き換えられます。

REMOTE_LOGGING = conf.get('core', 'remote_logging')

if REMOTE_LOGGING and REMOTE_BASE_LOG_FOLDER.startswith('s3://'):
        DEFAULT_LOGGING_CONFIG['handlers'].update(REMOTE_HANDLERS['s3'])
Elif REMOTE_LOGGING and REMOTE_BASE_LOG_FOLDER.startswith('gs://'):
        DEFAULT_LOGGING_CONFIG['handlers'].update(REMOTE_HANDLERS['gcs'])
Elif REMOTE_LOGGING and REMOTE_BASE_LOG_FOLDER.startswith('wasb'):
        DEFAULT_LOGGING_CONFIG['handlers'].update(REMOTE_HANDLERS['wasb'])
Elif REMOTE_LOGGING and ELASTICSEARCH_Host:
        DEFAULT_LOGGING_CONFIG['handlers'].update(REMOTE_HANDLERS['elasticsearch'])

S3へのログイン/ S3からの読み取り方法の詳細: https://github.com/Apache/incubator-airflow/blob/master/docs/howto/write-logs.rst#writing-logs -to-Amazon-s3

2
Paul Leclercq

上記の回答 の非常に有用な指示に従う人へのちょっとした注意:この問題に出くわした場合:「ModuleNotFoundError:「airflow.utils.log.logging_mixin.RedirectStdHandler」という名前のモジュールはありません」- ここで参照 (エアフロー1.9を使用する場合に発生します)、修正は簡単です-むしろこのベーステンプレートを使用してください: https://github.com/Apache/incubator-airflow/blob/v1- 9-stable/airflow/config_templates/airflow_local_settings.py (および 上記の回答 の他のすべての指示に従ってください)

現在のテンプレート incubator-airflow/airflow/config_templates/airflow_local_settings.py masterブランチに存在するクラスには、Apache-には存在しないクラス「airflow.utils.log.s3_task_handler.S3TaskHandler」への参照が含まれています。 airflow == 1.9.0 pythonパッケージ。これがお役に立てば幸いです!

1
diogoa

KubeのAirflow 10で動作するようにします。次のenv変数セットがあります。

AIRFLOW_CONN_LOGS_S3=s3://id:secret_uri_encoded@S3
AIRFLOW__CORE__REMOTE_LOGGING=True
AIRFLOW__CORE__REMOTE_BASE_LOG_FOLDER=s3://xxxx/logs
AIRFLOW__CORE__REMOTE_LOG_CONN_ID=logs_s3
0
Bertrand Paquet