Comment enregistrer la sortie d'une tâche dans un fichier?

10

L'une de mes tâches ansibles importe une base de données Oracle à l'aide de impdp.

Cela génère beaucoup de sortie vers la console, j'ai donc réglé no_log: True.

Cependant, lorsque cela échoue, je veux voir le journal!

Comment puis-je créer ce journal de tâches particulier dans un fichier et non dans la console?

optique
la source
Vous utilisez le module de commande?
Boycott SE pour Monica Cellio
Une idée [plus d'un hack] serait d'écrire les journaux dans un fichier externe, puis d'avoir une tâche après celle-ci qui utilise la failed_whencondition, et de supprimer le fichier journal, si le précédent. tâche réussie :)
Dawny33
Pourquoi pouvez-vous quand même voir la sortie de la console lors des exécutions réussies? Je n'ai pas vu de configuration pour, et je ne pensais pas qu'il était possible d'afficher stdout lors d'une exécution de tâche réussie, elle devrait simplement apparaître [ok: nom d'hôte]. Cependant, lorsqu'une erreur est détectée, la sortie est transférée vers la console de contrôle ansible (et tous les journaux ansible définis), cela vous dérangerait-il de partager la configuration qui vous donne la grande sortie standard lors d'une exécution régulière réussie?
hvindin
@hvindin Insérez -vvvaprès la ansible-playbookcommande pour obtenir des journaux détaillés.
Dawny33
1
L'enregistrement d'une variable semble être le meilleur choix logique, voir mon commentaire sur votre réponse pour mes opinions sur ce qu'il faut faire avec les sorties des commandes déclenchées par ansible.
hvindin

Réponses:

4

[Conversion de mon commentaire en réponse]

Une façon de le faire serait d'écrire les journaux dans un fichier externe, puis d'avoir une tâche après celle-ci qui utilise la condition failed_when, et de supprimer le fichier journal, si la tâche précédente a réussi.

Quelque chose comme ça devrait vous aider.

 - name: Run Py script
      command: <>.py  > <>.log
      become: yes
      register: PyScript
      ignore_errors: True

    - name: PyScript on success
      command: rm <>.log
      when: PyScript|succeeded

Remarque: Ce n'est peut-être pas la meilleure façon de gérer votre problème. Mais, c'était un hack qui m'a aidé à faire mon logging et mon monitoring.

Dawny33
la source
2
J'irais un peu plus loin et dirais que vous pourriez garder votre commande en écrivant sur stdout / stderr puis les vider simplement en réponse à un échec. Ainsi, à titre d'exemple dans votre exemple ci-dessus, si vous vouliez arrêter l'exécution en cas d'échec, utiliser une tâche d'échec pour simplement sortir la stdout et la stderr enregistrées dans PyScript lorsque le rc! = 0 semblerait une solution plus holistique. Si vous utilisez des mécanismes intégrés ansibles, si vous avez une journalisation ansible configurée sur un serveur de contrôle, par exemple, ce serveur de contrôle consignera l’échec dans le journal ansible. Ce qui je pense serait le bon endroit pour elle
hvindin
3

Je pense que tout ce que vous devez faire est d'enregistrer la sortie de chaque commande dont vous avez besoin (la stocker dans une variable), puis simplement vider la variable dans un fichier. De cette façon, vous pouvez le revoir plus tard.

tasks:
  - name: Dump all vars
    action: template src=templates/dumpall.j2 dest=/tmp/ansible.all

Puis dans dumpall.j2:

Module Variables ("vars"):
--------------------------------
{{ vars | to_nice_json }} 

Environment Variables ("environment"):
--------------------------------
{{ environment | to_nice_json }} 

GROUP NAMES Variables ("group_names"):
--------------------------------
{{ group_names | to_nice_json }}

GROUPS Variables ("groups"):
--------------------------------
{{ groups | to_nice_json }}

HOST Variables ("hostvars"):
--------------------------------
{{ hostvars | to_nice_json }} 

L'exemple que j'utilise vient d' ici

13dimitar
la source
3

J'ai résolu cela en ajoutant

ignore_errors: true
register: results

à la tâche no_log. Cela rend ansible continuer à la tâche suivante, même lorsque la tâche échoue. Ensuite, pour la tâche suivante, définissez une tâche de débogage, qui échoue toujours et génère la variable enregistrée, mais ne s'exécute que lorsque la tâche précédente a échoué:

- name: Error output
  debug:
     var: results
  failed_when: true
  when:
     results is failed

Donc, même avec no_log: true, cela rendra ansible afficher la sortie de la tâche ayant échoué. Cette solution ne l'enregistre pas dans un fichier comme demandé, mais répond pleinement à votre besoin de `` voir le journal en cas d'échec '', et bien sûr, vous pouvez rediriger ou utiliser tee pour sortir la sortie ansible complète dans un fichier, ce qui, avec cette solution contiennent également le journal de la tâche ayant échoué.

Robin Roevens
la source
2

Ce que je fais quand j'ai une commande à exécuter et que je souhaite obtenir le journal uniquement en cas d'échec est comme suit (préfixé par un shell et comme /bin/sh -c '...'si l'initiateur n'utilise pas d' systemappel ou n'exécute pas la commande directement sans shell) :

command 2&>1 > command-log.txt || cat command-log.txt

Cela redirigera l'erreur et la sortie standard vers un fichier et affichera le contenu du fichier en cas d'échec uniquement. Si la commande est très verbeuse et que vous ne souhaitez pas conserver le journal quand c'est ok vous pouvez aller avec:

command 2&>1 > command-log.txt && rm command-log.txt || cat command-log.txt

Citation &&et ||utilisation de la page de manuel sh :

Le symbole && (||) provoque l'exécution de la liste suivante uniquement si le pipeline précédent renvoie une valeur nulle (non nulle).

Ce n'est probablement pas la façon la plus idiomatique de le faire avec ansible mais a l'avantage d'être très portable avec tout système de gestion de configuration donnant la possibilité d'afficher la commande stdout.

Tensibai
la source
0

En supposant qu'ansible renvoie correctement les erreurs à stderr, vous pouvez capturer la sortie des erreurs dans n'importe quel programme vers un fichier en utilisant la redirection de sortie:

some command 2> error.log

Cependant, je ne pense pas que ce soit le cas.

Au lieu de cela, vous voudrez probablement vous référer à ce guide pour décider quand des erreurs se produiront http://docs.ansible.com/ansible/playbooks_error_handling.html puis grep votre sortie pour les chaînes qui indiquent une erreur avant de sortir dans un fichier

c'est à dire.

ansible-playbook my-playbook | grep 'error' > error.log

yosefrow
la source
-2

Je pense que ce que vous cherchez pourrait être trop simplement rediriger stdout et street vers un fichier.

En règle générale, some-command &> logfile.log

ou une variante ....

sparq
la source
Ce qui n'est qu'une réponse partielle, OP souhaite voir le log en cas d'erreur.
Tensibai
Je ne pense pas que ce soit même une réponse partielle à cette question. C'est bien pour un script shell, mais inutile pour le codage en ansible .
poussins
@chicks Je pense que cela pourrait être une solution de contournement valide sur une approche de méthode «shell» dans ansible (que je ne connais pas beaucoup)
Tensibai
-2

Tee sera un outil très simple pour la journalisation, vous pouvez vous référer à la commande suivante.

eric@eric-MacBookPro:~$ ansible -m ping all | tee > /tmp/ansible.log
eric@eric-MacBookPro:~$ cat /tmp/ansible.log 
localhost | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
Eric Zhang
la source
2
1. Cela affecte l'ensemble de l'exécution, pas seulement une tâche. 2. Il est inutile de passer par le tee si vous allez rediriger sa sortie standard vers un fichier; ce n'est pas ainsi que vous utilisez la commande. 3. Si vous utilisiez correctement tee, il enverrait tout le spam à la console, ce que OP ne veut pas.
Boycott SE pour Monica Cellio