# Log4J Logging über JMX Konfigurieren mit Spring



## Thomas Darimont (10. März 2010)

Hallo,

hier mal ein Beispiel wie man mit Spring das Log4J Logging über JMX Konfigurierbar machen kann:

```
package de.tutorials.workshop.system;

import java.lang.reflect.Field;

import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.jmx.export.annotation.ManagedOperation;
import org.springframework.jmx.export.annotation.ManagedOperationParameter;
import org.springframework.jmx.export.annotation.ManagedOperationParameters;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.stereotype.Component;

@Component
@ManagedResource("de.tutorials.logging:name=Log4JConfigurator")
public class Log4JConfigurator {

  @ManagedOperation
  @ManagedOperationParameters( {
    @ManagedOperationParameter(name = "Logger Name", description = "the qualified logger name"),
    @ManagedOperationParameter(name = "Log-Level", description = "OFF, FATAL, ERROR, WARNING, INFO, DEBUG, TRACE") })
  public void changeLogLevel(String loggerName, String logLevel) {
    
    if(loggerName == null || "String".equalsIgnoreCase(loggerName)){
      return;
    }
    
    Logger logger = LogManager.getLoggerRepository().getLogger(loggerName);
    Level level = parseLevel(logLevel);

    if (level != null) {
      logger.setLevel(level);
    }
    
  }

  protected Level parseLevel(String logLevel) {
    Level level = null;
    for (Field field : Level.class.getDeclaredFields()) {
      if (field.getType().equals(Level.class) && field.getName().equalsIgnoreCase(logLevel)) {
        try {
          level = (Level) field.get(null);
        } catch (Exception e) {
          e.printStackTrace();
        }
        break;
      }
    }
    return level;
  }
}
```

Da ich die Spring Beans nicht extra in der Konfiguration definieren möchte verwende ich eine automatische Konfiguration über Annotations.
In der Spring-Konfiguration definiere ich hierzu:

```
...
    <context:component-scan base-package="de.tutorials" />
    <context:annotation-config />

    <bean id="jmxAttributeSource"
        class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource" />

    <bean id="assembler"
        class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
        <property name="attributeSource" ref="jmxAttributeSource" />
    </bean>

    <bean id="namingStrategy"
        class="org.springframework.jmx.export.naming.MetadataNamingStrategy">
        <property name="attributeSource" ref="jmxAttributeSource" />
    </bean>

    <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"
        lazy-init="false">
        <property name="assembler" ref="assembler" />
        <property name="namingStrategy" ref="namingStrategy" />
        <property name="autodetect" value="true" />
    </bean>
...
```

Seltsamerweise muss man dann, auch unter Java 6, noch die JVM Option -Dcom.sun.management.jmxremote beim Java-Launcher angeben
damit die eigenen MBeans auch in JConsole / jvisualvm erscheinen.



Gruß Tom


----------

