Blogue ·
Um incidente que o silêncio nunca fecha
Um incidente de monitorização abre com uma medição e fecha com outra. Eis o que se parte quando a ausência de dados passa a contar como boa notícia.
Por Provibr
Todos os sistemas de monitorização acabam por enfrentar a mesma pergunta com um disfarce ligeiramente diferente: o que fazer quando as medições deixam de chegar?
A resposta tentadora é tratar isso como recuperação. Já nada está a falhar, a linha vermelha desaparece, o painel fica calmo. É também a mentira mais cara que o sistema consegue contar, porque o momento em que se deixa de conseguir olhar para uma coisa é exatamente o momento em que não se pode afirmar que ela está bem.
Este é o desenho a que chegámos para os incidentes, e a maior parte dele consiste em manter «medimos que está avariado», «medimos que está reparado» e «neste momento não conseguimos ver» como três afirmações separadas que nunca se transformam em silêncio umas nas outras.
Porque é que o incidente é um objeto
Antes disto, uma interrupção era uma série de linhas numa tabela de transições de estado. Isso chega para desenhar um gráfico e não chega para dizer o que quer que seja. Três coisas só existem a partir do momento em que há um objeto.
Uma duração. A mensagem de recuperação não transportava duração nenhuma, porque não havia com que preencher o parâmetro. Um incidente tem um princípio, portanto a duração é uma medição e não uma estimativa.
Uma camada humana. Reconhecer, atribuir e fechar à mão são coisas que as pessoas fazem, e não podem tocar no estado medido. Uma coluna acknowledged_at numa medição baralharia exatamente a linha sobre a qual toda esta funcionalidade está construída.
Desduplicação ao longo do tempo. Uma notificação quando abre, lembretes com relógio próprio, no máximo um escalonamento. Sem um objeto não há onde pendurar o «já lhe dissemos», e então cada tique é mais uma oportunidade para o voltar a dizer.
A desduplicação é um índice
A unicidade que impede a existência de dois incidentes para uma regra é um índice único parcial sobre a regra, onde o carimbo temporal da resolução é nulo. Dois gateways a processar a mesma transição produzem um incidente por construção; o segundo apanha uma violação de unicidade e segue caminho.
Código que verifica se já existe um e depois insere são duas instruções, o que são duas oportunidades para alguma coisa se intrometer pelo meio. É a mesma forma que o índice de intervalos do escalonador e o índice de ocupação de bastidores noutros pontos deste produto, e pela mesma razão.
Houve aqui também um erro genuinamente embaraçoso, que vale a pena registar porque é invisível numa revisão. A chave de desduplicação da notificação era construída a partir da regra, do estado novo e do carimbo temporal atual. Uma chave que contém o carimbo temporal atual não desduplica nada, por construção, e no ecrã parece perfeitamente razoável. Agora é o identificador do incidente. Medido depois: três falhas consecutivas produzem um incidente e uma notificação, e mais três não mudam nada.
Três formas de um incidente terminar, e só uma é uma medição
| Resolução | O que afirma | O que fica registado com ela |
|---|---|---|
recovered | medimos outra vez um estado saudável | o resultado que o fechou, guardado na cronologia |
configuration_retired | a regra que abriu isto já não mede | nenhuma, e nenhuma é afirmada |
manual | uma pessoa fechou-o | quem, e opcionalmente porquê |
A do meio é a razão de ser da lista. Uma regra que é substituída pela revisão de um modelo tem de fechar os incidentes que tem abertos, e tem de o fazer sem uma medição falsa de recuperação. Se a única resolução disponível fosse recovered, substituir um modelo escreveria em silêncio «isto voltou a subir» no histórico de todos os serviços que estivessem em baixo nessa altura.
Não existe deliberadamente uma resolução stale. O facto de as medições terem deixado de chegar não diz nada sobre o alvo.
Que transições chegam sequer a tocar num incidente
Um incidente pende de uma afirmação sobre o alvo. Por isso uma transição para «fonte indisponível», ou seja, o nosso próprio agente foi-se embora, não abre nada e, mais importante ainda, não fecha nada. Se um agente que se ausenta pudesse fechar um incidente, uma interrupção em curso desapareceria da vista exatamente no momento em que perdemos a capacidade de olhar para ela.
Uma transição para «erro de configuração» comporta-se da mesma maneira: a regra já não descreve nada de mensurável, o que é uma afirmação sobre nós e não sobre o serviço.
«Degradado» fecha, sim, um incidente. O serviço está a responder, a condição conta como saudável, só a latência é alta. Deixá-lo aberto faria de um serviço lento uma interrupção permanentemente aberta, lembretes incluídos.
Por baixo disto, vindo de uma ronda anterior, está uma distinção dura entre uma fonte inalcançável e um alvo que está em baixo. Uma verificação cujo agente não está ligado produz «fonte indisponível» e nunca «em baixo». Tudo o que está acima é essa mesma regra, uma camada acima.
A manutenção silencia notificações e continua a medir
Uma janela de manutenção suprime notificações. Não suprime a medição. O incidente continua a abrir, a cronologia continua a correr, e só a mensagem fica na gaveta.
Isso não é um pormenor. A pergunta que as pessoas fazem depois de uma janela de manutenção é «voltou a horas», e essa pergunta fica sem resposta se se parou de medir enquanto isso importava. Existe uma caixa de verificação separada e explícita que suspende mesmo as verificações, e está desligada por predefinição; com ela, o escalonador não reclama o intervalo, portanto nada fica em atraso e nada é perdido. O que fica depois é uma única marca de lacuna, igual à de qualquer outra lacuna. Não há recuperação do atrasado.
A janela em si é guardada como um intervalo absoluto com um fuso horário IANA ao lado. O cliente introduz a hora do relógio de parede e quer voltar a lê-la como a mesma hora de relógio de parede, ainda que o painel apresente as datas num fuso fixo. Guardar a hora de parede mais o fuso obrigaria todos os leitores, escalonador, ingestão e ecrã por igual, a refazer a conversão, e então uma mudança para a hora de verão passa a ser uma hora de desacordo entre dois deles.
Onde duas janelas se sobrepõem, ganha a que suspende as verificações. Quando um cliente fez explicitamente em algum lado a escolha mais restritiva, é essa a escolha a honrar.
Lembretes, escalonamento e a ordem de duas instruções
Tanto o intervalo dos lembretes como o atraso do escalonamento vivem na revisão da regra e não no incidente, porque são configuração e a configuração pertence à revisão que a registou. Mude a política durante uma interrupção e o incidente em curso continua sob a política com que abriu.
Ambos estão desligados por predefinição. Uma predefinição que acorda pessoas de noite é uma decisão que o cliente não tomou.
Reconhecer silencia os lembretes, e essa é a função inteira de reconhecer. Quem diz «estou a tratar disto» não deve ser interrompido a cada poucos minutos. A notificação de recuperação continua a chegar, porque é a resposta à pergunta que a pessoa estava a acompanhar. O relógio dos lembretes corre também a partir do último lembrete e não do início, pelo que um trabalhador a recuperar atrasos ao fim de uma hora não entrega doze lembretes de uma vez.
O trabalhador escreve primeiro o carimbo temporal e envia a mensagem depois, e a atualização exige que o estado continue a ser aquele que leu. Perdida essa corrida, aqui não acontece nada. Na ordem inversa, uma corrida perdida produz uma mensagem sem registo dela, e depois a mensagem volta a chegar na ronda seguinte.
O escalonamento acontece no máximo uma vez por incidente, e a verificação disso vive na regra partilhada e não no trabalhador. Sem ela, cada passagem escreveria mais um evento de escalonamento durante todo o tempo que a interrupção durasse: trinta por hora com uma sondagem de dois minutos.
O flapping é a exceção, e é decidido quando o incidente abre: três incidentes sobre a mesma regra dentro de uma hora. Uma verificação em flapping, por definição, nunca tem um incidente que fique aberto muito tempo, portanto qualquer escalonamento baseado no tempo falha-a para sempre. Três e não dois, porque duas vezes é azar e um limiar de dois chamaria flapping a todos os reinícios normais de um serviço. Uma hora e não um dia, porque três interrupções espalhadas por um dia de trabalho são três interrupções.
A duração é um número e uma unidade
A mensagem de recuperação transporta quanto tempo durou, como valor e unidade, nunca como frase. Se fosse o trabalhador a compor «1 hour 12 minutes», esse fragmento em inglês ficaria no meio de uma frase traduzida em oito outros idiomas. O que viaja em vez disso é uma unidade pela qual a tradução seleciona, com um plural dentro de cada ramo.
Uma unidade, sem compostos: um composto precisa de um separador e de uma ordem, e essas diferem de idioma para idioma. Segundos abaixo de um minuto, minutos até duas horas, horas até dois dias, dias a partir daí. Noventa minutos lê-se de forma mais nítida do que duas horas, e arredondar para cima faria uma interrupção de 89 minutos durar duas.
Duas consequências honestas que não corrigimos
Em baixo, recuperado e lembrete partilham uma chave de agrupamento de notificações, porque um lembrete é literalmente o mesmo assunto outra vez e deve atualizar a linha existente em vez de acrescentar uma sempre que o relógio dispara. O custo é que um lembrete atualiza uma linha que alguém já leu, e é portanto invisível para essa pessoa. O escalonamento tem um grupo próprio exatamente por esta razão: a mensagem que tem de cair com mais força não pode ser a primeira a ser sobrescrita. As notificações de monitorização não saem hoje por correio eletrónico.
O que registaríamos
- Nunca deixar a ausência de dados fechar seja o que for. Dê ao «não conseguimos ver» um estado próprio e garanta que não abre nem fecha um incidente.
- Dar ao incidente um objeto assim que se quiser uma duração, um reconhecimento ou uma segunda mensagem sobre a mesma coisa.
- Pôr a desduplicação num índice único, e verificar que a chave de notificação não contém a hora atual.
- Enumerar como um incidente pode terminar, e exigir prova apenas onde há prova afirmada.
- Suprimir notificações durante a manutenção, não medições, e fazer da suspensão das verificações uma escolha separada, explícita e desligada por predefinição.
- Atualizar o estado e só depois enviar a mensagem. A ordem inversa perde mensagens em silêncio.
Este trabalho está atrás de uma bandeira de lançamento desligada por predefinição, portanto nada disto é algo que se possa comprar hoje. Está escrito como método e não como anúncio. A camada de medição por baixo dele, incluindo a razão pela qual um agente inalcançável não é um serviço em falha, é uma história à parte, e a questão muito próxima de quando é que uma plataforma pode sequer indicar um tempo está em uma barra de progresso que se recusa a adivinhar.
Do trabalho de plataforma no Provibr.