Customiser le monitoring des ressources Weblogic avec JMX

Malgré la richesse des consoles Weblogic, il est parfois utile d’intégrer le monitoring de Weblogic dans des systèmes Tiers (ex : Nagios, BMC, Jira, …).

Pour cela, WebLogic Server fournit des interfaces (MBeans) basées sur des normes qui sont entièrement conformes à la spécification Java Management Extensions (JMX).

Les éditeurs de logiciels peuvent utiliser ces interfaces pour surveiller les MBeans WebLogic Server, pour modifier la configuration d’un domaine WebLogic Server et pour surveiller l’état des ressources du domaine.

Chaque domaine WebLogic Server comprend trois types de serveurs MBean, chacun donnant accès à différentes hiérarchies MBean :

Domain Runtime MBean Server :

MBeans pour les services à l’échelle du domaine. Ce serveur MBean sert également de point d’accès unique pour les MBeans résidant sur des serveurs gérés.

Runtime MBean Server :

MBeans qui permettent la surveillance, le contrôle d’exécution et la configuration à chaud d’une instance WebLogic Server spécifique.

Edit MBean Server :

MBeans pour les opérations qui contrôlent la configuration d’un domaine WebLogic Server. Il expose un ConfigurationManagerMBean pour verrouiller, enregistrer et activer les modifications.

Les MBeans sont regroupés dans 3 sous-systèmes :

Domain and Server Logging Configuration

Regroupe les MBeans pour la gestion et la configuration du système de journalisation des serveurs Weblogic

JMS Server and JMS System Module Configuration

Regroupe les MBeans pour la gestion et la configuration du serveurs JMS, des Modules JMS et de leurs ressources

JDBC Resource Configuration

Regroupe les MBeans pour la gestion et la configuration du Data Sources JDBC.

Dans la pratique, il est nécessaire d’initier une connexion avec le MBean Server avant de pouvoir gérer les ressources Weblogic via les APIs JMX.

Il est possible d’établir une connexion de type local ou à distance avec le serveur MBean. 

Ci-dessous un exemple de code java pour initier une connexion au MBean server :

public class MyConnection {

    private static MBeanServerConnection connection;

   private static JMXConnector connector;

   private static final ObjectName service;

   /*

   * Initialize connection to the Domain Runtime MBean Server.

   */

   public static void initConnection(String hostname, String portString,

     String username, String password) throws IOException,

     MalformedURLException {

      String protocol = « t3 »;

     Integer portInteger = Integer.valueOf(portString);

     int port = portInteger.intValue();

     String jndiroot = « /jndi/ »;

     String mserver = « weblogic.management.mbeanservers.domainruntime »;

     JMXServiceURL serviceURL = new JMXServiceURL(protocol, hostname, port,

     jndiroot + mserver);

 

     Hashtable h = new Hashtable();

     h.put(Context.SECURITY_PRINCIPAL, username);

     h.put(Context.SECURITY_CREDENTIALS, password);

     h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES,

         « weblogic.management.remote »);

     h.put(« jmx.remote.x.request.waiting.timeout », new Long(10000));

     connector = JMXConnectorFactory.connect(serviceURL, h);

     connection = connector.getMBeanServerConnection();

   }

    public static void main(String[] args) throws Exception {

     String hostname = args[0];

     String portString = args[1];

     String username = args[2];

     String password = args[3];

      MyConnection c= new MyConnection();

     initConnection(hostname, portString, username, password);

     connector.close();

   }

}

Ci-dessous un exemple de code java afin de pouvoir gérer les Data Sources Weblogic via les APIs JMX :

package weblogic.services.DataSource;

 

import java.io.IOException;

import java.net.MalformedURLException;

import java.util.Enumeration;

import java.util.Hashtable;

import java.util.Properties;

import javax.management.MBeanServerConnection;

import javax.management.ObjectName;

import javax.management.remote.JMXConnector;

import javax.management.remote.JMXConnectorFactory;

import javax.management.remote.JMXServiceURL;

import javax.naming.Context;

 

public class DSHandler {

   

    // TODO Auto-generated method stub

    private static MBeanServerConnection connection;

    private static JMXConnector connector;

    private static final ObjectName service = null;

    ObjectName[] atnProviders = null;

    ObjectName mBeanTypeService = null;

 

