Logstash结合log4j收集tomcat⽇志
翻译,原⽂地址:
译者博客:
参考:
解析原始⽇志⽂件是Logstash摄取数据的好⽅法,有好⼏种⽅法可以将同样的信息转送到Logstash。选择这些⽅法需要做⼀下权衡,它们或多或少只适合特定的场景。之前我已经发布了关于多⾏的tomcat⽇志解析,这篇博⽂是尝试⽐较它和⼀些其他的⽅法:log4j-JSON格式,log4j-TCP 和原始的log4j的多⾏编解码器。
这些例⼦是在⼀台机器上开发的,但设计⽬的是使您的ELK栈运⾏在不同的机器/实例/容器上。在多机环境Filebeat(原logstash-forwarder)将在使⽤⽂件输⼊的情况下使⽤。
下⾯是这次测试中,使⽤到的软件版本
Java 7u67
Spring 4.2.3
Logstash 2.1.0
Elasticsearch 2.1.1
Kibana 4.3.1
我第⼀次开始创作这篇博⽂是在,2014年11⽉28⽇,所以请原谅有些选项可能不再好⽤。此外,你会发现,SLF4J被⽤作⼀个log4j的抽象在代码⽰例中使⽤。
Log4j As JSON
这种⽅法⽤于JSON格式的log4j⽇志,然后⽤Logstash的⽂件输⼊⼀个JSON编解码器摄取数据。这将使⽤避免不必要的解析和线程不安全多⾏过滤器。Seeing json-formatted logs can be jarring for a Java dev (no pun intended), but reading individual log files should be a thing of the past once you’re up and running with log aggregation.如果您有⾜够的磁盘空间,你可以运⾏两个并联的追加程序。
⽐起使⽤复杂的PatternLayout,让我们⼀起来看看log4j-jsonevent-layou。⼀个完全基于配置的符合需求的解决⽅案。
在l中包含如下的依赖项:
<dependency>
<groupId>net.logstash.log4j</groupId>
<artifactId>jsonevent-layout</artifactId>
<version>1.7</version>
</dependency>
log4j.properties 看起来很熟悉
log4j.appender.json=org.apache.log4j.DailyRollingFileAppender
log4j.appender.json.File=target/app.log
log4j.appender.json.DatePattern=.yyyy-MM-dd
log4j.appender.json.layout=net.logstash.log4j.JSONEventLayoutV1
log4j.appender.json.layout.UserFields=application:playground,environment:dev
Logstash的配置如你所想:
input {
file {
codec => json
type => "log4j-json"
path => "/path/to/target/app.log"
}
}
output {
stdout {}
}
The values set in the UserFields are important because they allow the additional log metadata (taxonomy) to be set in the application configuration. This is information about the application and environment that will allow the log aggregation system to categorize the data. Because we’re using the file input plugin we could also use add_field, but this would require separate file plugins statements for every application. Certainly possible, but even with configuration management more of a headache than the alternative. Also, the path parameter of the file plugin is an array so we can specify multiple files with ease.
如果所有的事情都做对,在kibana中的log信息应该如下所⽰:
A log message from Playground using log4j-jsonevent-layout
As you can see, the UserFields are parsed into Logstash fields. If you prefer these values to be set via command line and environment variable, the library provides a way that will override anything set in the log4j.properties.
Log4j over TCP
这种⽅法使⽤log4j的SocketAppender和Logstash的log4j input。⽇志事件被转换成可经由SocketAppender⼆进制格式并传输到log4j input。这⾥的好处是,新的Log4j追加可⽆需额外的依赖,⽽且我们能够避免处理额外的多⾏过滤器。在深⼊挖掘这种⽅法的缺点之前,让我们来看看它如何实现。
这⾥的log4j.properties的⼀个⽚段:
p=org.apache.log4j.SocketAppender
p.Port=3456
p.RemoteHost=localhost
p.ReconnectionDelay=10000
p.Application=playground
对应的 Logstash配置⽚段如:
input {
log4j {
mode => "server"
host => "0.0.0.0"
port => 3456
type => "log4j"
}
}
output {
stdout {}
}
采⽤上⾯的log4j的配置,你将⽆法看到⽇志的application字段。当此参数被设置,Logstash将它解析为⼀个event字段。这是⾮常⽅便的,但它⽆法满⾜你进⾏⽇志分类- 揭露这种⽅法的缺点之⼀:⽤application和环境识别信息对⽇志事件打标签。在Logstash配置时需要使⽤⼀个输⼊插件add_field。这种做法将意味着对于每⼀个Java应⽤程序,将发送⽇志到不同的输⼊插件/端⼝ - 对于扩展应⽤来说,这真的不好玩!
映射诊断上下⽂(Mapped Diagnostic Context)
映射诊断上下⽂(MDC)提供了⼀种⽅法,通过设置⼀组你感兴趣的信息的map键值对,来丰富标准⽇志信息。值得庆幸的是log4j的插件将解析MDC到⽇志事件字段中。MDC 在每个线程中单独管理,但是⼦线程⾃动继承⽗线程的MDC的副本。这意味着⽇志分类可以在应⽤程序的主线程设置为MDC,并影响其整个⽣命周期的每个⽇志声明。
下⾯是⼀个简单的例⼦:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
public class LoggingTaxonomy {
log4j2不打印日志
private static final Logger log = Logger(LoggingTaxonomy.class);
static public void main(String[] args) {
MDC.put("environment", v("APP_ENV"));
// run the app
log.debug("the app is running!");
}
}
⼀个样式如%d{ABSOLUTE} %5p %c{1}:%L - %X{environment} - %m%n的PatternLayout,并且设置APP_ENV为dev,你将看到如下输出:
15:23:03,698 DEBUG LoggingTaxonomy:34 - dev - the app is running!
在何时何地集成MDC很⼤程度上决定于你的应⽤使⽤的框架。但是我曾经⽤过的每⼀个框架都有⼀个地⽅可以设置这个信息。在Spring MVC中,可以放在应⽤初始化⽅法中。如果所有的事情都做对,在kibana中的log信息应该如下所⽰:
使⽤这种⽅法需要注意⼏个事情:
The logging level is stored in priority, not level as is with log4j-jsonevent-layout
没有 source_host 字段, 所以你需要通过MDC⽅式⾃⾏添加

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。