Debugowanie: dane wyjściowe konsoli i skrypty początkowe

16

Jak wysyłasz dane wyjściowe skryptu upstart do terminala, aby znaleźć ślady zwrotne w kodzie python? Na zawsze zabiera mnie robienie rzeczy bez śladów, które zajmowały tylko sekundę. Muszę wykonać kilka wywołań zapisu plików, aby wyśledzić błędy. To, co wcześniej zajęło znalezienie drugiego śladu wstecz, zamienia się w kilka minut. To jest nieszczęśliwe. Trwa to już od kilku tygodni i mam tego dość. czy ktoś mógłby o tym mówić? Mam wrażenie, że ponownie używam asemblera bez debuggera.

bambuntu
źródło

Odpowiedzi:

27

Jeśli używasz Upstart 1.4 lub nowszego, włóż console logdo zadania Upstart, a wszystkie dane wyjściowe do stdout / stderr zakończą się /var/log/upstart/<job>.log. Następnie możesz zrobić, tail -f /var/log/upstart/<job>.log &aby dane wyjściowe pojawiały się w terminalu.

Tuminoid
źródło
Trochę późno na imprezę, ale ta odpowiedź mnie uratowała :) Wygląda też na to, że działa dla mnie bez specjalnego ustawienia w pliku conf na starcie. Z mojej strony powinna to być zaakceptowana odpowiedź.
rslite
Nie wiedziałem, że znajdują się dzienniki usług zarządzanych upstart /var/log/upstart. Naprawdę przydatne, dziękuję.
Francisco
2

W książce kucharskiej Upstart znajduje się cała sekcja na temat technik debugowania . Najłatwiejszą rzeczą, jaką możesz zrobić, jest dodanie --debugargumentów jądra, co zwiększy gadatliwość upstart i zrzuci wszystko do syslog. Tak, debugowanie jest skomplikowane, jest odzwierciedleniem złożoności sieci wymaganej do stworzenia równoległego systemu inicjującego. Jestem pewien, że jest miejsce na ulepszenia.

ppetraki
źródło
2
książka kucharska nie wyjaśnia poprawnie nowemu użytkownikowi środowiska debugowania. Wcześniej widziałem podobne wyjaśnienia. Brakuje albo przyjmuje założenia guru. Jest to bardzo frustrujące dla osób, które chcą dodać do społeczności i dopiero zaczynają. Nigdy nie spotkałem środowiska programistycznego, które nie dostarczyło wiersza kodu, w którym występuje błąd, z wyjątkiem montażu, w którym wymyślasz koło, aby można było to wybaczyć.
bambuntu
Co byś wtedy zaproponował? To otwarty dokument. Jeśli masz technikę debugowania, która przeskakuje ponad to, co tam jest przedstawione, dodaj ją. Problemy OP są raczej wynikiem niezrozumienia, jak zarządzać podstawowymi paradygmatami uniksowymi w jego dodatkowym środowisku wykonawczym do wyboru w kontekście kontekstu, w którym jest on wdrażany. To, że używasz Pythona lub [wstaw tutaj wymyślny język środowiska wykonawczego], nie oznacza, że ​​jesteś zignoruj ​​podstawowe środowisko uruchomieniowe, UNIX.
ppetraki
2

Kiedy piszę demona python, wychwytuję wszystkie wyjątki i wrzucam do pliku dziennika. Używam nie tylko do debugowania, ale także podczas produkcji. Mam mały skrypt, który uruchamiam każdego ranka i który szuka czegoś niepokojącego w logach.

Oczywiście pomaga również w utrzymaniu działania demona.

Trochę przykładowego kodu (usuwam nieciekawe części):

import logging

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s %(levelname)s %(message)s',
                    filename=LOG_FILE,
                    filemode='w')
    logging.info("Sincrod inicializado")
    if not DEBUG:
        daemonize()
    while True:
        try:
            actua()
        except:
            logging.error(sys.exc_info())
        if (datetime.datetime.now().hour > NOITE_EMPEZA\
         and datetime.datetime.now().hour < NOITE_REMATA):
            time.sleep(INTERVALO_NOITE)
        else:
            time.sleep(INTERVALO_DIA)

