Sobre o projeto
vitals é um monitor de sistema para Macs com Apple Silicon executando macOS 14 ou posterior. Um único binário em Rust amostra CPU, GPU, memória, energia e estado térmico in-process: não utiliza shell para powermetrics, não requer sudo e não inicia nenhum subprocesso de qualquer tipo. A saída é um JSON estruturado que um script, um agente ou uma pessoa pode ler diretamente. O mesmo binário, executado sem argumentos, também é um item de bandeja na barra de menus com um dashboard local opcional.
Verbos de linha de comando
snapshot imprime uma amostra completa do SoC: chip host e contagem de núcleos, utilização de CPU em todo o sistema, entradas por núcleo com tipo de núcleo (eficiência ou performance), frequência e utilização, utilização e frequência da GPU, totais e uso de memória e swap, pressão de memória do kernel, valores de energia para CPU, GPU, ANE, RAM e sistema, temperaturas de CPU e GPU, velocidades dos ventiladores com máximos, médias de carga, uptime e estado térmico. Uma opção de intervalo altera a janela de amostragem sobre a qual a residência de CPU, GPU e energia são integradas.
top classifica processos por CPU e por memória, de forma independente e com uma contagem de linhas configurável, portanto, o mesmo processo pode aparecer em ambas as listas. A porcentagem de CPU é por processo e não em todo o sistema, podendo exceder 100 em trabalhos multi-core, como no ps.
pressure retorna um veredito em vez de números brutos: um estado, uma flag indicando se existe histórico utilizável, uma lista de razões com códigos e severidades, uma lista de processos suspeitos com a razão pela qual cada um foi sinalizado e um resumo de uma linha. Por design, ele sai com zero ao reportar um estado ruim, pois o reporte não é uma falha. Uma flag de código de saída incorpora a severidade do veredito no status (0 nominal, 3 aviso, 4 crítico), enquanto uma falha de tempo de execução sai com 1 e uma invocação malformada sai com 2.
watch é o único verbo que não sai por conta própria. Ele emite um objeto JSON compacto por linha, descarregado após cada linha, e executa até ser interrompido ou até que o número solicitado de amostras seja emitido. O intervalo define tanto a cadência quanto a janela de amostragem. Como a saída é descarregada por linha, um consumidor que lê uma linha e fecha o pipe obtém uma saída limpa. É sempre JSON delimitado por nova linha e rejeita a flag JSON.
JSON é o padrão para snapshot, top e pressure; cada um também aceita uma forma de texto legível para humanos para terminais, e a flag JSON é aceita como um no-op. Toda resposta carrega uma versão de esquema. As unidades residem nos nomes das chaves (memória em MB, energia em watts, temperaturas em Celsius) em vez de campos separados, e campos opcionais ausentes são omitidos em vez de emitidos como null.
App de barra de menus e dashboard
Executado sem argumentos, o vitals é uma bandeja de barra de menus com texto ao vivo e um menu suspenso personalizado cobrindo CPU (um sparkline mais uma barra por núcleo, núcleos de eficiência e performance coloridos diferentemente), GPU, memória julgada pelo sinal de pressão do kernel e energia. Valores de destaque mudam de cor em limiares, nada é redesenhado enquanto o menu suspenso está fechado e a cadência de amostragem diminui enquanto a tela dorme.
O app se declara como um acessório, portanto não possui ícone no Dock nem entrada no alternador de apps até que uma janela seja solicitada. Um dashboard pode ser aberto a partir do menu suspenso ou reabrindo o app em execução, e abre-se em uma janela nativa suportada por uma web view, como seu próprio processo. Enquanto está aberto, possui um tile no Dock e menu de app; quando fecha, esse processo encerra, mantendo um dashboard fechado com custo zero. Se a bandeja sair ou travar, a janela percebe via monitoramento de descritor de arquivo e encerra prontamente. O servidor HTTP roda dentro do processo da bandeja e inicia sob demanda, portanto, uma bandeja que nunca solicitou o dashboard não possui listener nem segundo amostrador.
A página do dashboard foi construída para ser lida de cima para baixo: o mesmo veredito que o verbo pressure produz, quatro tiles para CPU, GPU, memória e energia com valor de destaque, ponto de status, linha de contexto e tendência, um controle de intervalo para 2, 5 ou 15 minutos que define o escopo de tudo abaixo dele, gráficos de CPU e GPU ao longo do tempo com mira e tooltip, uma barra por núcleo rotulada por posição com velocidade de clock ao passar o mouse, medidores de memória e swap cujo preenchimento segue o sinal de pressão do kernel, e processos top com barras inline. Cada gráfico possui um alternador gráfico-ou-tabela para os mesmos dados, a consulta para quando a página é ocultada, a última renderização válida permanece na tela escurecida se o servidor desaparecer, e o tema claro ou escuro segue o sistema.
Instalação e empacotamento
Dois caminhos de instalação independentes terminam com o vitals no PATH. Um build seguido de um install cria links simbólicos do binário de release em um diretório bin de prefixo (sobrescreva o prefixo para evitar sudo, e um alvo de uninstall remove o link simbólico). O caminho de instalação do app faz o build, empacota, copia o app para a pasta Applications, instala um agente de inicialização por usuário para que a bandeja inicie a cada login e redireciona o mesmo link simbólico para a cópia do bundle; um alvo de uninstall correspondente reverte tudo isso. O bundle é assinado ad-hoc em vez de notarizado, o que é suficiente para a execução do agente de inicialização; abrir o app via Finder pode exigir um clique com o botão direito em Abrir ou aprovação nas Ajustes do Sistema.
Desenvolvimento
Build, teste, clippy-com-avisos-como-erros e formatação possuem alvos de make. O dashboard é um app Vite e React cujo output de build de produção é incorporado ao binário em tempo de compilação, portanto, o binário deve ser reconstruído após a página. Um servidor de dev com hot reload faz proxy de requisições de API para a porta local, funcionando contra qualquer instância em execução, incluindo a da bandeja.
A contribuição ocorre via relatórios de bugs, medições e pull requests, com um canal separado para vulnerabilidades. O projeto possui licença MIT.
Comments
0 Rating appears after 10 ratings
Sign in to join the discussion.