javaloggingwildflyslf4jjboss-cli

How to change WildFly logging levels programatically from within deployed application


I am currently running WildFly 23, and I want to force a certain log level when my application is deployed in it. Meaning that, if someone were to go into the standalone.xml file and change the log level to something else, the application would detect it and change it back to the level I want.

The detecting part is easy, but I'm having trouble setting it back. I work with slf4j and it does not have a setLevel method. I could do it by importing the log4j dependency and change the level through log4j's setLevel method, but I do not want to import specific logger library dependencies, I'd like to stay only with slf4j.

I could also do it through jboss-cli commands, but that requires running a separate script, which could be manually modified as well, so I wanted to do it programatically from inside the code.

I have searched a lot for a way to do this but have not found anything that could help me out. Does anyone have any idea on how one would go about doing that, if it is even possible?

Thank you very much!


Solution

  • As James said in his answer, you should probably avoid doing this, but in my case I had to do it because of regulatory rules.

    Here is how I solved it ...

    Wildfly Client dependency:

    <!-- https://mvnrepository.com/artifact/org.wildfly.core/wildfly-controller-client -->
    <dependency>
        <groupId>org.wildfly.core</groupId>
        <artifactId>wildfly-controller-client</artifactId>
        <version>18.1.1.Final</version>
    </dependency>
    

    Programmatic execution of jboss-cli commands in the Wildfly:

    //First we find out the WildFly parameters
    String hostname = (String) ManagementFactory.getPlatformMBeanServer().getAttribute(new ObjectName("jboss.as:interface=public"), "inet-address");
    Integer managementPort = (Integer) ManagementFactory.getPlatformMBeanServer().getAttribute(new ObjectName("jboss.as:socket-binding-group=standard-sockets,socket-binding=management-http"), "port");
    Integer portOffset = (Integer) ManagementFactory.getPlatformMBeanServer().getAttribute(new ObjectName("jboss.as:socket-binding-group=standard-sockets"), "port-offset");
    
    //Then we create the client using the parameters obtained above
    try (ModelControllerClient client = ModelControllerClient.Factory.create(hostname, managementPort+portOffset)) {
        //Creates the change log level operation
        ModelNode op = new ModelNode();
        op.get("operation").set("change-root-log-level");
        //Writes the way to the root logger that will be changed
        ModelNode addr = op.get("address");
        addr.add("subsystem", "logging");
        addr.add("logging-profile", "myApp"); //myApp is my logging-profile name, yours will be different!
        addr.add("root-logger", "ROOT");
        //Makes the level change
        op.get("level").set("INFO");
        //Executes the operation
        ModelNode returnVal = client.execute(op);
        
        //If you want, you can log the results
        if(logger.isInfoEnabled()) {
            logger.info("Execution results:");
            logger.info("Outcome: {}", returnVal.get("outcome"));
            logger.info("Result: {}", returnVal.get("result"));
        }
    }