本文介绍了如何在log4j2中创建滚动文件appender插件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个自定义log4j2滚动文件appender。我需要创建这个自定义appender,因为我想用我的应用程序特有的一些信息包装log4j日志事件。例如userId,托管的应用程序名称。

I want to create a custom log4j2 rolling file appender. I need to create this custom appender because I want to wrap the log4j log event with some information unique to my application. Such as userId, hosted application name.

我有一个扩展Log4jLogEvent实现LogEvent的类。这个类包含了我需要用日志事件包装的信息。
请参阅此代码:

I have a class which extends Log4jLogEvent implements LogEvent. This class has information that I need to wrap with the log event.Please see this code :

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
}

在log4j2中我们不能像log4j 1.2那样扩展滚动文件appender,我通过查看原始滚动文件appender的源代码创建了新的滚动文件appender。该类扩展了AbstractOutputStreamAppender。

In log4j2 since we cannot extend rolling file appender like we did with log4j 1.2, I created new rolling file appender by seeing the source code of original rolling file appender. This class extends AbstractOutputStreamAppender.

这是我为滚动文件追加器编写的代码。

This is the code I have written for rolling file appender.

@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);
}
}

我正在从log4j 1.2升级到log4j2的应用程序使用Apache commons API因此我不能使用线程上下文映射来添加信息。

The application I'm upgrading from log4j 1.2 to log4j2 uses Apache commons API therefore I cannot use thread context maps to add information.

这个appender现在工作正常。但是我对我的程序有些困惑。

This appender works fine for now.However I have some confusions of my procedure.

我想确保我这样做的方式(即用自定义信息包装日志事件并为自定义信息创建滚动文件追加器)是正确的,因为我们无法扩展现有的滚动文件appender我是否需要在我的自定义类中重新编写滚动文件appender的所有代码,以便在日志事件中再添加两个字段?
有没有简单的方法可以做同样的事情?

I want to make sure that the way I'm doing this (i.e wrapping log event with custom information and creating the rolling file appender for custom information) is correct and since we cannot extend existing rolling file appender do I need to re write all the code of rolling file appender in my custom class to just add two more fields in to the log event?Is there any easy way to do the same ?

谢谢!

推荐答案

您要升级的应用程序使用Apache Commons记录,Commons Logging API中没有ThreadContext映射。

The application you are upgrading uses Apache Commons Logging, and there is no ThreadContext map in the Commons Logging API.

但是,您只需在应用程序中使用log4j2 ThreadContext映射即可完成对象。这样您就不需要任何自定义日志事件或appender子类。

However, you can accomplish your object by simply using the log4j2 ThreadContext map in your application. That way you don't need any custom log events or appender subclasses.

应用程序中应该只有少数位置可以设置或修改userID。在这些地方,添加以下代码行:

There should only be a few places in your application where the userID is set or modified. In those places, add these lines of code:

int userId = //get user Id
String appplicationName = //get application name
ThreadContext.put("userID", String.valueOf(userId));
ThreadContext.put("appplicationName", appplicationName);
// ... your business logic

如果将Commons Logging委托给log4j2,那么你可以配置一个模式布局,如:% - 5p [%t]%c:%X {userID} /%{appplicationName}%m%n来制作你的价值观出现在日志中。

If Commons Logging is delegated to log4j2, you can configure a pattern layout like: "%-5p [%t] %c: %X{userID}/%{appplicationName} %m%n" to make your values appear in the log.

这篇关于如何在log4j2中创建滚动文件appender插件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-16 22:02