6 Replies Latest reply on Apr 20, 2018 11:52 AM by oislas

    How to write wildfly cluster-specific information to a log file

    oislas

      I'm using WildFly 12 to make a cluster in domain mode and I want to create a custom log which only writes useful information about the cluster, something like the following:

      1. How many hosts registered to the cluster
      2. Which hosts are currently available and not available
      3. When a node goes down, who went down and who picked up the load

      It's information like this that I want to have in a separate log file.

      I've found information but i'm confused, for example this blog uses a custom java class to retrieve data from CLI, but I can't figure out how to get information about which node in the cluster went down and who picked up the load.

      I've also read about the logging subsystem but i'm not sure how to go about a custom log that only writes the data that I want I just know how to get configuration information but don't know about information that is triggered after something happens with the servers.
      So do I need to configure a custom handler in java or do I need to configure just the logging subsystem to have an extra log file? In which case I still can't figure out how to write only the data that I want.

      Any hints or information about how to approach this would be appreciated, Thank you!.

        • 1. Re: How to write wildfly cluster-specific information to a log file
          oislas

          I've been researching since I asked this question and I found out about the "clustering public API" and i'm trying to use it.

           

          I'm creating a java class called ClusterListener that implements the GroupListener interface of the public API.

          So far i'm able to create a log file in the path that I want but for some reason the log is empty. I'll keep researching and reading about it to see what I have wrong.

           

          If anyone sees this and has some examples or tips, feel free to tell me. Thank you.

          • 2. Re: How to write wildfly cluster-specific information to a log file
            oislas

            An update about this.

             

            I still can't really fix this but I've been able to use the clustering api to create a class that implements the GroupListener interface, it's supposed to be listening to every change in the cluster topology, at least according to documentation and an example in the WildFly Github project.

             

            However, despite that a cluster.log file is created, its empty. I can't figure out why exactly but i'll keep trying.

             

            If anyone has a clue please let me know. I'll let my code here, the class in which I implemented the GroupListener interface as well as the module.xml that I created and the changes made to the logging subsystem in domain.xml

             

             

            Class that implements GroupListener interface

             

            package com.matco.logger;
            
            
            import java.util.List;
            import javax.ejb.Singleton;
            import javax.ejb.Startup;
            import org.jboss.logging.Logger;
            import org.wildfly.clustering.group.GroupListener;
            import org.wildfly.clustering.group.Membership;
            import org.wildfly.clustering.group.Node;
            
            
            
            @Singleton
            @Startup
            public class ClusterListener implements GroupListener
            
            
            
                private static final Logger LOG = Logger.getLogger(ClusterListener.class);
            
            
                @Override
                public void membershipChanged(Membership previousMembership, Membership newMembership, boolean merged)
                {
            
            
                    List previousNodes = previousMembership.getMembers();
            
            
                    LOG.infof("========================================");
                    LOG.infof("= Information about the previous nodes =");
                    for (Node node : previousNodes)
                    {
                        LOG.infof("Node name: " + node.getName());
                        LOG.infof("Node address: " + node.getSocketAddress());
                    }
                    LOG.infof("========================================");
            
            
                    List newNodes = newMembership.getMembers();
            
            
                    LOG.infof("========================================");
                    LOG.infof("=== Information about the new nodes ====");
                    for (Node node : newNodes)
                    {
                        LOG.infof("Node name: " + node.getName());
                        LOG.infof("Node address: " + node.getSocketAddress());
                    }
                    LOG.infof("========================================");
            
            
                    LOG.infof("Are they merged?: " + merged);
                    LOG.infof("========================================");
                }
            }

             

            module.xml to implement a custom logging module

             

            <?xml version="1.0" encoding="UTF-8"?>
            <module xmlns="urn:jboss:module:1.0" name="com.matco.logger">
                 <resources>
                       <resource-root path="ClusterLogger.jar"/>
                 </resources>
                 <dependencies>
                      <module name="org.jboss.logging"/>
                      <module name="javax.api"/>
                      <module name="org.wildfly.clustering"/>
                 </dependencies>
            </module>
            

             

            Configuration in domain.xml

             

            <size-rotating-file-handler name="CLUSTER-LOG">
              <formatter>
              <named-formatter name="CLUSTER-PATTERN"/>
              </formatter>
              <file relative-to="jboss.home.dir" path="cluster.log"/>
              <rotate-size value="10m"/>
              <suffix value=".yyyy-MM-dd"/>
            </size-rotating-file-handler>
            ...
            <logger category="com.cluster.logger">
              <level name="TRACE"/>
              <handlers>
              <handler name="CLUSTER-LOG"/>
              </handlers>
            </logger>
            ...
            <formatter name="CLUSTER-PATTERN">
              <pattern-formatter pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
            </formatter>

             

            Thanks in advance if anyone can help.

            • 3. Re: How to write wildfly cluster-specific information to a log file
              pferraro

              You just need to register your listener with a Group.

              e.g.

              @Singleton  
              @Startup  
              public class ClusterListener implements GroupListener {
                  @Resource(lookup = "java:jboss/clustering/group/default")
                  private Group group;
                  private Registration registration;
              
                  @PostConstruct
                  public void init() {
                      this.registration = this.group.register(this);
                  }
              
                  @PreDestroy
                  public void destroy() {
                      this.registration.close();
                  }
                  // Listener implementation
              }
              • 4. Re: How to write wildfly cluster-specific information to a log file
                oislas

                Hello, Paul, and thank you for your answer

                 

                I didn't update on this matter because its still not resolved but I did register the listener as you pointed out, and the log messages that are in the @PostConstruct and @PreDestroy methods are writen to server.log instead of cluster.log, however the listener still doesn't log any messages that I put.

                 

                As of right know i'm no longer trying to test with a custom module but instead i'm just deploying my application to my cluster.

                 

                I really have no idea what's the problem.

                 

                I'll leave my class here. I appretiate that you can take the time to take a look and tell me if something is wrong.

                 

                package src.main.java.com.matco.cluster.logger;
                
                import java.util.List;
                import java.util.logging.Logger;
                import javax.annotation.PostConstruct;
                import javax.annotation.PreDestroy;
                import javax.annotation.Resource;
                import javax.ejb.Singleton;
                import javax.ejb.Startup;
                import org.wildfly.clustering.Registration;
                import org.wildfly.clustering.group.Group;
                import org.wildfly.clustering.group.GroupListener;
                import org.wildfly.clustering.group.Membership;
                import org.wildfly.clustering.group.Node;
                
                
                /**
                *
                * @author Oscar I. Islas
                */
                @Singleton
                @Startup
                public class ClusterLogger implements GroupListener
                {
                
                
                    private static final Logger LOG = Logger.getLogger(ClusterLogger.class.toString());
                
                
                    @Resource(lookup = "java:jboss/clustering/group/default")
                    private Group channelGroup;
                
                
                    private Registration channelRegistration;
                
                
                    @PostConstruct
                    public void registerListener()
                    {
                        this.channelRegistration = this.channelGroup.register(this);
                        LOG.info("Channel group registered! ===================================");
                    }
                
                
                    @PreDestroy
                    public void destroyListener()
                    {
                        this.channelRegistration.close();
                        LOG.info("Channel registration destroyed! =============================");
                    }
                
                
                    @Override
                    public void membershipChanged(Membership previousMembership, Membership newMembership, boolean merged)
                    {
                        LOG.info("===========================================================");
                        LOG.info("Printing previous members of the cluster topology");
                        List previousNodes = previousMembership.getMembers();
                        for (Node previousNode : previousNodes)
                        {
                            LOG.info(previousNode.getName() + ":" + previousNode.getSocketAddress());
                        }
                
                
                        LOG.info("===========================================================");
                        LOG.info("Printing new members of the cluster topology");
                        List newNodes = newMembership.getMembers();
                        for (Node previousNode : newNodes)
                        {
                            LOG.info(previousNode.getName() + ":" + previousNode.getSocketAddress());
                        }
                
                
                        LOG.info("===========================================================");
                        LOG.info("Are the merged? " + merged);
                        LOG.info("===========================================================");
                        LOG.info("===========================================================");
                
                
                        LOG.info("=================== Membership changed ====================");
                        LOG.info("Channel Coordinator?: " + channelGroup.getMembership().isCoordinator());
                        LOG.info("Channel Coordinator name: " + channelGroup.getMembership().getCoordinator().getName());
                    }
                }

                 

                Thank you for the help!

                • 5. Re: How to write wildfly cluster-specific information to a log file
                  pferraro

                  I assume you already defined a separate logger for this class (via the logging subsystem) that uses a distinct file-handler (that writes to a separate file)?

                  To which profile is your server group associated? e.g. default, full, ha, etc.  Only the "ha" profiles have clustering enabled.

                  • 6. Re: How to write wildfly cluster-specific information to a log file
                    oislas

                    Hello, Paul

                     

                    Yes I already defined a separate logger as a size rotating file handler and my server group is associated with the full-ha profile, this is my configuration in domain.xml in the full-ha profile

                     

                    <size-rotating-file-handler name="CLUSTER-LOG" autoflush="true">
                         <formatter>
                              <named-formatter name="CLUSTER-PATTERN"/>
                         </formatter>
                         <file relative-to="jboss.home.dir" path="cluster.log"/>
                         <rotate-size value="10m"/>
                         <suffix value=".yyyy-MM-dd"/>
                    </size-rotating-file-handler>
                    ...
                    <logger category="org.infinispan" use-parent-handlers="false">
                         <level name="TRACE"/>
                         <handlers>
                              <handler name="CLUSTER-LOG"/>
                         </handlers>
                    </logger>
                    ...
                    <formatter name="CLUSTER-PATTERN">
                         <pattern-formatter pattern="%K{level}%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
                    </formatter>
                    

                     

                    Note that "category="org.infinispan" is only there because I wanted to see if that would actually log to the correct file and it does. Its just that when I want to use my own listener it doesn't work.

                    I used to have my module configuration in the category, which was "com.matco.logger" but that didn't work.

                    Is there something else that I should configure?

                     

                    Thanks for the help.