    //This method creates a WebLogic connection  Object

    public static void initConnection(String hostname, String portString,String username, String password) throws IOException, MalformedURLException {

 

        String protocol = « t3 »;

        Integer portInteger = Integer.valueOf(portString);

        int port = portInteger.intValue();

        String jndiroot = « /jndi/ »;

        String mserver = « weblogic.management.mbeanservers.domainruntime »;

        JMXServiceURL serviceURL = new JMXServiceURL(protocol, hostname, port, jndiroot + mserver);

 

        Hashtable h = new Hashtable();

       

        h.put(Context.SECURITY_PRINCIPAL, username);

        h.put(Context.SECURITY_CREDENTIALS, password);

        h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES, « weblogic.management.remote »);

        h.put(« jmx.remote.x.request.waiting.timeout », new Long(10000));

        connector = JMXConnectorFactory.connect(serviceURL, h);

        connection = connector.getMBeanServerConnection();

       

      }

 

    public static ObjectName[] getServerRuntimes() throws Exception {

        ObjectName service =

            new ObjectName(« com.bea:Name=DomainRuntimeService,Type=weblogic.management.mbeanservers.domainruntime.DomainRuntimeServiceMBean »);

        return (ObjectName[]) connection.getAttribute(service, « ServerRuntimes »);

    }

 

    public static void shutdownDataSource(String dsName, String hostname, String portString,String username, String password) throws Exception {

         initConnection(hostname, portString,username, password);

         ObjectName[] serverRT = getServerRuntimes();

         System.out.println(« ############################################################ »);

         System.out.println(« ################# shutting down data source :  » + dsName);

         System.out.println(« ############################################################ »);

         for (int i = 0; i < serverRT.length; i++) {

             String name = (String) connection.getAttribute(serverRT[i], « Name »);

             System.out.println(« ################# currect server name :  » + name);

             ObjectName[] connectionPools =

                 (ObjectName[]) connection.getAttribute(new ObjectName(« com.bea:Name= » + name + « ,ServerRuntime= » +

                                                                       name + « ,Location= » + name +

                                                                       « ,Type=JDBCServiceRuntime »),

                                                                       « JDBCDataSourceRuntimeMBeans »);

            

             System.out.println(« ################# before cheking data sources » );

             int pool_length = connectionPools.length;

            

             for (int x = 0; x < pool_length; x++) {

                 System.out.println(« ############## current DS =  » + connection.getAttribute(connectionPools[x], « Name »));

                 if ( (connection.getAttribute(connectionPools[x], « Name »)).equals(dsName) )  {

                     connection.invoke(connectionPools[x], »shutdown »,null,null);

                     System.out.println(« Name =  » + connection.getAttribute(connectionPools[x], « Name ») +  » was shutdown from OSB on  » + name);

                 }

             }

         }   

     }

    public static void printDataSources(String hostname, String portString,String username, String password) throws Exception {

        initConnection(hostname, portString,username, password);

        ObjectName[] serverRT = getServerRuntimes();

       

        System.out.println(« ############################################################ »);

        System.out.println(« ################# Printing Data Sources : « );

        System.out.println(« ############################################################ »);

 

        for (int i = 0; i < serverRT.length; i++) {

            System.out.println(« Server Instance= » + serverRT[i]);

            String name = (String) connection.getAttribute(serverRT[i], « Name »);

            ObjectName[] connectionPools =

                (ObjectName[]) connection.getAttribute(new ObjectName(« com.bea:Name= » + name + « ,ServerRuntime= » +

                                                                      name + « ,Location= » + name +

                                                                      « ,Type=JDBCServiceRuntime »),

                                                                      « JDBCDataSourceRuntimeMBeans »);

            int pool_length = connectionPools.length;

            for (int x = 0; x < pool_length; x++) {

                System.out.println(« Name =  » + connection.getAttribute(connectionPools[x], « Name »));

            }

        }

    }

}

En conclusion, cette fonctionnalité de Weblogic est très utile pour implémenter un système de monitoring personnalisé. Ce choix peut se justifier pour pallier les insuffisances des consoles Weblogic en terme d’alertes et de notification.
Il est aussi souvent pratique de centraliser le monitoring de l’infrastructure du SI, les APIs JMX Weblogic permettent d’intégrer la surveillance des ressources Weblogic dans une console globale.