LOG4J Fichier de configuration

De EjnTricks

Le framework LOG4J se configure à l'aide d'un fichier de paramètre au format texte, habituellement log4j.properties, ou XML, fichier log4j.xml.

Traditionnellement le fichier est placé dans le classpath de l'application et tout se déroule correctement. Or dans le cadre d'un projet, il a été demandé de placer ce fichier dans un répertoire qui ne figurait pas dans le classpath. Cet article présente comment il est possible de spécifier l'emplacement du fichier de configuration au démarrage du programme.

Attention, cette analyse a été réalisée sur la version 1.2.17.

Hand-icon.png Votre avis

Nobody voted on this yet

 You need to enable JavaScript to vote


Study icon.png Etude

Il existe beaucoup de fil de discussion sur ce point, mais une petite étude des sources va permettre de comprendre rapidement le mode de fonctionnement. Le projet étant OpenSource, cela va être particulièrement simple. En fait, il suffit de chercher la chaîne log4j.xml, un des fichiers recherchés par défaut, dans les sources et la classe org.apache.log4j.LogManager ressort rapidement.

Dans un premier temps, nous y trouvons trois constantes intéressantes.

  /**
   * @deprecated This variable is for internal use only. It will
   * become package protected in future versions.
   * */
  static public final String DEFAULT_CONFIGURATION_FILE = "log4j.properties";
  
  static final String DEFAULT_XML_CONFIGURATION_FILE = "log4j.xml";  
   
  /**
   * @deprecated This variable is for internal use only. It will
   * become private in future versions.
   * */
  static final public String DEFAULT_CONFIGURATION_KEY="log4j.configuration";

Il suffit donc de chercher où sont elles utilisées et du code statique, exécuté au chargement de la classe, ressort.

  static {
    // By default we use a DefaultRepositorySelector which always returns 'h'.
    Hierarchy h = new Hierarchy(new RootLogger((Level) Level.DEBUG));
    repositorySelector = new DefaultRepositorySelector(h);

    /** Search for the properties file log4j.properties in the CLASSPATH.  */
    String override =OptionConverter.getSystemProperty(DEFAULT_INIT_OVERRIDE_KEY,
						       null);

    // if there is no default init override, then get the resource
    // specified by the user or the default config file.
    if(override == null || "false".equalsIgnoreCase(override)) {

      String configurationOptionStr = OptionConverter.getSystemProperty(
							  DEFAULT_CONFIGURATION_KEY, 
							  null);

      String configuratorClassName = OptionConverter.getSystemProperty(
                                                   CONFIGURATOR_CLASS_KEY, 
						   null);

      URL url = null;

      // if the user has not specified the log4j.configuration
      // property, we search first for the file "log4j.xml" and then
      // "log4j.properties"
      if(configurationOptionStr == null) {	
	url = Loader.getResource(DEFAULT_XML_CONFIGURATION_FILE);
	if(url == null) {
	  url = Loader.getResource(DEFAULT_CONFIGURATION_FILE);
	}
      } else {
	try {
	  url = new URL(configurationOptionStr);
	} catch (MalformedURLException ex) {
	  // so, resource is not a URL:
	  // attempt to get the resource from the class path
	  url = Loader.getResource(configurationOptionStr); 
	}	
      }
      
      // If we have a non-null url, then delegate the rest of the
      // configuration to the OptionConverter.selectAndConfigure
      // method.
      if(url != null) {
	    LogLog.debug("Using URL ["+url+"] for automatic log4j configuration.");
        try {
            OptionConverter.selectAndConfigure(url, configuratorClassName,
					   LogManager.getLoggerRepository());
        } catch (NoClassDefFoundError e) {
            LogLog.warn("Error during default initialization", e);
        }
      } else {
	    LogLog.debug("Could not find resource: ["+configurationOptionStr+"].");
      }
    } else {
        LogLog.debug("Default initialization of overridden by " + 
            DEFAULT_INIT_OVERRIDE_KEY + "property."); 
    }  
  }


Finalement, le chargement de la configuration est rapidement compréhensible et se déroule en quelques étapes.

  • Récupération de la variable d'environnement log4j.configuration. Si celle-ci est renseignée, elle est utilisée pour charger la ressource à l'aide de la classe java.net.URL.
  • Si la valeur fournie ne correspond pas à une URL, c'est considéré comme une resource devant être disponible dans le classpath.
  • Si la variable d'environnement n'est pas positionnée, le fichier log4j.xml est recherché dans le classpath. Si celui-ci n'est pas disponible, le fichier log4j.properties est recherché.


Warning-icon.png Conclusion

Afin de spécifier un emplacement alternatif pour le fichier de configuration, il suffit de positionner la variable d'environnement log4j.configuration. Cependant, cette valeur est chargée à l'aide de la classe java.net.URL. Il est donc impératif de préfixer l'emplacement du fichier par file:. Sinon, le fichier sera recherché dans le classpath de l'application.

Ainsi, la valeur /var/opt/study/log4j/myconf.xml entraînera la recherche du fichier myconf.xml dans le paquet var.opt.study.log4j. Il faut donc spécifier file:/var/opt/study/log4j/myconf.xml.


Examples-icon.png Exemple implémentation

Les variables d'environnement peuvent être positionnées dans la ligne de commande Java pour démarrer l'application. Dans le cadre de l'exemple précédant, celle-ci serait alors la suivante.

#java -Dlog4j.configuration="file:/var/opt/study/log4j/myconf.xml" -cp ... net.jouvinio.study.log4j.MyLogger

net.jouvinio.study.log4j.MyLogger serait la classe de démarrage.


Viewer icon.png Voir aussi

Tout ceci est bien entendu décrit dans le manuel officiel.

Documentation officielle: http://logging.apache.org/log4j/1.2/manual.html


Une version 2.X est disponible du framework. Le mode de fonctionnement est identique, avec plus de format supporté, et la procédure est la même.

Documentation officielle: http://logging.apache.org/log4j/2.x/manual/configuration.html