Logback appender将消息发布为HTTP消息

时间:2016-07-08 16:19:58

标签: json log4j logback slf4j

根据我的要求,我只想将HTTP消息发布到org.slf4j.LoggerFactory.getLogger()记录的另一端。

INFO level记录了以下JSON字符串。

{
  "studentName": "My Name",
  "Deratment": "Computer Science",
  "address": {
     "Address Line1": "My Address Line1",
     "Address Line2": "My Address Line2",
     "Address Line3": "My Address Line3"
  }
}

注意事项,

  1. Http邮件应以MIME类型application/json

  2. 发布
  3. 应该只处理INFO级别的特定日志而不是全部。

  4. Logback中是否有内置的appender来实现这个目的?

    如果没有,最好的方法是什么?

2 个答案:

答案 0 :(得分:1)

Logback与logstash https://github.com/logstash/logstash-logback-encoder的效果非常好。

第一步是将logback配置为logstash连接。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <appender name="stash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
      <destination>127.0.0.1:4560</destination>

      <!-- encoder is required -->
      <encoder class="net.logstash.logback.encoder.LogstashEncoder" />
  </appender>

  <root level="DEBUG">
      <appender-ref ref="stash" />
  </root>
</configuration>

完成后,您需要创建一个从tcp输入到http输出插件的管道,可能如下所示

input {
    tcp {
            port => 4560
            codec => json_lines
        }
}

output {
    http {
        http_method => ...
        url => ...
    }
}

(见https://www.elastic.co/guide/en/logstash/current/plugins-outputs-http.html

答案 1 :(得分:0)

我认为发布json消息的最佳方法是使用org.apache.logging.log4j。

第1步:添加Maven依赖项

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.11.1</version>
</dependency>

以及构建json的任何依赖项,例如

<dependency>
     <groupId>com.google.code.gson</groupId>
     <artifactId>gson</artifactId>
     <version>2.8.5</version>
</dependency>

第2步:编写自定义布局以创建json

@Plugin(name = "CustomJsonLayout", category = Node.CATEGORY, elementType = Layout.ELEMENT_TYPE)
public class CustomJsonLayout extends AbstractStringLayout {
    private static final Gson gson = new Gson();

    public CustomJsonLayout(Configuration config, Charset aCharset, Serializer headerSerializer, Serializer footerSerializer) {
        super(config, aCharset, headerSerializer, footerSerializer);
    }

    @PluginFactory
    public static CustomJsonLayout createLayout(@PluginConfiguration final Configuration config,
                                                @PluginAttribute(value = "charset", defaultString = "US-ASCII") final Charset charset) {
        return new CustomJsonLayout(config, charset, null, null);
    }

    @Override
    public String toSerializable(LogEvent event) {
        JsonObject jsonObject = new JsonObject();

        // as example
        jsonObject.addProperty("application_name", "MyApp");
        jsonObject.addProperty("timestamp", "" + System.currentTimeMillis());

        // some log Information
        jsonObject.addProperty("level", event.getLevel().name());
        jsonObject.addProperty("thread", event.getThreadName());
        jsonObject.addProperty("thread_id", event.getThreadId());
        jsonObject.addProperty("logger_name", event.getLoggerName());

        // extra information
        final StackTraceElement source = event.getSource();
        JsonObject sourceObject = new JsonObject();
        sourceObject.addProperty("class", source.getClassName());
        sourceObject.addProperty("method", source.getMethodName());
        sourceObject.addProperty("file", source.getFileName());
        sourceObject.addProperty("line", source.getLineNumber());
        jsonObject.add("source", sourceObject);

        // your log message
        jsonObject.addProperty("message", event.getMessage().getFormattedMessage());

        // Exceptions
        if (event.getThrownProxy() != null) {
            final ThrowableProxy thrownProxy = event.getThrownProxy();
            final Throwable throwable = thrownProxy.getThrowable();

            final String exceptionsClass = throwable.getClass().getCanonicalName();
            if (exceptionsClass != null) {
                jsonObject.addProperty("exception", exceptionsClass);
            }

            final String exceptionsMessage = throwable.getMessage();
            if (exceptionsMessage != null) {
                jsonObject.addProperty("cause", exceptionsMessage);
            }

            final String stackTrace = thrownProxy.getExtendedStackTraceAsString("");
            if (stackTrace != null) {
                jsonObject.addProperty("stacktrace", stackTrace);
            }
        }

        return gson.toJson(jsonObject).concat("\r\n");
    }

}

第3步:配置log4j2.xml,其中yourUrl-如果您使用Spring Boot(yourUrl = http://...。),则为application.properties的目标URL。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Properties>
        <Property name="urlProp">${bundle:application:yourUrl}</Property>
    </Properties>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
        <Http name="Http" url="${urlProp}">
            <Property name="X-Java-Runtime" value="$${java:runtime}" />
            <CustomJsonLayout/>
        </Http>
        <File name="LogToFile" fileName="logs/app.log">
            <PatternLayout>
                <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
            </PatternLayout>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="100 MB"/>
            </Policies>
            <DefaultRolloverStrategy max="10"/>
        </File>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="Http"/>
            <AppenderRef ref="Console"/>
            <AppenderRef ref="LogToFile"/>
        </Root>
    </Loggers>
</Configuration>

第4步:因此,最后,您可以在任何类中使用记录器

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

private static final Logger logger = LogManager.getLogger(App.class);

logger.info("Application started");