Como monitorar um programa de longa duração programaticamente

11

O que eu tenho atualmente pode ser resumido com este pseudo-código:

public static void Main(string[] args)
{
    var listOfObjects = Database.GetObjectsToUploadToOnlineService();
    Parallel.ForEach(Upload)
}

private static void Upload(MyUploadObject obj)
{
    //Build object (takes a few milliseconds)
    //Format to JSON (takes a few more milliseconds)
    //Upload (can take up to a max of 10 minutes)
    //Wait for a response (can take up to a max of 10 minutes)
    //Save response to our database (takes a few milliseconds)
}

Este programa acabou de ser configurado em nosso servidor como uma tarefa agendada. Nós possuímos o programa e podemos fazer o que queremos com ele. Minha pergunta deriva de um blog sobre como fazer verificações de monitoramento automatizadas (não tenho um link à mão).

Então isso me fez pensar: como no mundo posso modificar meu programa para iniciar outro programa de "monitoramento"? Ou isso deve mudar de um programa de console para dizer um programa WPF oculto?

No geral, eu preferiria poder executar um programa no meu computador que verifique o andamento do programa através da rede, para que não precise fazer o RDP no servidor para verificar seu status (mas não ser o fim do mundo).

No geral, suponho que gostaria de ver uma janela que diz algo como: Processo x de y até agora, os seguintes itens estão sendo processados. Liste os itens em, como, uma tabela e diga-os como "Carregando" ou "Aguardando resposta". Talvez se eu enlouquecer, eu também poderia como uma fila de itens com falha (mas isso seria apenas extra).

Minha mente continua inclinada para um evento, mas não consigo descobrir como executar um programa que possa se inscrever ou cancelar a inscrição em um programa em execução. Isso é possível?

Robert Snyder
fonte
Deseja monitorar o progresso nas operações de upload / resposta (com duração de 10 minutos) ou deseja saber quantos envios ocorreram dentro do loop "Parallel.ForEach"?
Doc Brown
@DocBrown veja edit. (últimos dois parágrafos)
Robert Snyder
1
Parece-me que o que você quer é talvez um simples programa receptor UDP. Você pode descartar pacotes de status na rede e, se não houver nada para recebê-los, nenhum dano será causado.
24715 Robert Harvey

Respostas:

7

O que você precisa é de uma maneira de se comunicar entre seus programas que não os vincule. Há várias maneiras de fazer isso: você pode ter a tarefa gravada em um arquivo e monitorar a leitura do arquivo, disponibilizar a tarefa via WCF para que o monitor possa 'pesquisar' por alterações, usar a rede ...

Para evitar reinventar a roda, dê uma olhada nos destinos de log do log4net. Se eu implementasse algo assim, provavelmente usaria o log4net e o log no UDP ou Telnet e teria o monitor na outra extremidade conectado. O log4net cuida de tudo para você, incluindo não lançar exceções quando não houver um monitor ativo.

JDT
fonte
Eu acho que estou indo para ir com esta resposta, porque já usamos log4net para bem .. log :) :) Portanto, isso se encaixaria muito bem com o que ele tem. Eu não tinha idéia do log4net poderia fazer isso! Obrigado
Robert Snyder
9

Pelos seus comentários, vejo que você tem um banco de dados cliente / servidor disponível e o seu remetente já tem uma conexão e acesso de gravação? Provavelmente seria mais fácil adicionar uma tabela de "monitoramento" ou "status" ao banco de dados e permitir que o remetente relate seu progresso lá (registre cada etapa "interessante", provavelmente as 5 etapas listadas acima).

Para visualizar o status, crie um segundo programa com a GUI, que se conecta ao banco de dados e exibe o status (por exemplo, pesquisando em intervalos de 1 minuto). Você pode executar esse programa na área de trabalho local, desde que seja possível conectar-se ao banco de dados a partir daí.

É claro que, ao gravar em uma tabela de status, interfira com as transações do banco de dados, você poderá usar uma conexão separada. Você também pode utilizar um mecanismo de fila de mensagens, como o MSQM , mas isso pode ser uma solução enorme para o seu caso simples.

Doc Brown
fonte
+1 Essa é a melhor abordagem para simplificar e não complicar demais algo que não deve ser muito complexo.
Thomas Stringer
3

Apenas para desenvolver a resposta do @ JDT, uma maneira comum de fazer isso é escrever mensagens em uma fila de mensagens. Sempre que algo importante acontece no seu aplicativo, ele grava uma mensagem e a envia para a fila de mensagens. Normalmente, o formato da mensagem é XML ou semelhante. É o escritor da fila.

O aplicativo de monitoramento lê (leitor de fila) a fila e seleciona as mensagens e as processa, salvando-as e analisando a mensagem versus mensagens ou condições anteriores. Se uma condição for atendida, o aplicativo de monitoramento emitirá um alerta, indicando um problema em potencial.

Isso desacopla seu aplicativo do monitoramento próprio, pois está apenas disparando mensagens. Cabe ao aplicativo de monitoramento determinar quando, com base nas mensagens atuais, algo de bom ou ruim aconteceu. As filas são usadas porque oferecem um bom meio de armazenar as mensagens sem perda.

Você deseja centralizar as mensagens se houver várias instâncias do seu aplicativo em execução. Se houver apenas 1 instância, o uso de outros armazenamentos, como o log de eventos do Windows ou um arquivo, pode ser suficiente.

Jon Raynor
fonte