13 Monitoramento JMX

Visão geral

O monitoramento JMX pode ser usado para monitorar os contadores JMX de uma aplicação Java.

O monitoramento JMX tem suporte nativo no Zabbix por meio de um daemon chamado "Zabbix Java Gateway", introduzido desde o Zabbix 2.0.

Para recuperar o valor de um contador JMX específico em um host, o servidor Zabbix consulta o Java gateway, que, por sua vez, usa a JMX management API para consultar remotamente a aplicação de interesse.

Para mais detalhes e configurações, consulte a seção Zabbix Java gateway.

A comunicação entre o Java Gateway e a aplicação JMX monitorada não deve ser bloqueada por firewall.

Habilitando o monitoramento remoto JMX para uma aplicação Java

Uma aplicação Java não precisa de software adicional instalado, mas precisa ser iniciada com as opções de linha de comando especificadas abaixo para ter suporte ao monitoramento remoto JMX.

Como mínimo necessário, se você deseja começar monitorando uma aplicação Java simples em um host local sem segurança habilitada, inicie-a com estas opções:

java \
       -Dcom.sun.management.jmxremote \
       -Dcom.sun.management.jmxremote.port=12345 \
       -Dcom.sun.management.jmxremote.authenticate=false \
       -Dcom.sun.management.jmxremote.ssl=false \
       -Dcom.sun.management.jmxremote.registry.ssl=false \
       -jar /usr/share/doc/openjdk-6-jre-headless/demo/jfc/Notepad/Notepad.jar

Isso faz com que o Java escute conexões JMX recebidas na porta 12345, apenas no host local, e indica que não é necessário autenticação ou SSL.

Se você deseja permitir conexões em outra interface, defina o parâmetro -Djava.rmi.server.hostname para o IP dessa interface.

Se você quiser ser mais rigoroso em relação à segurança, há muitas outras opções disponíveis no Java. Por exemplo, o próximo exemplo inicia a aplicação com um conjunto de opções mais versátil e a abre para uma rede mais ampla, não apenas para o host local.

java \
       -Djava.rmi.server.hostname=192.168.3.14 \
       -Dcom.sun.management.jmxremote \
       -Dcom.sun.management.jmxremote.port=12345 \
       -Dcom.sun.management.jmxremote.authenticate=true \
       -Dcom.sun.management.jmxremote.password.file=/etc/java-6-openjdk/management/jmxremote.password \
       -Dcom.sun.management.jmxremote.access.file=/etc/java-6-openjdk/management/jmxremote.access \
       -Dcom.sun.management.jmxremote.ssl=true \
       -Dcom.sun.management.jmxremote.registry.ssl=true \
       -Djavax.net.ssl.keyStore=$YOUR_KEY_STORE \
       -Djavax.net.ssl.keyStorePassword=$YOUR_KEY_STORE_PASSWORD \
       -Djavax.net.ssl.trustStore=$YOUR_TRUST_STORE \
       -Djavax.net.ssl.trustStorePassword=$YOUR_TRUST_STORE_PASSWORD \
       -Dcom.sun.management.jmxremote.ssl.need.client.auth=true \
       -jar /usr/share/doc/openjdk-6-jre-headless/demo/jfc/Notepad/Notepad.jar

A maioria (senão todas) dessas configurações pode ser especificada no arquivo /etc/java-6-openjdk/management/management.properties (ou onde quer que esse arquivo esteja no seu sistema).

Observe que, se você quiser usar SSL, será necessário modificar o script de inicialização (startup.sh), adicionando as opções -Djavax.net.ssl.* ao gateway Java, para que ele saiba onde encontrar os arquivos de key store e trust store.

Para uma descrição mais detalhada, consulte Monitoramento e gestão usando o JMX.

Configurando interfaces e itens JMX no Zabbix Frontend

Com o Java Gateway em execução, o Server tendo conhecimento de onde o encontrar e uma aplicação Java iniciada com suporte a monitoramento JMX remoto, é hora de configurar as interfaces e itens no GUI do Zabbix.

Configurando interface JMX

Você começa criando uma interface do tipo JMX no host de interesse.

