Creating a Custom Logback Appender – 创建一个自定义的日志回传应用器

最后修改: 2017年 12月 16日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.介绍

In this article, we’ll explore creating a custom Logback appender. If you are looking for the introduction to logging in Java, please take a look at this article.

在这篇文章中,我们将探讨如何创建一个自定义的Logback应用器。如果你正在寻找Java中的日志介绍,请看看这篇文章

Logback ships with many built-in appenders that write to standard out, file system, or database. The beauty of this framework’s architecture is its modularity, which means we can easily customize it.

Logback带有许多内置的应用程序,可以写到标准输出、文件系统或数据库。这个框架架构的美妙之处在于其模块化,这意味着我们可以轻松地对其进行定制。

In this tutorial, we’ll focus on logback-classic, which requires the following Maven dependency:

在本教程中,我们将重点介绍logback-classic,它需要以下Maven依赖。

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.6</version>
</dependency>

The latest version of this dependency is available on Maven Central.

该依赖的最新版本可在Maven Central上找到。

2. Base Logback Appenders

2.基础日志回溯应用程序

Logback provides base classes we can extend to create a custom appender.

Logback提供了基类,我们可以通过扩展来创建一个自定义的appender。

Appender is the generic interface that all appenders must implement. The generic type is either ILoggingEvent or AccessEvent, depending on if we’re using logback-classic or logback-access, respectively.

Appender是所有appender必须实现的通用接口。通用类型是ILoggingEvent或者AccessEvent,这取决于我们是否使用logback-classic或者logback-access,分别。

Our custom appender should extend either AppenderBase or UnsynchronizedAppenderBase, which both implement Appender and handle functions such as filters and status messages.

我们的自定义应用程序应该扩展AppenderBaseUnsynchronizedAppenderBase它们都实现了应用程序。400″>,它们都实现了Appender,并处理诸如过滤器和状态信息等功能。

AppenderBase is thread-safe; UnsynchronizedAppenderBase subclasses are responsible for managing their thread safety.

AppenderBase是线程安全的;UnsynchronizedAppenderBase子类负责管理其线程安全。

Just as the ConsoleAppender and the FileAppender both extend OutputStreamAppender and call the super method setOutputStream(), the custom appender should subclass OutputStreamAppender if it is writing to an OutputStream.

就像ConsoleAppenderFileAppender都扩展OutputStreamAppender并调用超级方法setOutputStream()自定义Appender应该子类化OutputStreamAppender,如果它要写入一个OutputStream

3. Custom Appender

3.自定义Appender

For our custom example, we’ll create a toy appender named MapAppender. This appender will insert all logging events into a ConcurrentHashMap, with the timestamp for the key. To begin, we’ll subclass AppenderBase and use ILoggingEvent as the generic type:

对于我们的自定义例子,我们将创建一个名为MapAppender的玩具应用器。这个appender将把所有的日志事件插入一个ConcurrentHashMap中,并以时间戳为键。首先,我们将子类化AppenderBase并使用ILoggingEvent作为通用类型。

public class MapAppender extends AppenderBase<ILoggingEvent> {

    private ConcurrentMap<String, ILoggingEvent> eventMap 
      = new ConcurrentHashMap<>();

    @Override
    protected void append(ILoggingEvent event) {
        eventMap.put(String.valueOf(System.currentTimeMillis()), event);
    }
    
    public Map<String, ILoggingEvent> getEventMap() {
        return eventMap;
    }
}

Next, to enable the MapAppender to start receiving logging events, let’s add it as an appender in our configuration file logback.xml:

接下来,为了使MapAppender开始接收日志事件,让我们在配置文件logback.xml中把它作为一个appender加入。

<configuration>
    <appender name="map" class="com.baeldung.logback.MapAppender"/>
    <root level="info">
        <appender-ref ref="map"/>
    </root>
</configuration>

4. Setting Properties

4.设置属性

Logback uses JavaBeans introspection to analyze properties set on the appender. Our custom appender will need getter and setter methods to allow the introspector to find and set these properties.

Logback使用JavaBeans自省来分析设置在appender上的属性。我们的自定义appender将需要getter和setter方法,以便让自省器找到并设置这些属性。

Let’s add a property to MapAppender that gives the eventMap a prefix for its key:

让我们为MapAppender添加一个属性,给eventMap的键添加一个前缀。

public class MapAppender extends AppenderBase<ILoggingEvent> {

    //...

    private String prefix;

    @Override
    protected void append(ILoggingEvent event) {
        eventMap.put(prefix + System.currentTimeMillis(), event);
    }

    public String getPrefix() {
        return prefix;
    }

    public void setPrefix(String prefix) {
        this.prefix = prefix;
    }

    //...

}

Next, add a property to our configuration to set this prefix:

接下来,在我们的配置中添加一个属性来设置这个前缀。

<configuration debug="true">

    <appender name="map" class="com.baeldung.logback.MapAppender">
        <prefix>test</prefix>
    </appender>

    //...

</configuration>

5. Error Handling

5 错误处理

To handle errors during the creation and configuration of our custom appender, we can use methods inherited from AppenderBase.

为了处理在创建和配置我们的自定义应用程序期间的错误,我们可以使用从AppenderBase继承的方法。

For example, when the prefix property is a null or an empty string, the MapAppender can call addError() and return early:

例如,当prefix属性为null或空字符串时,MapAppender可以调用addError()并提前返回。

public class MapAppender extends AppenderBase<ILoggingEvent> {

    //...

    @Override
    protected void append(final ILoggingEvent event) {
        if (prefix == null || "".equals(prefix)) {
            addError("Prefix is not set for MapAppender.");
            return;
        }

        eventMap.put(prefix + System.currentTimeMillis(), event);
    }

    //...

}

When the debug flag is turned on in our configuration, we’ll see an error in the console that alerts us that the prefix property has not been set:

当我们在配置中打开调试标志时,我们会在控制台看到一个错误,提醒我们前缀属性没有被设置。

<configuration debug="true">

    //...

</configuration>

6. Conclusion

6.结论

In this quick tutorial, we focused on how to implement our custom appender for Logback.

在这个快速教程中,我们着重介绍了如何实现我们的Logback的自定义应用程序。

As usual, the example can be found over on Github.

像往常一样,这个例子可以在Github上找到over