在近期的项目中,由于其项目中记录了许多日志,当系统由于某些BUG挂掉时,单纯地通过命令来查询错误日志很不方便排除,且搜索起来很非常不方便,很花费时间,对于一向不喜欢干重复单调很费时间的我来说,如果没有一种办法来解决日志问题是一件很痛苦的事情。那天偶然,公司的CTO说解决这种事情,只需要ELK就能解决掉了(CTO果然见多识广),对于一向喜欢新技术的我来说,我便在网上搜索了一些关于ELK的知识,正好今天周六,我将此记录一下,为方便以后查看和快速安装ELK。
首先ELK到底是什么呢?通过在网上查询相关信息了解到,其实ELK是由Elasticsearch、Logstash、Kibana这3个软件的缩写。
在以前的项目中日志的处理流程大致是这样的:先由我们自己开发的系统产生出日志,由其日志框架进行处理,(在JAVAEE中这些日志框架如log4j,slf4j,logback)通过日志框架将日志打印到控制台或输出到指定的文件中,当我们需要对日志文件进行查看时,通过vim等工具进行查看。
L
那么有了ELK之后,其日志的处理流程就是在其上所述的基础上,日志处理框架在输出日志信息的时候,还将日志输出到一个开放了TCP端口的程序中,那么在ELK中,这个用于收集日志的程序便是Logstash,在Logstash收集到日志信息后,Logstash这个程序可以将这些日志再次包装一下,也可以直接输出到Elasticsearch这个程序中。
E
由Elasticsearch这个名字猜想出,它是一个和搜索相关的程序,事实上也是这样的,Elasticsearch是一个基于Lucene的搜索服务器,能在很快的时间内检索出你所想要查询的信息。
K
Kibana是什么呢?个人理解的话,Kibana是一个用于操作Elasticsearch的一个图形化界面,通过Kibana这个WEB界面,使得对于Elasticsearch的数据的检索变得非常方便。
ELK流程
所有总结起来,ELK的流程应该是这样的:Logback->Logstash->(Elasticsearch<->Kibana)
由我们自己的程序产生出日志,由日志框架进行处理,将日志数据输出到Logstash中,Logstash再将数据输出到Elasticsearch中,Elasticsearch再与Kibana相结合展示给用户。
ELK搭建过程
软件准备
在这里,以Centos7服务器为例,记录下其ELK的搭建过程。
首先在服务器上下载好以下安装包:
logstash-1.5.4-1.noarch.rpm
elasticsearch-1.7.3.noarch.rpm
kibana-4.1.2-linux-x64.tar.gz
当然,由于以上软件的运行环境为JAVA,所以得要提前安装好JDK。我这里安装的是JDK1.8,并设好环境变量及JAVA_HOME
Logstash安装
[root@Hadoop elk]# whereis logstash
logstash: /etc/logstash /opt/logstash/bin/logstash /opt/logstash/bin/logstash.bat
[root@Hadoop elk]# cd /opt/logstash/bin
[root@Hadoop bin]# ll
total 36
-rwxrwxr-x. 1 logstash logstash 1046 Aug 20 2015 logstash
-rw-rw-r--. 1 logstash logstash 689 Aug 20 2015 logstash.bat
-rwxrwxr-x. 1 logstash logstash 4107 Aug 20 2015 logstash.lib.sh
-rwxrwxr-x. 1 logstash logstash 439 Aug 20 2015 plugin
-rw-rw-r--. 1 logstash logstash 251 Aug 20 2015 plugin.bat
-rwxrwxr-x. 1 logstash logstash 322 Aug 20 2015 rspec
-rw-rw-r--. 1 logstash logstash 245 Aug 20 2015 rspec.bat
-rw-rw-r--. 1 logstash logstash 2165 Aug 20 2015 setup.bat
然后建立一个logstash的配置文件
mkdir config
vim log4j_to_es.conf
在这里面插入如下内容:
input {
tcp {
port => 4567
}
}
filter {
}
output {
stdout {
codec => rubydebug
}
}
其意思就是,开放本地的4567端口,通过此端口接收日志数据
output代表输出,将日志数据输出配置 stdout codec代表按照rubydebug方式把日志包装下
然后再启动下logstash,为了省事,先防火墙关掉
[root@Hadoop ping]# systemctl stop firewalld
然后再执行启动,并以config目录下的log4j_to_es.conf为配置文件
[root@Hadoop bin]# ./logstash -f config/log4j_to_es.conf
提示startup completed就证明启动OK了!
Logback配置
<!-- Logstash encoder -->
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>4.4</version>
</dependency>
再在logback.xml中添加如下内容:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are by default assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="logstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<param name="Encoding" value="UTF-8"/>
<remoteHost>192.168.31.222</remoteHost>
<port>4567</port>
<!-- encoder is required -->
<encoder class="net.logstash.logback.encoder.LogstashEncoder" />
</appender>
<root level="info">
<appender-ref ref="logstash" />
<appender-ref ref="STDOUT" />
</root>
</configuration>
其中remoteHost指定了logstash的IP地址,port为logstash的端口
elasticsearch安装与配置
# 重载所有修改过的配置文件
[root@Hadoop elk]# systemctl daemon-reload
查询出elasticsearch的配置文件,再根据需要修改就好
rpm -qc elasticsearch
kibana安装与配置
在kibana.yml中可以修改kibana的端口和要关联的elasticsearch地址
ELK配置关联,并测试
[root@Hadoop config]# vim log4j_to_es.conf
input {
tcp {
port => 4567
}
}
filter {
}
output {
elasticsearch { host => localhost }
stdout {
codec => rubydebug
}
}
~
~
~
~
~
~
~
~
~
~
~
~
~
~
:wq
添加elasticsearch配置,制定host的位置,然后重新启动logstash
@Controller
@RequestMapping("test")
public class TestController {
private Logger logger = LoggerFactory.getLogger(getClass());
private static int i = 0;
@RequestMapping(value = "hello")
public ResponseEntity<?> helloWorld() {
logger.debug("[ResponseEntity]:{}", "i am debug" + i);
logger.info("[ResponseEntity] i am info" + i);
logger.error("[ResponseEntity]i am error" + i);
logger.warn("[ResponseEntity]i am warn" + i);
i++;
String responseStr = "OK";
ResponseEntity<String> responseEntity = new ResponseEntity<>(responseStr, HttpStatus.OK);
return responseEntity;
}
}
启动测试的WEB工程后,访问测试的controller,并在kibana中查看下日志