MÓDULO 2.2

🩺 Operar no dia a dia

Diagnóstico, logs e o que fazer quando quebra: doctor e doctor --deep, journal e dashboard, /health, /status e /usage, os alertas com dedupe, o backup noturno e o procedimento de quebra.

6
Tópicos
45
Minutos
Técnico
Nível
Prático
Tipo
Progresso do módulo 2.2 0%
0 de 0
1

🔎 doctor e doctor --deep: config contra realidade

São dois diagnósticos diferentes com o mesmo comando. O npm run doctor lê configuração e ambiente: arquivos, variáveis, RAM, modelos do Ollama, CLIs, units do systemd, banco, conectores. Ele não muda nada e não chama o LLM. Já o npm run doctor -- --deep acrescenta quatro probes que exercitam o sistema de verdade, cada um marcado como probe para você reconhecer que o efeito colateral foi seu.

npm run doctor · só lê .env v3 e .env v2 RAM e swap modelos do Ollama claude e codex units v2 e v3, banco --deep · quatro probes que atravessam o sistema 1. GET /healtho serviço responde 2. sendMessagechega no seu chat 3. roteador via gatewayOllama responde 4. job doctor-probelane io, 30 s

Legenda: a faixa tracejada de cima é inofensiva e pode rodar a qualquer hora. A faixa sólida de baixo manda mensagem no Telegram e enfileira um job de verdade, por isso cada linha vem com o rótulo deep:.

✓ O que o doctor comum responde

  • Falta key, falta arquivo, falta modelo: .env v2 (keys compartilhadas), config/ollama.yaml, modelo roteador.
  • A máquina aguenta: RAM mostra GB disponíveis, total, swap usado e o piso para carregar modelo grande.
  • Coexistência sã: v2 ativo, v3 unit, v3 MemoryMax, mesmo modelo geral que o v2 e ollama serve paralelo.

✗ O que só o --deep pega

  • Serviço no ar mas com binário antigo: o job doctor-probe não é reconhecido e a linha diz "serviço antigo sem a tarefa doctor-probe? reinstale".
  • Token válido no arquivo mas o bot não entrega: só o sendMessage real mostra isso.
  • Modelo listado no tags mas travado: o probe chama o papel roteador pelo gateway e espera texto de volta.

Copie e rode: diagnóstico raso e diagnóstico profundo

Objetivo: ver a foto da configuração e, em seguida, provar que o caminho inteiro funciona de ponta a ponta.

cd ~/projetos/openpcbotv3
npm run doctor
npm run doctor -- --deep

Como verificar: a última linha diz Tudo crítico OK ou quantas falhas críticas existem, e o processo sai com código 1 quando há alguma. No --deep, as quatro linhas começam com deep: e trazem o tempo medido, por exemplo job #123 done em 900 ms. Uma mensagem com 🩺 e a palavra probe chega no seu Telegram: é o teste, não um alerta.

Dica prática

O --deep precisa do serviço no ar: sem ele, a linha da fila sai como "pulado: serviço fora do ar" e conta como falha crítica. A ordem que economiza tempo é sempre a mesma: doctor primeiro, resolver o que estiver ❌, e só então --deep. O probe do Ollama grava em banco de memória e não entra em chamadas_llm, então diagnosticar não suja o seu relatório de custo.

2

📜 Journal e dashboard: as duas janelas do serviço

O v3 registra em log estruturado (pino, JSON) e tudo vai para o journal do systemd do usuário. Para leitura humana, o -o cat tira o carimbo do systemd e deixa só a linha do processo. A segunda janela é o dashboard em http://127.0.0.1:3142/, que mostra health, Ollama e RAM, fila por lane, custo dos últimos 14 dias com sparkline, custo por tier e por agente, memória e jobs recentes, atualizando a cada 10 s.

1

Acompanhe ao vivo

Enquanto manda uma mensagem

journalctl --user -u openpcbotv3 -f -o cat segue o log. É a forma de ver o caminho da mensagem acontecendo: canal, roteador, fila, resposta.

