根据我的要求,我只想将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"
}
}
注意事项,
Http邮件应以MIME类型application/json
应该只处理INFO
级别的特定日志而不是全部。
Logback中是否有内置的appender来实现这个目的?
如果没有,最好的方法是什么?
答案 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");