Todos os campos obrigatórios estão marcados com um asterisco vermelho.

Adicionando item de agente JMX

Para cada contador JMX no qual você está interessado, você adiciona um item do agente JMX associado a essa interface.

A chave na captura de tela abaixo diz jmx["java.lang:type=Memory","HeapMemoryUsage.used"].

Todos os campos obrigatórios estão marcados com um asterisco vermelho.

Os campos que requerem informações específicas para itens JMX são:

Tipo Defina como agente JMX aqui.
Chave A chave do item jmx[] contém três parâmetros:
nome do objeto - o nome do objeto de um MBean
nome do atributo - um nome de atributo MBean com nomes de campo de dados compostos opcionais, separados por pontos
descrição curta e única - uma descrição única que permite vários itens JMX com o mesmo nome de objeto e nome de atributo no host (opcional)
Veja abaixo mais detalhes sobre as chaves de itens.
Desde o Zabbix 3.4, você pode descobrir MBeans e atributos MBean usando um item de descoberta de baixo nível jmx.discovery[] low-level discovery.
JMX endpoint Você pode especificar um endpoint JMX personalizado. Certifique-se de que os parâmetros de conexão do endpoint JMX correspondam à interface JMX. Isso pode ser feito usando macros {HOST.*} , como feito no endpoint JMX padrão.
Este campo é suportado desde a versão 3.4.0. As macros {HOST.*} macros e macros de usuário são suportados.
Nome do usuário Especifique o nome de usuário, se você tiver configurado autenticação na sua aplicação Java.
Macros do usuário são suportadas.
Senha Especifique a senha, se você tiver configurado autenticação na sua aplicação Java.
Macros de usuário são suportados.

Se você quiser monitorar um contador Booleano que é "true" ou "false", então você especifica o tipo de informação como "Numérico (sem sinal)" e seleciona o passo de pré-processamento "Booleano para decimal" na aba de Pré-processamento. O servidor armazenará valores Booleanos como 1 ou 0, respectivamente.

Chaves de item JMX em mais detalhes

Atributos simples

Um nome de objeto MBean é nada senão uma string que você define em sua aplicação Java. Um nome de atributo, por outro lado, pode ser mais complexo. No caso de o atributo retornar um tipo de dado primitivo (um inteiro, uma string, etc.), não há nada com o que se preocupar, a chave se parecerá com esta:

jmx[com.example:Type=Hello,weight]

Neste exemplo temos um nome de objeto "com.example:Type=Hello", o nome de atributo é "weight" e provavelmente o tipo de valor retornado deve ser "Numérico (float)".

Atributos que retornam dados compostos

Fica mais complicado quando o seu atributo retorna dados compostos. Por exemplo: o nome do seu atributo é "apple" e ele retorna um hash representando seus parâmetros, como "weight", "color", etc. Sua chave pode se parecer com isso:

jmx[com.example:Type=Hello,apple.weight]

É assim que um nome de atributo e uma chave de hash são separados, usando um ponto. Da mesma forma, se um atributo retornar dados compostos aninhados, as partes são separadas por um ponto:

jmx[com.example:Type=Hello,fruits.apple.weight]
Atributos que retornam dados tabulares

Atributos de dados tabulares consistem em um ou múltiplos atributos compostos. Se tal atributo for especificado no parâmetro do nome do atributo, então o valor desse item retornará a estrutura completa do atributo em formato JSON. Os valores dos elementos individuais dentro do atributo de dados tabulares podem ser recuperados usando pré-processamento.

Exemplo de atributo de dados tabulares:

 jmx[com.example:type=Hello,foodinfo]

Valor do item:

[
         {
           "a": "apple",
           "b": "banana",
           "c": "cherry"
         },
         {
           "a": "potato",
           "b": "lettuce",
           "c": "onion"
         }
       ]
Problema com pontos

Até aqui tudo bem. Mas e se o nome de um atributo ou uma chave de hash conter o símbolo de ponto? Aqui está um exemplo:

jmx[com.example:Type=Hello,all.fruits.apple.weight]

