web-dev-qa-db-fra.com

Comment créer un appender personnalisé dans log4j2?

Comme indiqué dans ce lien: Comment créer un propre Appender dans log4j?

Pour créer un appender personnalisé dans log4j 1.x, nous devons étendre la classe AppenderSkeleton et implémenter sa méthode append.

De même, nous pouvons créer un appender personnalisé dans log4j2, car nous n'avons pas de classe AppenderSkelton à étendre et tous les autres appender étendent une classe AppenderBase.

40
saurabh goyal

Cela fonctionne assez différemment dans log4j2 que dans log4j-1.2.

Dans log4j2, vous créeriez un plugin pour cela. Le manuel contient une explication avec un exemple pour un appender personnalisé: http://logging.Apache.org/log4j/2.x/manual/extending.html#Appenders

Il peut être pratique d’étendre org.Apache.logging.log4j.core.appender.AbstractAppender, mais cela n’est pas obligatoire.

Lorsque vous annotez votre classe Appender personnalisée avec @Plugin(name="MyCustomAppender", ...., le nom du plug-in devient le nom de l'élément de configuration. Ainsi, une configuration avec votre appender personnalisé ressemblerait alors à ceci:

<Configuration packages="com.yourcompany.yourcustomappenderpackage">
  <Appenders>
    <MyCustomAppender name="ABC" otherAttribute="...">
    ...
  </Appenders>
  <Loggers><Root><AppenderRef ref="ABC" /></Root></Loggers>
</Configuration>

Notez que l'attribut packages de la configuration est une liste séparée par des virgules de tous les packages avec les plugins log4j2 personnalisés. Log4j2 recherchera ces classes dans le chemin de classe pour les classes annotées avec @Plugin.

Voici un exemple d'appender personnalisé qui s'imprime sur la console:

package com.yourcompany.yourcustomappenderpackage;

import Java.io.Serializable;
import Java.util.concurrent.locks.*;
import org.Apache.logging.log4j.core.*;
import org.Apache.logging.log4j.core.config.plugins.*;
import org.Apache.logging.log4j.core.layout.PatternLayout;

// note: class name need not match the @Plugin name.
@Plugin(name="MyCustomAppender", category="Core", elementType="appender", printObject=true)
public final class MyCustomAppenderImpl extends AbstractAppender {

    private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
    private final Lock readLock = rwLock.readLock();

    protected MyCustomAppenderImpl(String name, Filter filter,
            Layout<? extends Serializable> layout, final boolean ignoreExceptions) {
        super(name, filter, layout, ignoreExceptions);
    }

    // The append method is where the appender does the work.
    // Given a log event, you are free to do with it what you want.
    // This example demonstrates:
    // 1. Concurrency: this method may be called by multiple threads concurrently
    // 2. How to use layouts
    // 3. Error handling
    @Override
    public void append(LogEvent event) {
        readLock.lock();
        try {
            final byte[] bytes = getLayout().toByteArray(event);
            System.out.write(bytes);
        } catch (Exception ex) {
            if (!ignoreExceptions()) {
                throw new AppenderLoggingException(ex);
            }
        } finally {
            readLock.unlock();
        }
    }

    // Your custom appender needs to declare a factory method
    // annotated with `@PluginFactory`. Log4j will parse the configuration
    // and call this factory method to construct an appender instance with
    // the configured attributes.
    @PluginFactory
    public static MyCustomAppenderImpl createAppender(
            @PluginAttribute("name") String name,
            @PluginElement("Layout") Layout<? extends Serializable> layout,
            @PluginElement("Filter") final Filter filter,
            @PluginAttribute("otherAttribute") String otherAttribute) {
        if (name == null) {
            LOGGER.error("No name provided for MyCustomAppenderImpl");
            return null;
        }
        if (layout == null) {
            layout = PatternLayout.createDefaultLayout();
        }
        return new MyCustomAppenderImpl(name, filter, layout, true);
    }
}

Pour plus de détails sur les plugins: http://logging.Apache.org/log4j/2.x/manual/plugins.html

Si le manuel ne suffit pas, il peut être utile de consulter le code source des ajouts intégrés dans log4j-core.

71
Remko Popma

Il semble que les extensions de plug-ins sont analysées au démarrage et ne peuvent pas être ajoutées lors de l'exécution. Est-ce vrai?

pour ajouter un nouvel appender en cours d’exécution, vous pouvez utiliser la propriété monitorInterval pour mettre à jour la configuration du journal, c'est-à-dire toutes les 60 secondes:

    <Configuration monitorInterval="60">
1
Javoslaw

Pour que les utilisateurs aient besoin de sortir vers TextArea, voici un tweak qui fonctionne

Rendre le TextArea statique

NetBeans Swing TextArea n'est pas statique, pose problème

Ajouter une méthode statique dans votre cadre

public class MyFrame extends javax.swing.JFrame {
    ...
    public static void outputToTextArea(String message) {
        jTextArea.append(message);
    }

Appeler dans l'appendeur

@Override
public void append(LogEvent event) {
    final byte[] bytes = getLayout().toByteArray(event);
    MyFrame.outputToTextArea(new String(bytes));
}
0
pppk520