web-dev-qa-db-fra.com

configuration de s3 pour les journaux dans le flux d'air

J'utilise docker-compose pour configurer un cluster de flux d'air évolutif. J'ai basé mon approche sur ce Dockerfile https://hub.docker.com/r/puckel/docker-airflow/

Mon problème est d'obtenir les journaux configurés pour écrire/lire à partir de S3. Quand un dag est terminé je reçois une erreur comme celle-ci

*** 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

J'ai créé une nouvelle section dans le fichier airflow.cfg comme ceci

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

Et puis spécifié le chemin s3 dans la section des journaux distants dans airflow.cfg

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

Ai-je bien configuré cela et il y a un bug? Y at-il une recette du succès ici qui me manque?

-- Mettre à jour

J'ai essayé d'exporter aux formats URI et JSON et aucun ne semblait fonctionner. J'ai ensuite exporté les mots aws_access_key_id et aws_secret_access_key, puis Airflow a commencé à le récupérer. Maintenant, je reçois son erreur dans les journaux de travail 

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

-- Mettre à jour

J'ai aussi trouvé ce lien https://www.mail-archive.com/[email protected]/msg00462.html

J'ai ensuite shell dans l'une de mes machines de travail (séparée du serveur Web et du planificateur) et ai exécuté ce morceau de code en python

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

Je reçois cette erreur.

boto.exception.S3ResponseError: S3ResponseError: 403 Forbidden

J'ai essayé d'exporter différents types d'environnements AIRFLOW_CONN_ comme expliqué ici dans la section des connexions https://airflow.incubator.Apache.org/concepts.html et par d'autres réponses à cette question.

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>"}

J'ai également exporté AWS_ACCESS_KEY_ID et AWS_SECRET_ACCESS_KEY sans succès.

Ces informations d'identification sont stockées dans une base de données. Par conséquent, une fois que je les ai ajoutées dans l'interface utilisateur, elles doivent être récupérées par les travailleurs, mais ils ne sont pas en mesure d'écrire/lire les journaux pour une raison quelconque.

28
JackStat

Vous devez configurer la connexion s3 via l'interface utilisateur de flux d'air. Pour cela, vous devez accéder à l'onglet Admin -> Connexions de l'interface utilisateur de flux d'air et créer une nouvelle ligne pour votre connexion S3.

Un exemple de configuration serait:

ID de connexion: my_conn_S3

Type de connecteur: S3

Extra: {"aws_access_key_id": "your_aws_key_id", "aws_secret_access_key": "your_aws_secret_key"}}

14
Him

UPDATE Airflow 1.10 facilite la journalisation beaucoup plus facilement.

Pour la journalisation s3, configurez le crochet de connexion comme indiqué dans la réponse ci-dessus

puis ajoutez simplement ce qui suit à 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

Pour la journalisation gcs, 

  1. Installez d’abord le paquet gcp_api, comme suit: pip install Apache-airflow [gcp_api].

  2. Configurez le crochet de connexion comme indiqué dans la réponse ci-dessus

  3. Ajouter ce qui suit à 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
    

REMARQUE: à partir de Airflow 1.9, la journalisation à distance a été modifiée de manière significative . Si vous utilisez 1.9, lisez la suite.

Référence ici

Instructions complètes:

  1. Créez un répertoire pour stocker les configurations et placez-les de manière à pouvoir les trouver dans PYTHONPATH. Un exemple est $ AIRFLOW_HOME/config

  2. Créez des fichiers vides nommés $ AIRFLOW_HOME/config/log_config.py et $ AIRFLOW_HOME/config/__ init__.py 

  3. Copiez le contenu de airflow/config_templates/airflow_local_settings.py dans le fichier log_config.py qui vient d'être créé à l'étape ci-dessus.

  4. Personnalisez les parties suivantes du modèle:

    #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. Assurez-vous qu’un crochet de connexion s3 a été défini dans Airflow, conformément à la réponse ci-dessus . Le hook devrait avoir un accès en lecture et en écriture au compartiment s3 défini ci-dessus dans S3_LOG_FOLDER. 

  6. Mettez à jour $ AIRFLOW_HOME/airflow.cfg pour qu'il contienne:

    task_log_reader = s3.task
    logging_config_class = log_config.LOGGING_CONFIG
    remote_log_conn_id = <name of the s3 platform hook>
    
  7. Redémarrez le serveur Web Airflow et le planificateur, puis déclenchez (ou attendez) l'exécution d'une nouvelle tâche.

  8. Vérifiez que les journaux indiquent les tâches nouvellement exécutées dans le compartiment que vous avez défini.

  9. Vérifiez que le visualiseur de stockage s3 fonctionne dans l'interface utilisateur. Extrayez une tâche nouvellement exécutée et vérifiez que vous voyez quelque chose comme:

    *** 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
    
27
Arne Huang