Isso é um problema. Como informar ao Zabbix que o nome do atributo é "all.fruits", e não apenas "all"? Como distinguir um ponto que faz parte do nome de um ponto que separa o nome do atributo e as chaves de hash?

Antes da versão 2.0.4, o Java gateway não conseguia lidar com tais situações, e os usuários ficavam com itens NÃO SUPORTADOS. Desde a versão 2.0.4, isso é possível; basta escapar os pontos que fazem parte do nome com uma barra invertida:

jmx[com.example:Type=Hello,all\.fruits.apple.weight]

Da mesma forma, se sua chave de hash conter um ponto, basta escapá-lo:

jmx[com.example:Type=Hello,all\.fruits.apple.total\.weight]
Outros problemas

Um caractere de barra invertida no nome de um atributo deve ser escapado:

jmx[com.example:type=Hello,c:\\documents]

Para lidar com quaisquer outros caracteres especiais na chave de item JMX, consulte a seção sobre o formato da chave de item section.

Isso é tudo! Bom monitoramento JMX!

Tipos de dados não primitivos

Desde o Zabbix 4.0.0 é possível trabalhar com MBeans personalizados que retornam tipos de dados não primitivos e que substituem o método toString()

Usando endpoint personalizado com JBoss EAP 6.4

Endpoints personalizados permitem trabalhar com protocolos de transporte diferentes do RMI padrão.

Para ilustrar essa possibilidade, vamos configurar o monitoramento do JBoss EAP 6.4 como exemplo. Primeiramente, vamos fazer algumas suposições:

  • O Zabbix Java gateway já está instalado. Caso contrário, você pode instalá-lo de acordo com a documentation.
  • O servidor Zabbix e o Java gateway estão instalados com o prefixo /usr/local/
  • O JBoss já está instalado em /opt/jboss-eap-6.4/ e está em execução no modo standalone
  • Vamos assumir que todos esses componentes funcionam no mesmo host
  • Firewall e SELinux estão desativados (ou configurados adequadamente)

Vamos fazer algumas configurações simples em zabbix_server.conf:

JavaGateway=127.0.0.1
       StartJavaPollers=5

E no arquivo de configuração zabbix_java/settings.sh (ou zabbix_java_gateway.conf):

START_POLLERS=5

Verifique se o JBoss está ouvindo sua porta de gerenciamento padrão:

$ netstat -natp | grep 9999
       tcp        0      0 127.0.0.1:9999          0.0.0.0:*               LISTEN      10148/java

Agora vamos criar um host com a interface 127.0.0.1:9999 no Zabbix.

Sabendo que essa versão do JBoss usa o protocolo JBoss Remoting em vez de RMI, podemos atualizar o parâmetro do endpoint JMX para os itens em nosso template JMX da seguinte forma:

service:jmx:remoting-jmx://{HOST.CONN}:{HOST.PORT}

Vamos atualizar o cache de configuração:

/usr/local/sbin/zabbix_server -R config_cache_reload

Note que pode ocorrer um erro inicialmente.

"Unsupported protocol: remoting-jmx" significa que o Java gateway não sabe como trabalhar com o protocolo especificado. Isso pode ser corrigido criando um arquivo ~/needed_modules.txt com o seguinte conteúdo:

jboss-as-remoting
       jboss-logging
       jboss-logmanager
       jboss-marshalling
       jboss-remoting
       jboss-sasl
       jcl-over-slf4j
       jul-to-slf4j-stub
       log4j-jboss-logmanager
       remoting-jmx
       slf4j-api
       xnio-api
       xnio-nio

e, em seguida, executando o comando:

for i in $(cat ~/needed_modules.txt); do find /opt/jboss-eap-6.4 -iname "${i}*.jar" -exec cp '{}' /usr/local/sbin/zabbix_java/lib/ \; ; done

Assim, o Java gateway terá todos os módulos necessários para trabalhar com jmx-remoting. O que resta é reiniciar o Java gateway, aguardar um pouco e, se tudo foi feito corretamente, ver que os dados de monitoramento JMX começam a chegar ao Zabbix (veja também: Latest data).