I have this application running on an IR829.
I have some problems, I would like to know if you have already gone through this and if you can help me.
1 - I need to write the logs to the environment variable.
So that I can debug them.
2 - the python script is "crashing". within 20 to 30 minutes it crashes, doesn't display the logs in the .txt file and I have to stop and start the application to get it back.
On my laptop it runs without interruption.
# -*- coding: utf-8 -*-
#!/usr/bin/python
import ftplib
import subprocess
import os
import time
from datetime import datetime, timedelta
from threading import Thread
import SimpleHTTPServer
import SocketServer
import threading
ftp_dest_path = "/Data/"
ftp_source_path = "/home/Datalogger/"
host = "192.168.0.45"
logdir = os.getenv("CAF_PERSISTENT_DIR")
if logdir is None:
logdir = "." # Caso a variável de ambiente não esteja definida, use o diretório atual como padrão
# Funcao para registrar mensagens em um arquivo de log
def log_message(message
now = datetime.now()
current_time = now.strftime("%Y-%m-%d %H:%M:%S")
log_filename = "log.txt"
log_filepath = os.path.join(logdir, log_filename)
with open(log_filepath, "a") as log_file:
log_file.write("%s - %s\n" % (current_time, message))
def clear_old_logs():
log_filename = "log.txt"
log_filepath = os.path.join(logdir, log_filename)
if os.path.exists(log_filepath
last_modified_time = datetime.fromtimestamp(os.path.getmtime(log_filepath))
current_time = datetime.now()
if (current_time - last_modified_time).days > 30:
os.remove(log_filepath)
def check_icmp(host
try:
subprocess.check_output(["ping", "-c", "1", host]) # Usando -c no Linux
return True
except subprocess.CalledProcessError:
return False
def connect_ftp(host, username, password
print("Entrei na função para conectar no FTP")
max_retries = 5
retries = 0
while retries < max_retries:
try:
ftp = ftplib.FTP(host, timeout=10) # Adiciona um timeout de 10 segundos
ftp.set_pasv(True)
ftp.login(username, password)
return ftp, None # Retorna também None para o erro
except ftplib.all_errors as e:
retries += 1
error_message = "FTP connection attempt {}/{} failed. Error: {}".format(retries, max_retries, str(e))
log_message(error_message)
print(error_message)
try:
ftp.quit() # Tenta desconectar em caso de falha
except:
pass
time.sleep(1) # Espera um curto período antes de tentar reconexão
return None, "Failed to establish FTP connection after {} attempts.".format(max_retries)
def disconnect_ftp(ftp
try:
ftp.sendcmd('PASV') # Envia PASV antes de fechar a conexão
ftp.quit()
except Exception as e:
error_message = "Error while disconnecting FTP: {}".format(str(e))
log_message(error_message)
print(error_message)
def collect_ftp_info(ftp
ftp.cwd(ftp_source_path) # Altera o diretório de trabalho para o diretório desejado
items = ftp.nlst()
files = [item for item in items if "." in item] # Filtra apenas arquivos
return files
def copy_file(source_ftp, dest_ftp, file
try:
print("Entrei na função de cópia")
dest_file_path = os.path.join(ftp_dest_path, os.path.basename(file))
source_file_path = os.path.join(ftp_source_path, os.path.basename(file))
source_mod_time = source_ftp.sendcmd("MDTM " + file)
try:
dest_mod_time = dest_ftp.sendcmd("MDTM " + dest_file_path)
except ftplib.error_perm:
dest_mod_time = None # Arquivo não existe no destino
if dest_mod_time is None or source_mod_time > dest_mod_time:
with open(file, "wb") as local_file:
source_ftp.retrbinary("RETR " + file, local_file.write)
with open(file, "rb") as local_file:
try:
dest_ftp.storbinary("STOR " + dest_file_path, local_file)
except ftplib.error_perm as e:
if "550" in str(e
print("Erro 550: Permissão negada. Movendo arquivo para diretório de arquivos corrompidos.")
log_message("Erro 550: Permissão negada para {}. Movendo arquivo para diretório de arquivos corrompidos.".format(file))
move_corrupted_file(file)
return True, None # Continua com o próximo arquivo sem gerar erro
else:
print("Erro durante a cópia de arquivo FTP: {}".format(str(e)))
time.sleep(5) # Aguarda antes de tentar novamente
return False, str(e) # Tenta novamente
os.remove(file)
# Verifique o tamanho do arquivo no servidor de origem e no servidor de destino
source_size = source_ftp.size(file)
dest_size = dest_ftp.size(dest_file_path)
print("Comparando arquivos: {} ({} bytes) vs {} ({} bytes)".format(
file, source_size, dest_file_path, dest_size))
if source_size == dest_size:
# Se os tamanhos são iguais, o arquivo foi copiado corretamente
bkp_file_path = os.path.join("/home/Datalogger/bkp/", os.path.basename(file))
try:
source_ftp.rename(file, bkp_file_path)
print("Movendo arquivos já copiados")
except ftplib.error_perm as e:
if "550" in str(e
print("Erro 550: Não foi possível mover {}. Continuando...".format(file))
log_message("Erro 550: Não foi possível mover {}. Continuando...".format(file))
pass
else:
print("Erro ao mover arquivo FTP: {}".format(str(e)))
message = "File %s copied successfully from source to destination and moved to /home/Datalogger/bkp." % file
log_message(message)
print(message)
else:
# Se os tamanhos são diferentes, move o arquivo corrompido
print("Erro: Tamanhos diferentes. Movendo arquivo para diretório de arquivos corrompidos.")
log_message("Erro: Tamanhos diferentes para {}. Movendo arquivo para diretório de arquivos corrompidos.".format(file))
move_corrupted_file(file)
return True, None # Retorna sucesso e None para o erro
except Exception as e:
print("Erro durante a cópia de arquivo FTP: {}".format(str(e)))
time.sleep(5) # Aguarda antes de tentar novamente
return False, str(e) # Tenta novamente
def move_corrupted_file(file
corrupted_dir = "/home/Datalogger/corrupted/"
if not os.path.exists(corrupted_dir
os.makedirs(corrupted_dir)
corrupted_file_path = os.path.join(corrupted_dir, os.path.basename(file))
os.rename(file, corrupted_file_path)
# Handler personalizado para o servidor HTTP
class MyHandler(SimpleHTTPServer.SimpleHTTPRequestHandler
pass
def start_http_server():
handler = MyHandler
httpd = SocketServer.TCPServer(('0.0.0.0', 3330), handler)
print("Server running on port 3330")
httpd.serve_forever()
def create_log_file():
log_file_path = os.path.join(logdir, "log.txt")
with open(log_file_path, "w") as log_file:
log_file.write("Initial log content.")
def test_icmp(host
try:
subprocess.run(["ping", "-c", "1", host], timeout=10, check=True)
return True
except subprocess.CalledProcessError:
print("Teste ICMP falhou para o host: {}".format(host))
log_message("Teste ICMP falhou para o host: {}".format(host))
return False
except subprocess.TimeoutExpired:
print("Teste ICMP expirou para o host: {}".format(host))
log_message("Teste ICMP expirou para o host: {}".format(host))
return False
def start_ftp_operations():
while True:
try:
clear_old_logs()
ftp_dest_host = "192.168.0.45"
ftp_dest_user = "User"
ftp_dest_pass = "Password"
ftp_source_host = "192.168.0.247"
ftp_source_user = "User"
ftp_source_pass = "Password"
icmp_host_to_check = ftp_dest_host
icmp_failures = 0
ftp_dest_failures = 0
ftp_source_failures = 0
def ftp_operations(source_ftp, dest_ftp
try:
while True:
if test_icmp(ftp_source_host) and test_icmp(ftp_dest_host
source_ftp, source_error = connect_ftp(ftp_source_host, ftp_username, ftp_password)
dest_ftp, dest_error = connect_ftp(ftp_dest_host, ftp_username, ftp_password)
if source_ftp and dest_ftp:
try:
ftp_operations(source_ftp, dest_ftp)
finally:
source_ftp.quit()
dest_ftp.quit()
else:
log_message("Falha na conexão FTP. Source: {}. Dest: {}.".format(source_error, dest_error))
time.sleep(30) # Aguarda 30 segundos antes de tentar novamente
except KeyboardInterrupt:
print("Script interrompido pelo usuário.")
except Exception as e:
print("Erro no script: {}".format(str(e)))
log_message("Erro no script: {}".format(str(e)))
def test_icmp(host
try:
subprocess.run(["ping", "-c", "1", host], timeout=10, check=True)
return True
except subprocess.CalledProcessError:
print("Teste ICMP falhou para o host: {}".format(host))
log_message("Teste ICMP falhou para o host: {}".format(host))
return False
except subprocess.TimeoutExpired:
print("Teste ICMP expirou para o host: {}".format(host))
log_message("Teste ICMP expirou para o host: {}".format(host))
return False
def ftp_operations_thread(source_host, source_user, source_pass, dest_host, dest_user, dest_pass, ftp_failures, log_prefix
while True:
try:
if not check_icmp(dest_host
print("Entrei na funcao do teste ICMP")
ftp_failures += 1
mensagem = "{} Falha no teste ICMP ({} falhas). Tentando novamente em 1 segundo...".format(log_prefix, ftp_failures)
log_message(mensagem)
print(mensagem)
time.sleep(1)
continue
ftp_failures = 0
mensagem = "{} Teste ICMP bem-sucedido. Tentando conexão FTP...".format(log_prefix)
log_message(mensagem)
print(mensagem)
source_ftp, erro_source = connect_ftp(source_host, source_user, source_pass)
dest_ftp, erro_dest = connect_ftp(dest_host, dest_user, dest_pass)
if source_ftp is None or dest_ftp is None:
ftp_failures += 1
mensagem = "{} Falha na conexão FTP ({} falhas). Erro Source: {}. Erro Dest: {}".format(log_prefix, ftp_failures, erro_source, erro_dest)
log_message(mensagem)
print(mensagem)
else:
mensagem = "{} Conectado ao FTP.".format(log_prefix)
log_message(mensagem)
print(mensagem)
if source_ftp is not None and dest_ftp is not None:
ftp_failures = 0
try:
arquivos = collect_ftp_info(source_ftp)
except ftplib.error_temp as e:
if "425" in str(e
print("{} Erro 425: Não é possível preparar para a conexão de dados. Tentando novamente em 1 segundo...".format(log_prefix))
print("Arquivos" + arquivos)
time.sleep(1)
continue
mensagem = "{} Copiando arquivos...".format(log_prefix)
log_message(mensagem)
print(mensagem)
for arquivo in arquivos:
tentativas = 0
while tentativas < 3: # Tenta até 3 vezes
try:
print(arquivos)
sucesso, erro = copy_file(source_ftp, dest_ftp, arquivo)
if not sucesso:
mensagem = "{} Falha ao copiar {}. Erro: {}".format(log_prefix, arquivo, erro)
log_message(mensagem)
print(mensagem)
break
except ftplib.error_temp as e:
if "425" in str(e
print("{} Erro 425: Não é possível preparar para a conexão de dados. Tentando novamente em 1 segundo...".format(log_prefix))
time.sleep(1)
tentativas += 1
continue
else:
print("{} Erro temporário FTP: {}. Tentando novamente em 1 segundo...".format(log_prefix, str(e)))
time.sleep(1)
tentativas += 1
continue
try:
disconnect_ftp(source_ftp)
disconnect_ftp(dest_ftp)
except Exception as e:
print("{} Erro ao encerrar as conexões FTP: {}".format(log_prefix, e))
mensagem = "{} Operações FTP concluídas.".format(log_prefix)
log_message(mensagem)
print(mensagem)
mensagem = "{} Fora do loop interno.".format(log_prefix)
log_message(mensagem)
print(mensagem)
print("Funçao Thread, aguarde 30 segundos...")
time.sleep(30)
except Exception as e:
print("{} Erro não tratado: {}. Tentando novamente em 1 segundo...".format(log_prefix, str(e)))
time.sleep(120)
ftp_operations_thread(ftp_source_host, ftp_source_user, ftp_source_pass, ftp_dest_host, ftp_dest_user, ftp_dest_pass, ftp_dest_failures, "Destination")
ftp_operations_thread(ftp_source_host, ftp_source_user, ftp_source_pass, ftp_dest_host, ftp_dest_user, ftp_dest_pass, ftp_source_failures, "Source")
time.sleep(5)
# Crie o arquivo log.txt inicial
create_log_file()
time.sleep(5) # Aguarda 5 segundos antes de reiniciar
except Exception as e:
print("Erro não tratado no loop principal: {}. Reiniciando em 5 segundos...".format(str(e)))
time.sleep(5)
# Inicie o servidor HTTP em uma thread separada
http_server_thread = Thread(target=start_http_server)
http_server_thread.start()
# ------------
# Espere que a thread do servidor HTTP termine
http_server_thread.join()
if __name__ == "__main__":
start_ftp_operations()