(Mis à jour à partir du flux d'air 1.10.2)

Voici une solution si vous n'utilisez pas l'interface utilisateur d'administration.

Mon Airflow ne fonctionne pas sur un serveur persistant ... (Il est lancé tous les jours dans un conteneur Docker, sur Heroku.) Je sais que je manque de nombreuses fonctionnalités exceptionnelles, mais dans ma configuration minimale. , Je ne touche jamais à l'interface d'administration ni au fichier cfg. À la place, je dois définir des variables d'environnement spécifiques à Airflow dans un script bash, qui remplace le fichier .cfg.

Apache-airflow [s3]

Tout d’abord, le sous-paquet s3 doit être installé pour écrire vos journaux d’airflow sur S3. (boto3 fonctionne bien pour les travaux Python dans vos DAG, mais le S3Hook dépend du sous-package s3.)

Encore une note de côté: conda install ne gère pas encore cela , je dois donc faire pip install Apache-airflow[s3].

Variables d'environnement

Dans un script bash, je définis ces variables core. À partir de ces instructions mais en utilisant la convention d'appellation AIRFLOW__{SECTION}__{KEY} pour les variables d'environnement, je fais:

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

ID de connexion S3

Le s3_uri ci-dessus est un identifiant de connexion que j'ai composé. Dans Airflow, cela correspond à une autre variable d'environnement, AIRFLOW_CONN_S3_URI. La valeur de cela est votre chemin S3, qui doit être au format URI. C'est

s3://access_key:secret_key@bucket/key

Stockez-le, mais vous gérez d’autres variables d’environnement sensibles.

Avec cette configuration, Airflow pourra écrire vos journaux sur S3. Ils suivront le chemin de s3://bucket/key/dag/task_id/timestamp/1.log.


Annexe sur la mise à niveau de Airflow 1.8 à Airflow 1.10

J'ai récemment mis à niveau mon pipeline de production d'Airflow 1.8 à 1.9, puis 1.10. La bonne nouvelle est que les changements sont minimes. le reste du travail consistait simplement à trouver des nuances dans les installations de paquets (sans rapport avec la question initiale concernant les journaux S3).

(1) Avant tout, je devais passer à Python 3.6 avec Airflow 1.9.

(2) Le nom du paquet est passé de airflow à Apache-airflow avec 1.9. Vous pouvez également rencontrer this dans votre pip install.

(3) Le package psutil doit figurer dans une plage de versions spécifique pour Airflow. Vous pourriez rencontrer cela quand vous faites pip install Apache-airflow.

(4) Les en-têtes python3-dev sont nécessaires avec Airflow 1.9+.

(5) Voici les modifications de fond: export AIRFLOW__CORE__REMOTE_LOGGING=True est maintenant requis. Et

(6) Les journaux ont un chemin légèrement différent dans S3, que j’ai mis à jour dans la réponse: s3://bucket/key/dag/task_id/timestamp/1.log.

Mais c'est tout! Les journaux ne fonctionnaient pas dans la version 1.9, je vous recommande donc d’aller directement à la version 1.10, maintenant qu’elle est disponible.

7
Niels Joaquin

Pour compléter la réponse d'Arne avec les dernières mises à jour d'Airflow, il n'est pas nécessaire de définir task_log_reader sur une valeur autre que celle par défaut: task.

Comme si vous suiviez le modèle de journalisation par défaut airflow/config_templates/airflow_local_settings.py vous pouvez voir puisque ce commit (notez que le nom du gestionnaire a été changé en 's3': {'task'... au lieu de s3.task), ce qui correspond à la valeur du dossier distant (REMOTE_BASE_LOG_FOLDER). remplacera le gestionnaire par le bon:

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'])

Plus de détails sur la façon de se connecter à/lire depuis S3: https://github.com/Apache/incubator-airflow/blob/master/docs/howto/write-logs.rst#writing-logs-to-Amazon- s3

2
Paul Leclercq

Remarque juste pour les personnes qui suivent les instructions très utiles figurant dans la réponse ci-dessus : Si vous tombez sur ce problème: "ModuleNotFoundError: Aucun module nommé 'Airflow.utils.log.logging_mixin.RedirectStdHandler" " comme référencé ici (ce qui se produit lors de l’utilisation de airflow 1.9), le correctif est simple - utilisez plutôt ce modèle de base: https://github.com/Apache/incubator-airflow/blob/v1-9- stable/airflow/config_templates/airflow_local_settings.py (et suivez toutes les autres instructions de la réponse ci-dessus )

Le modèle actuel incubator-airflow/airflow/config_templates/airflow_local_settings.py present dans la branche maître contient une référence à la classe "airflow.utils.log.s3_task_handler.S3TaskHandler", absente dans Apache-airflow == Paquet 1.9.0 python. J'espère que cela t'aides!

1
diogoa

Faites-le fonctionner avec Airflow 10 dans kube .

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