2

Olhe para trás

Depois de um erro

journalctl --user -u openpcbotv3 -n 50 --no-pager -o cat mostra as últimas 50 linhas sem abrir o paginador. É o comando que o CLAUDE.md do repo indica para diagnóstico.

3

Veja o conjunto

No navegador

O dashboard junta o que o log só conta linha a linha. Com DASHBOARD_TOKEN_V3 definido, / e /api/* passam a exigir o segredo; o /health continua aberto porque o hub wifi consome esse endpoint.

Copie e rode: log ao vivo e health cru

Objetivo: confirmar que o processo está vivo e ler o estado sem depender do Telegram.

systemctl --user is-active openpcbotv3
curl -s http://127.0.0.1:3142/health
journalctl --user -u openpcbotv3 -n 50 --no-pager -o cat

Como verificar: o primeiro comando responde active. O curl devolve JSON com ok, fila, modelos, RAM e orçamento. O journal termina nas linhas mais recentes do processo. Se a porta estiver mudada no .env, troque 3142 pelo valor de <seu-PORT_V3>.

Escutar só em casa é o padrão

O HTTP escuta em 127.0.0.1 por padrão porque POST /mensagem dispara agente com as permissões da sua máquina. Expor na rede local só faz sentido com os dois juntos: HTTP_BIND_V3=0.0.0.0 e DASHBOARD_TOKEN_V3 preenchido. Um sem o outro é dashboard aberto para quem estiver no mesmo Wi-Fi.

3

📊 /health, /status e /usage: ler fila, Ollama, RAM e custo

Três comandos no chat cobrem a operação inteira sem sair do Telegram. O /health responde saúde, o /status responde trabalho e o /usage responde dinheiro. Vale saber o que é "saudável" para o v3: o GET /health devolve ok quando o Ollama está online, a RAM livre está em 10 GB ou mais e o heartbeat rodou há menos de 90 minutos.

ComandoO que devolveQuando usar
/healthOllama (modelos carregados e latência), RAM e swap, RSS do processo, fila, heartbeat, canaisO bot está lento ou mudo
/statusFila por lane: o que está rodando e o que está pendentePedi algo e não voltou
/status <id-do-job>Detalhe de um job, com resultado ou erroUm job específico falhou
/usageCusto de hoje, da semana e do mês, por tier e por agente, mais o orçamentoAntes de pedir algo caro
/ollama statusEstado do gestor do OllamaSuspeita de modelo descarregado
/dailyTarefas, feitas nas últimas 24 h, custo do dia, fila, Ollama, MEMORY.mdComeço do dia, às 8h também sai sozinho

Legenda: as lanes que aparecem no /status são chat (concorrência 2), agente (1), ollama (1), cron (1) e io (4). Job nunca é apagado: a fila é o histórico.

Copie e rode: a mesma leitura sem o Telegram

Objetivo: ler saúde e custo pela linha de comando, útil quando o canal do Telegram é justamente o que está quebrado. O npm run cli fala com o serviço no ar por POST /mensagem, e comando iniciado por barra é tratado igual em qualquer canal.

cd ~/projetos/openpcbotv3
npm run cli -- "/health"
npm run cli -- "/usage"

Como verificar: a saída é o mesmo texto que o bot mandaria no chat. No /health, confira RAM disponível e heartbeat; no /usage, o total do mês contra o ORCAMENTO_MENSAL_USD. Se o serviço estiver fora do ar, o CLI avisa que o v3 não respondeu na porta; com DASHBOARD_TOKEN_V3 definido, ele manda o segredo sozinho.

Dica prática

Quando o /status mostrar algo preso, prefira operar a fila a reiniciar o serviço: /cancelar <id-do-job> tira o job sem corrida e /prioridade <id-do-job> <número> reordena o que ainda não começou. Restart é remédio de último caso, porque o drain gracioso espera até 110 s antes de abortar o que está em curso.

4

🔔 Alertas no Telegram e o dedupe de 30 minutos

O v3 avisa sozinho no chat permitido quando algo sai do lugar, e cada alerta tem uma chave própria com dedupe de 30 minutos: a mesma condição não vira dez mensagens seguidas. São sete gatilhos, e cada um tem uma resposta esperada de você.

Ollama fora RAM baixa lease morto job zumbi 3 falhas em 1 h orçamento 70 % orçamento 100 % dedupe por chave janela de 30 min chat permitido ALLOWED_CHAT_ID

Legenda: sem ALLOWED_CHAT_ID definido, o próprio doctor avisa que os alertas no Telegram estão desligados. O alerta não substitui o log: ele diz que olhar, o journal diz o que houve.

✓ Resposta certa ao alerta

  • Ollama fora: cheque o serviço do Ollama (systemctl), não suba ollama serve num terminal.
  • RAM baixa: veja quem está residente com /ollama status; descarregar só o que é do v3.
  • Orçamento 70 %: /usage para ver qual tier ou agente puxou, e segure o premium até virar o mês.

✗ Reação que piora

  • Reiniciar o serviço a cada alerta: lease morto e zumbi já são recuperados sozinhos pelo heartbeat de 30 min.
  • Descarregar o modelo grande para liberar RAM sem olhar de quem ele é: o v3 nunca descarrega modelo alheio, e você não deve fazer na mão o que ele evita de propósito.
  • Ignorar o alerta de 3 falhas da mesma tarefa em 1 h: é exatamente o caso que vira linha no FALHAS.md.

Copie e rode: achar o alerta no log

Objetivo: depois de receber um alerta no chat, encontrar no journal a linha que o originou.

journalctl --user -u openpcbotv3 --since "1 hour ago" -o cat | grep -i alerta
journalctl --user -u openpcbotv3 --since today -o cat | grep -i "<palavra-do-alerta>"

Como verificar: as linhas do log são JSON do pino, então cada uma traz o contexto completo do evento. Se o grep não achar nada e o alerta chegou, amplie a janela: o dedupe de 30 min pode ter suprimido as repetições, mas a primeira ocorrência está lá.

5

💾 Backup noturno: VACUUM INTO, cifra e retenção 14

Todo o estado do v3 mora num arquivo SQLite: fila, memórias, custo, preferências. O cron backup-noturno roda às 4h15 e usa VACUUM INTO, que produz uma cópia consistente mesmo com o banco em uso (WAL). Depois cifra com age se AGE_RECIPIENT estiver definido, ou comprime com gzip quando não estiver, e mantém os 14 arquivos mais recentes em store/backups/.

1

Cópia consistente

4h15, lane cron

O arquivo sai com carimbo de data e hora no nome, no formato openpcbotv3-<data-e-hora>.db. Nada é parado para isso: VACUUM INTO escreve um banco novo enquanto o atual segue recebendo escrita.

2

Cifra ou compressão

Com age, ou gzip

Com AGE_RECIPIENT o resultado é .db.age; sem ele, .db.gz. O doctor tem a linha age (backup cifrado) justamente para avisar quando o binário não está instalado e o backup cai para gzip.

3

Retenção de 14

Os mais antigos somem

Depois de gravar, o backup lista os arquivos que começam com openpcbotv3-, ordena do mais novo para o mais velho e apaga o que passar de 14. Se quiser guardar um marco, copie para fora de store/backups/.

Copie e rode: conferir que existe backup de ontem

Objetivo: provar que o cron noturno está de fato gravando, antes de precisar do arquivo.

ls -lht ~/projetos/openpcbotv3/store/backups/ | head -5
npm run cli -- "/cron lista"

Como verificar: o arquivo mais recente deve ser da madrugada passada e terminar em .age ou .gz. A lista nunca passa de 14 itens. No /cron lista, backup-noturno precisa aparecer ligado; /cron off backup-noturno e /cron on backup-noturno desligam e religam.

Restaurar é trocar o arquivo, com o serviço parado

Restaurar quer dizer decifrar ou descomprimir o arquivo escolhido e pôr o banco de volta no lugar apontado por store/, com o serviço parado (systemctl --user stop openpcbotv3) para ninguém escrever no meio. O repo documenta a geração do backup, não uma receita de restauração passo a passo; guarde uma cópia do banco atual antes de sobrescrever qualquer coisa.

6

🚨 Quando quebra: parar, reinstalar, registrar

A ordem importa. Primeiro conter: /parar tudo <motivo> no chat bloqueia novos trabalhos na hora e /retomar libera; o interruptor fica gravado na tabela prefs, então sobrevive a restart. Depois diagnosticar com doctor e journal. Só então reinstalar com bash scripts/instalar-servico.sh, que é build mais restart. E, antes da próxima tarefa, registrar uma linha no FALHAS.md.

Copie e rode: o ciclo de recuperação

Objetivo: voltar de um serviço quebrado para um serviço saudável, na ordem que não perde informação.

cd ~/projetos/openpcbotv3
journalctl --user -u openpcbotv3 -n 50 --no-pager -o cat
npm run doctor
bash scripts/instalar-servico.sh
npm run doctor -- --deep

Como verificar: o script imprime as primeiras linhas do status e o MemoryMax lido do systemd. O serviço precisa terminar em active (running), e o --deep logo depois precisa fechar as quatro linhas de probe sem falha crítica. O restart é sempre com systemctl --user, sem sudo, e não encosta no v2.

✓ Garantias que já existem

  • Unit com Restart=on-failure e RestartSec=5: queda isolada volta sozinha.
  • MemoryHigh=1536M e MemoryMax=2G no cgroup, mais --max-old-space-size=1024 no node: o v3 não come a RAM da máquina.
  • Drain gracioso no SIGTERM: renova o lease enquanto espera e aborta só depois de 110 s.

✗ O que não fazer na coexistência

  • Mudar a tag do papel geral só no v3: viram dois modelos grandes residentes e a máquina vai a OOM.
  • Descarregar um modelo que o v3 não carregou: o /ollama descarregar recusa de propósito.
  • Ligar Slack ou WhatsApp antes do corte: o v2 é dono da sessão e do token.

Uma linha por falha, antes da próxima tarefa

O FALHAS.md na raiz do repo é uma tabela: data, o que quebrou, a menor correção possível e se era problema de prompt ou de infraestrutura. Mais recente no topo, uma linha só, sem narrativa. A coluna que mais ensina é a da menor correção: se a resposta foi reescrever um módulo, provavelmente faltava só uma proteção, um teto ou uma validação.

Duas linhas reais do FALHAS.md

A primeira conversa do v3 falhou com Ollama error 400 porque keep_alive estava como string "-1" no YAML; a correção foi uma só, deixar o número. E o doctor acusava dois ollama serve e porta ocupada com o serviço parado, porque pgrep -f contava o próprio sh -c e um grep -c sem resultado sai com código 1; a correção foi pgrep -c -x e um || true. Duas linhas, dois consertos pequenos, nenhuma reescrita.

Chegou o alerta de RAM baixa e o modelo grande residente é o mesmo que o v2 usa. O que fazer?

Resumo do módulo

doctor - lê config, RAM, modelos, CLIs e units sem mudar nada; --deep acrescenta 4 probes reais e precisa do serviço no ar
Journal e dashboard - journalctl --user -u openpcbotv3 -f -o cat para o vivo; 127.0.0.1:3142 para o conjunto, atualizando a cada 10 s
/health, /status, /usage - saúde, trabalho e dinheiro; ok exige Ollama online, RAM ≥ 10 GB e heartbeat < 90 min
Alertas - 7 gatilhos com dedupe de 30 min por chave, entregues no chat permitido
Backup noturno - 4h15, VACUUM INTO, age ou gzip, retenção 14 em store/backups/
Quando quebra - /parar tudo, journal, doctor, instalar-servico.sh, e uma linha no FALHAS.md antes da próxima tarefa

Próximo módulo:

3.1 - Comandos e conversa