Agente Java que coleta dados de hardware (CPU, GPU e memória) usando o LibreHardwareMonitor e os publica em uma fila RabbitMQ para consumo remoto. Roda em segundo plano com ícone na system tray do Windows, com pico de 70 MB de RAM e 1% máximo de CPU.
O agente é responsável por:
- Iniciar o LibreHardwareMonitor.exe automaticamente como processo filho.
- Consumir o endpoint HTTP local (
http://localhost:8085/data.json) exposto pelo LHM via Feign + Jackson. - Mapear dinamicamente os JsonPointers dos sensores configurados (temperatura de CPU/GPU, carga de CPU e uso de memória) percorrendo a árvore JSON do LHM.
- Publicar leituras periódicas (a cada 1 segundo) na fila
MinhaFilado RabbitMQ (CloudAMQP). - Exibir status através de um ícone na system tray e logs coloridos no console.
A arquitetura é orientada a eventos, usando SubmissionPublisher<AppEvent<?>> do Java Flow API para desacoplar
produção, consumo, logging e visualização.
PROJETINHO/
├── LibreHardwareMonitor/ # Binário do LibreHardwareMonitor + DLLs
│ └── LibreHardwareMonitor.exe
└── SISTEMA/ # Aplicação Java (Maven)
├── pom.xml
└── src/main/java/com/fernandoprado/lhmagent/
├── Main.java
├── Controller/
│ ├── client/LhmClient.java # Cliente Feign do LHM
│ ├── core/LhmProcessManager.java # Inicia/encerra o processo do LHM
│ ├── enviroment/EnvConfiguration.java # Carrega .env (dotenv)
│ ├── logger/ # Logging com cores ANSI
│ ├── messaging/ # Conexão e envio ao RabbitMQ
│ ├── model/ # AppEvent, Sensor
│ ├── service/ # MainService, HardwareBusca, HardwareFinder
│ └── threads/ # MainThread + GetThread
└── view/
├── TrayView.java # Ícone na system tray
└── ViewPrint.java # Saída no console
| Camada | Tecnologia |
|---|---|
| Linguagem | Java 23 |
| Build | Maven (maven-assembly-plugin para fat-jar) |
| HTTP Client | OpenFeign 13.2.1 + feign-jackson |
| JSON | Jackson Databind 2.17.0 |
| Mensageria | RabbitMQ (amqp-client 5.20.0) — CloudAMQP |
| Configuração | dotenv-java 3.0.0 |
| Logging | Logback 1.5.3 + SLF4J |
| Acesso nativo | JNA / JNA-Platform 5.14.0 |
| TUI (lib.) | Lanterna 3.1.5 |
| Coleta de hardware | LibreHardwareMonitor (binário externo) |
- Java 23 (JDK)
- Maven 3.6+
- Windows (a system tray e o LibreHardwareMonitor.exe são dependências de plataforma)
- Acesso à internet para o broker CloudAMQP (ou um RabbitMQ local)
Crie um arquivo .env ao lado do .jar (ou na raiz, se executado pela IDE). Todas as chaves possuem valor padrão,
então o arquivo é opcional.
# RabbitMQ
RABBITMQ_HOST=localhost
RABBITMQ_URI=amqps://usuario:senha@host.cloudamqp.com/vhost
# Identificação do agente
AGENT_ID=default-agent
# URL do LibreHardwareMonitor (HTTP server interno)
LHM_CLIENT_URL=http://localhost:8085
# Palavras-chave dos sensores no LHM (devem bater com o "Text" do JSON)
CPU_TEMP_KEYWORD=Core (Tctl/Tdie)
GPU_TEMP_KEYWORD=GPU Hot Spot
CPU_LOAD_KEYWORD=CPU Total
MEMORY_USAGE=MemoryOs keywords mudam conforme o fabricante (Intel/AMD, NVIDIA/AMD GPU). Abra
http://localhost:8085/data.jsoncom o LHM rodando para descobrir oTextexato de cada sensor.
Importante: o LHM precisa estar configurado para expor o servidor web na porta 8085. Em
LibreHardwareMonitor.exe→ Options → Remote Web Server → Run (porta 8085).
A partir da pasta SISTEMA/:
mvn clean packageIsso gera, em SISTEMA/target/:
SISTEMA-1.0-SNAPSHOT.jar— sem dependênciasSISTEMA-1.0-SNAPSHOT-jar-with-dependencies.jar— uber-jar executável
O agente espera encontrar a pasta LibreHardwareMonitor/ no diretório atual de execução, pois o LhmProcessManager
invoca:
new ProcessBuilder("LibreHardwareMonitor/LibreHardwareMonitor.exe");Layout recomendado de execução:
<pasta-de-execucao>/
├── LibreHardwareMonitor/
│ └── LibreHardwareMonitor.exe
├── SISTEMA-1.0-SNAPSHOT-jar-with-dependencies.jar
└── .env (opcional)
Rodar:
java -jar SISTEMA-1.0-SNAPSHOT-jar-with-dependencies.jarMaininstanciaMainServicee chamainitProgram().MainService:- Cria um
SubmissionPublisher<AppEvent<?>>central. - Inicializa
ViewPrint,TrayView,MessagingServiceeLogServicecomo consumers do publisher. - Inicia o processo do LibreHardwareMonitor via
LhmProcessManager.startLhm(). - Faz polling até o endpoint
/data.jsonresponder (com até 10 tentativas). - Repassa o JSON inicial para
MainThread.start(node).
- Cria um
HardwareBuscapercorre a árvore JSON e gera umMap<String, JsonPointer>com o caminho para cada sensor configurado.MainThreadagenda execução a cada 1 s; cada tick dispara oGetThread, que:- Chama o LHM via Feign.
- Lê valores atuais com
HardwareFinder.lerValoresAtuais(...). - Publica um
AppEventdo tipoUPDATEcom oMap<String, String>no publisher.
MessagingServiceconsome eventosUPDATE, serializa em JSON com Jackson e publica emMinhaFilaviachannel.basicPublish.TrayViewatualiza o tooltip do ícone conforme eventosOK/ERROR.LogServiceimprime logs coloridos no console (ERROR,WARN,OK) com timestamp e nome da classe.
| Tipo | Uso |
|---|---|
INIT |
Estado inicial do GetThread |
UPDATE |
Carrega payload Map<String,String> para o RabbitMQ |
OK / ERROR |
Estado de saúde para a TrayView |
LOG_OK / LOG_WARN / LOG_ERROR |
Eventos consumidos pelo LogService |
WARN |
Reservado |
O encerramento limpo é feito pelo menu CLOSE do ícone na system tray:
RabbitMQProvider.closeConnection();
LhmProcessManager.closeLhm();
System.exit(0);Também é acionado automaticamente caso o agente não consiga conectar ao LHM em até 10 tentativas.
ERRO AO CONECTAR AO LHM: verifique se o servidor web do LibreHardwareMonitor está habilitado na porta8085.FALHA AO DECLARAR CONEXAO COM RABBIT: valide aRABBITMQ_URIe a conectividade com o CloudAMQP.- Sensores não aparecem: ajuste as
*_KEYWORDno.envpara casar exatamente com o campoTextdodata.jsondo LHM. TRAY VIEW NAO SUPORTADO: ambiente sem suporte a system tray (servidor headless, alguns Linux sem libs). O agente continua funcionando, apenas sem o ícone.- Build falhando com versão de Java: o
pom.xmlestá fixado emmaven.compiler.source/target = 23. Ajuste para a sua JDK ou instale a 23.
Fernando Prado — com.fernandoprado.lhmagent
- 💼 LinkedIn: fernando-prado21
- 🐙 GitHub: FernandoPPrado