Gdzie actua () jest prawdziwym demonem (pisze też, aby się zalogować). Zauważ, że mam również zmienną DEBUG w pliku ustawień, gdy jest to prawda, nie rozwidlam demona, więc jest uruchamiany na konsoli.

Demony

Demony są uniksowym odpowiednikiem usług Windows. Są to procesy działające w tle niezależnie od innych procesów. Oznacza to, że ich ojciec jest zwykle inicjowany i że są oderwani od jakiegokolwiek tty. Ponieważ są one niezależne, nie ma z góry określonego miejsca na umieszczenie ich wyników.

Istnieje wiele bibliotek i fragmentów Pythona do stworzenia demona, w powyższym przykładzie używam własnej funkcji, która łączy kilka pomysłów z wersji Steinar Knutsens i Jeff Kunces. To jest tak proste, jak to możliwe, pamiętaj, że rozwidlam dwa razy .

def daemonize():
    """Forks this process creating a daemon and killing the original one"""
    if (not os.fork()):
        # get our own session and fixup std[in,out,err]
        os.setsid()
        sys.stdin.close()
        sys.stdout = NullDevice()
        sys.stderr = NullDevice()
        if (not os.fork()):
            # hang around till adopted by init
            ppid = os.getppid()
            while (ppid != 1):
                time.sleep(0.5)
                ppid = os.getppid()
        else:
            # time for child to die
            os._exit(0)
    else:
        # wait for child to die and then bail
        os.wait()
        sys.exit()
Javier Rivera
źródło
OK ponieważ już logujesz się do syslog, po prostu odfiltruj wiadomości demona i zrzuć je do konsoli. Nie rozumiem, dlaczego jest to specyficzne dla upstart? Inicjatywa SysV miałaby ten sam problem.
ppetraki
Masz rację, to nie jest specyficzne dla upstart, mówiąc prawdę, większość moich serwerów działa 8.04, bez upstartu. Ale dotyczy to również upstartu. OP pytał, jak debugować skrypty Pythona za pomocą upstartu, a nie dla metody, która działa tylko z upstartem. Nie loguję się do syslog, ale do określonego pliku, a „sztuczka” polega na wyłapywaniu wszystkich wyjątków i zrzucaniu śladu stosu do tego pliku.
Javier Rivera
Cóż, to tylko zarządzanie standardem na podstawie kontekstu, prawda? Znam wiele demonów unixowych, które mają równoważną szczegółowość rejestrowania, niezależnie od tego, czy są podłączone do tty, czy działają jako demony. Gdyby to był Ruby, przesadziłbym lub udekorowałbym metodę klasy bazowej, której wyjątki używają do wypisywania. Jestem pewien, że coś podobnego można zrobić w Pythonie. Lepiej lepiej zadaj to pytanie przy właściwej wymianie stosu. Jest to bardziej podstawowy problem kodowania / projektowania demona unixowego i, jak powiedziałeś, nie ma on nic wspólnego ze skryptami inicjującymi.
ppetraki
Wciąż poznaję język. Zakładam, że przez demona masz na myśli konkretny skrypt działający w tle. W twoim kodzie po prostu umieściłem mój skrypt zamiast actua (), aby uzyskać wywołania zwrotne dla tego wywołania skryptu? Czy istnieje możliwość przekierowania go do konsoli zamiast pliku?
bambuntu
1
demony w sensie samodzielnym są zwykle odłączane od tty, na którym zostały uruchomione, zamykają swoje oryginalne uchwyty plików na stdin, stdout i stdin i są potomkami init. Jeśli więc chcesz wydrukować wyjątki w określonym miejscu, dowiedz się, w jaki sposób są one generowane, i skieruj je stamtąd. linfo.org/daemon.html . Ponownie, nie ma to nic wspólnego z upstartem, ani nawet z initem. Spraw, aby Twój program działał poprawnie w trybie prawdziwego demona, a następnie przenieś go na wyższy poziom.
ppetraki