• Członkowie 2 posty
    15 marca 2026 00:12

    Dzień dobry.

    Pracuję nad skryptem wykorzystującym bibliotekę "pymodbus" do odczytu danych w trybie synchronicznym protokołem ModBus RTU, uruchamianym jako daemon w systemie RaspianOS opartym na Debianie 11. Program zapisuje odczytane dane do plików. Tryb daemon-a oparty jest na skrypcie HanzDaemon używającym podwójnego odgałęzienia. Daemon korzysta zarówno z zapisu wyjścia do standardowego deskryptora pliku jak i zapisu błędów do standardowego deskryptora pliku.

    def _makeDaemon(self):
            """
            tworzenie demona - podwójne rozgałęzienie
            """
    
            try:
                pid = os.fork()
                if pid > 0:
                    # Exit first parent.
                    sys.exit(0)
            except OSError as err:
                print(f'Błąd rozwidlenia #1: {err}')
                sys.exit(1)
    
            # odłączenie od środowiska rodzica
            os.chdir('/')
            os.setsid()
            os.umask(0)
    
            # wykonanie drugiego odgałęzienia
            try:
                pid = os.fork()
                if pid > 0:
                    # Exit from second parent.
                    sys.exit(0)
            except OSError as err:
                print(f'Błąd rozwidlenia #2: {err}')
                sys.exit(1)
    
            print(f'Proces demona uruchomiono w tle (PID:{os.getpid()}).')
    
            # przekierowanie standardowych deskryptorów plików
            sys.stdout.flush()
            sys.stderr.flush()
            si = open(self.stdin, 'r')
            so = open(self.stdout, 'a+')
            se = open(self.stderr, 'a+')
            os.dup2(si.fileno(), sys.stdin.fileno())
            os.dup2(so.fileno(), sys.stdout.fileno())
            os.dup2(se.fileno(), sys.stderr.fileno())
    

    Wykorzystuję w programie obsługę wyjątków "try - except" do przechwytywania błędów "IO Exception" i "Communication Exception". Zapis do pliku wyjściowego komunikatów o błędach jest opóźniony czasowo. Program przechowuje wystąpienie pierwszego błędu i po zdefiniowanym czasie sprawdza, czy błąd nadal występuje co jest odnotowywane odpowiednim komunikatem w pliku wyjściowym. Skrypt pracuje prawidłowo.
    Problemem jest brak jakiejkolwiek kontroli nad ilością komunikatów błędów zapisywanych do pliku błędów, który w wypadku ich wystąpienia rośnie do horrendalnych rozmiarów.
    Na przykład: brak portu szeregowego odnotowywany jest w pliku wyjściowym komunikatami co pięć minut. W tym czasie plik błędów zawiera 100 komunikatów "[Errno 2] could not open port /dev/ttyUSB0".
    Inny przykład: brak odpowiedzi od urządzenia ModBus slave odnotowywane jest w pliku wyjściowym komunikatami co 15 minut. W tym czasie plik błędów zawiera komunikaty "No response received after 3 retries, continue with next request" w ilości odpowiadającej ilości odpytywanych rejestrów.

    Jak zapanować nad ilością komunikatów błędów zapisywanych do pliku błędów?

  • Członkowie 156 postów
    17 marca 2026 13:17

    Logi można zapisywać do pliku(ów) o nazwie zawierającej aktualną datę i np. logi starsze niż 7 dni czy 14 dni kasować z dysku. Bo rozumiem, że problemem oprócz przeglądania dużej liczby wpisów jest miejsce na "malinie"? Do przeglądania samych logów są dziś inteligentne narzędzia oparte o AI więc duża liczba błędów czy ostrzeżeń też nie powinna być problemem.

  • Członkowie 2 posty
    18 marca 2026 00:14

    Dzięki za zainteresowanie się tematem.

    W rzeczy samej chodzi głównie o miejsce na "malinie".
    Podejrzewam, że problemem są nowsze wersje bibliotek pythona "pymodbus 3.8.6" i "pyserial 3.5", gdzie zmienił się sposób obsługi i zgłaszania błędów połączeń.
    Zastanawiałem się, czy jest możliwość przechwycenia przez skrypt daemona błędu zgłaszanego przez bibliotekę i zliczanie jego wystąpień, a następnie po np. 100 wystąpieniach zapisania do pliku błędów jednego komunikatu. Coś podobnego robię do pliku wyjściowego (try - except), tylko tu kontroluję co wysyłam na standardowe wyjście daemona (plik wyjściowy). Natomiast nie mam kontroli nad tym co jest zapisywane w pliku błędów daemona.

  • Członkowie 156 postów
    18 marca 2026 12:37

    Jeśli te biblioteki są open-source to wystarczy zobaczyć z jakich loggerów korzystają, zapoznać się z nimi i je odpowiednio skonfigurować.

    pymodbus zawiera
    import logging

    Nie wiem na czym bazuje ten drugi.

    To powinno pomóc:

    import logging
    import logging.handlers
    
    logger = logging.getLogger("CustomLogger")
    logger.setLevel(logging.INFO)
    
    log_filename = 'app.log'
    handler = logging.handlers.TimedRotatingFileHandler(
        log_filename, 
        when='midnight', 
        interval=1, 
        backupCount=7, # Trzymaj logi tydzień
        encoding='utf-8'
    )
    
    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
    handler.setFormatter(formatter)
    logger.addHandler(handler)