Como criar um plug-in appender de arquivo contínuo no log4j2

Eu quero criar um aplicativo de arquivo de log4j2 personalizado. Preciso criar esse appender personalizado, pois quero agrupar o evento de log log4j com algumas informações exclusivas do meu aplicativo. Como userId, nome do aplicativo hospedado.

Eu tenho uma classe que estende Log4jLogEvent implementa LogEvent. Esta classe tem informações que eu preciso agrupar com o evento de log. Por favor, veja este código:

public class CustomLogEvent extends Log4jLogEvent implements LogEvent {

private String userId;
private String applicationName;

private static final long serialVersionUID = 1L;

public CustomLogEvent(String loggerName, Marker marker, String loggerFQCN, Level level, Message message, Throwable t, Map<String, String> mdc, ThreadContext.ContextStack ndc, String threadName, StackTraceElement location, long timestamp){
    super(loggerName,marker,loggerFQCN,level,message,t,mdc,ndc,threadName,location,timestamp);
}
         //Getters and setters for user Id and app name
}

No log4j2, uma vez que não podemos estender o appender de arquivo móvel, como fizemos com o log4j 1.2, criei um novo aplicativo de arquivo móvel vendo o código-fonte do aplicativo de arquivo móvel original. Esta classe estende AbstractOutputStreamAppender.

Este é o código que eu escrevi para o aplicativo rollender de arquivos.

@Plugin(name = "MyRollingFileAppender", category = "Core", elementType = "appender", printObject = true)
public class MyRollingFileAppender extends AbstractOutputStreamAppender<RollingFileManager> {

private static final int DEFAULT_BUFFER_SIZE = 8192;
private static final long serialVersionUID = 1L;

private final String fileName;
private final String filePattern;
private Object advertisement;
private final Advertiser advertiser;


private MyRollingFileAppender(final String name, final Layout<? extends Serializable> layout, final Filter filter,
                            final RollingFileManager manager, final String fileName, final String filePattern,
                            final boolean ignoreExceptions, final boolean immediateFlush, final Advertiser advertiser) {
    super(name, layout, filter, ignoreExceptions, immediateFlush, manager);
    if (advertiser != null) {
        final Map<String, String> configuration = new HashMap<String, String>(layout.getContentFormat());
        configuration.put("contentType", layout.getContentType());
        configuration.put("name", name);
        advertisement = advertiser.advertise(configuration);
    }
    this.fileName = fileName;
    this.filePattern = filePattern;
    this.advertiser = advertiser;
}


@Override
public void append(final LogEvent logEvent) {

    int userId = //get user Id

    String appplicatinName = //get application name

    GetLoggingEvent myLogEvent = new GetLoggingEvent();

    LogEvent customLogEvent = myLogEvent.getCustomLogEvent(logEvent, userId, applicationName);
    getManager().checkRollover(customLogEvent);
    super.append(customLogEvent);
}

@PluginFactory
public static MyRollingFileAppender createAppender(
        @PluginAttribute("fileName") final String fileName,
        @PluginAttribute("filePattern") final String filePattern,
        @PluginAttribute("append") final String append,
        @PluginAttribute("name") final String name,
        @PluginAttribute("bufferedIO") final String bufferedIO,
        @PluginAttribute("bufferSize") final String bufferSizeStr,
        @PluginAttribute("immediateFlush") final String immediateFlush,
        @PluginElement("Policy") final TriggeringPolicy policy,
        @PluginElement("Strategy") RolloverStrategy strategy,
        @PluginElement("Layout") Layout<? extends Serializable> layout,
        @PluginElement("Filter") final Filter filter,
        @PluginAttribute("ignoreExceptions") final String ignore,
        @PluginAttribute("advertise") final String advertise,
        @PluginAttribute("advertiseURI") final String advertiseURI,
        @PluginConfiguration final Configuration config) {

    final boolean isAppend = Booleans.parseBoolean(append, true);
    final boolean ignoreExceptions = Booleans.parseBoolean(ignore, true);
    final boolean isBuffered = Booleans.parseBoolean(bufferedIO, true);
    final boolean isFlush = Booleans.parseBoolean(immediateFlush, true);
    final boolean isAdvertise = Boolean.parseBoolean(advertise);
    final int bufferSize = Integers.parseInt(bufferSizeStr, DEFAULT_BUFFER_SIZE);
    if (!isBuffered && bufferSize > 0) {
        LOGGER.warn("The bufferSize is set to {} but bufferedIO is not true: {}", bufferSize, bufferedIO);
    }
    if (name == null) {
        LOGGER.error("No name provided for FileAppender");
        return null;
    }

    if (fileName == null) {
        LOGGER.error("No filename was provided for FileAppender with name "  + name);
        return null;
    }

    if (filePattern == null) {
        LOGGER.error("No filename pattern provided for FileAppender with name "  + name);
        return null;
    }

    if (policy == null) {
        LOGGER.error("A TriggeringPolicy must be provided");
        return null;
    }

    if (strategy == null) {
        strategy = DefaultRolloverStrategy.createStrategy(null, null, null,
                String.valueOf(Deflater.DEFAULT_COMPRESSION), config);
    }

    if (layout == null) {
        layout = PatternLayout.createDefaultLayout();
    }

    final RollingFileManager manager = RollingFileManager.getFileManager(fileName, filePattern, isAppend,
            isBuffered, policy, strategy, advertiseURI, layout, bufferSize);
    if (manager == null) {
        return null;
    }

    return new MyRollingFileAppender(name, layout, filter, manager, fileName, filePattern,
            ignoreExceptions, isFlush, isAdvertise ? config.getAdvertiser() : null);
}
}

O aplicativo que estou atualizando do log4j 1.2 para o log4j2 usa a API do Apache commons, portanto, não posso usar mapas de contexto de threads para adicionar informações.

Este aplicativo funciona bem por enquanto. No entanto, tenho algumas confusões sobre o meu procedimento.

Quero ter certeza de que a maneira como estou fazendo isso (por exemplo, agrupar o evento de log com informações personalizadas e criar o aplicativo de arquivo de rolamento para informações personalizadas) está correta e, como não podemos estender o aplicativo de arquivo de rolamento existente, preciso reescrever todos os código do appender de arquivo sem interrupção na minha classe personalizada para adicionar apenas mais dois campos ao evento de log? Existe alguma maneira fácil de fazer o mesmo?

Obrigado!

questionAnswers(1)

yourAnswerToTheQuestion