Jak zapisać dane wyjściowe zadania do pliku?


10

Jedno z moich odpowiedzialnych zadań importuje bazę danych Oracle przy użyciu impdp.

To generuje dużo danych wyjściowych do konsoli, więc ustawiłem no_log: True.

Jednak gdy to się nie powiedzie, chcę zobaczyć dziennik!

Jak mogę zapisać to konkretne zadanie w pliku, a nie w konsoli?


Używasz modułu poleceń?
Xiong Chiamiov

Jednym z pomysłów [więcej hackowania] byłoby zapisanie dzienników w jakimś zewnętrznym pliku, a następnie wykonanie zadania, które korzysta z failed_whenwarunku, i usunięcie pliku dziennika, jeśli poprzedni. zadanie
powiodło się

Dlaczego mimo wszystko widzisz dane wyjściowe konsoli? Nie widziałem konfiguracji, ani też nie sądziłem, że jest możliwe, aby pokazać standardowe wyjście podczas pomyślnego wykonania zadania, powinno po prostu się pojawić [ok: nazwa hosta]. Jeśli jednak zostanie wykryty błąd, dane wyjściowe zostaną zrzucone do konsoli sterowania ansible (i zdefiniowane wszystkie logi ansible). Czy miałbyś coś przeciwko udostępnieniu konfiguracji, która daje ci duże możliwości podczas regularnego pomyślnego uruchamiania?
hvindin

@hvindin Wpisz -vvvpo ansible-playbookpoleceniu pobierania pełnych dzienników.
Dawny33

1
Rejestracja zmiennej wydaje się najlepszym logicznym posunięciem, zobacz mój komentarz do twojej odpowiedzi, aby uzyskać opinie na temat tego, co zrobić z wyjściami z uruchamianych poleceń ansible.
hvindin

Odpowiedzi:


4

[Konwertowanie mojego komentarza na odpowiedź]

Jednym ze sposobów na to byłoby zapisanie dzienników w jakimś zewnętrznym pliku, a następnie wykonanie zadania po nim, które korzysta z warunku fail_when, i usunięcie pliku dziennika, jeśli poprzednie zadanie zakończyło się powodzeniem.

Coś takiego powinno ci pomóc.

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

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

Uwaga: To może nie być najlepszy sposób na rozwiązanie problemu. Ale to był hack, który pomógł mi w logowaniu i monitorowaniu.


2
Chciałbym pójść jeszcze dalej i powiedzieć, że możesz zapisywać swoje polecenia do stdout / stderr, a następnie po prostu je zrzucić jako odpowiedź na awarię. Tak więc, jako przykład w powyższym przykładzie, jeśli chciałbyś zatrzymać wykonywanie w przypadku awarii, to przy użyciu zadania fail wystarczy wyprowadzić stdout i stderr zarejestrowane w PyScript, gdy rc! = 0 wydaje się bardziej holistycznym rozwiązaniem. Jeśli użyjesz wbudowanych mechanizmów ansibles, to jeśli na przykład skonfigurowano rejestrowanie odpowiedzi na serwerze sterującym, serwer kontroli zarejestruje awarię w dzienniku odpowiedzi. Który ja myślę byłoby właściwe miejsce dla niego
hvindin

3

Myślę, że wszystko, co musisz zrobić, to zarejestrować wynik każdego polecenia (przechowywać go w zmiennej), a następnie po prostu zrzucić zmienną do pliku. W ten sposób możesz to sprawdzić później.

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

Następnie w 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 }} 

Przykład, którego używam, pochodzi stąd


3

Rozwiązałem to, dodając

ignore_errors: true
register: results

do zadania no_log. Dzięki temu możliwe jest przejście do następnego zadania, nawet gdy zadanie się nie powiedzie. Następnie dla następnego zadania zdefiniuj zadanie debugowania, które zawsze kończy się niepowodzeniem i wyświetla zarejestrowaną zmienną, ale działa tylko wtedy, gdy poprzednie zadanie nie powiodło się:

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

Tak więc nawet przy no_log: true spowoduje to, że ansible wyświetli wynik nieudanego zadania. To rozwiązanie nie rejestruje go do pliku zgodnie z żądaniem, ale spełnia twoją potrzebę „zobacz dziennik, gdy nie powiodło się”, i oczywiście możesz przekierować lub użyć tee, aby wypisać pełne odpowiedzi wyjściowe do pliku, co w przypadku tego rozwiązania zawiera również dziennik nieudanego zadania.


2

To, co robię, gdy mam polecenie do wykonania i chcę uzyskać dziennik tylko w przypadku awarii, jest następujące (poprzedzone przez komendę powłoki, tak jak /bin/sh -c '...'w przypadku, gdy inicjator nie używa systemwywołania lub wykonuje polecenia bezpośrednio bez powłoki) :

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

To przekieruje błąd i standardowe wyjście do pliku i wyświetli zawartość pliku tylko w przypadku awarii. Jeśli polecenie jest bardzo szczegółowe i nie chcesz przechowywać dziennika, gdy jest w porządku, możesz:

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

Wycena &&i ||użycie strony sh :

Symbol && (||) powoduje wykonanie poniższej listy tylko wtedy, gdy poprzedni potok zwraca wartość zerową (niezerową).

To prawdopodobnie nie jest najbardziej idiomatyczny sposób na wykonanie tego z ansible, ale ma tę zaletę, że jest bardzo przenośny z dowolnym systemem zarządzania konfiguracją, który umożliwia wyświetlanie standardowego polecenia.


0

Zakładając, że ansible poprawnie generuje błędy do stderr, możesz przechwycić dane wyjściowe błędów w dowolnym programie do pliku za pomocą przekierowania wyjścia:

some command 2> error.log

Jednak nie sądzę, że tak jest.

Zamiast tego prawdopodobnie będziesz chciał zapoznać się z tym przewodnikiem, aby zdecydować, kiedy wystąpią błędy http://docs.ansible.com/ansible/playbooks_error_handling.html, a następnie grep swoje dane wyjściowe w poszukiwaniu ciągów wskazujących błąd przed wysłaniem do pliku

to znaczy.

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


-2

Myślę, że to, czego szukasz, może być po prostu przekierowaniem standardowego wejścia i ulicy do pliku.

Zazwyczaj niektóre polecenia i> logfile.log

lub jakiś wariant ....


Co jest tylko częściową odpowiedzią, OP chce zobaczyć dziennik na wypadek błędu.
Tensibai

Nie sądzę, że jest to nawet częściowa odpowiedź na to pytanie. Jest odpowiedni dla skryptu powłoki, ale bezużyteczny do kodowania w ansible .
pisklęta

@ laski Myślę, że może to być prawidłowe obejście metody „powłoki” w programie ansible (której niewiele wiem)
Tensibai

-2

Tee będzie bardzo prostym narzędziem do logowania, możesz odwołać się do następującego polecenia.

eric@eric-MacBookPro:~$ ansible -m ping all | tee > /tmp/ansible.log
eric@eric-MacBookPro:~$ cat /tmp/ansible.log 
localhost | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

2
1. Wpływa to na cały przebieg, a nie tylko na jedno zadanie. 2. Nie ma sensu przepływać przez tee, jeśli zamierzasz przekierować jego stdout do pliku; nie tak używasz polecenia. 3. Jeśli używałeś tee poprawnie, nadal wysyłałby cały spam do konsoli, czego OP nie chce.
Xiong Chiamiov
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.