【Windows】部署ELK
什么是ELK?
ELK是三个开源项目的首字母缩写,这三个项目分别是:Elasticsearch、Logstash 和 Kibana。Elasticsearch 是一个搜索和分析引擎。Logstash 是服务器端数据处理管道,能够同时从多个来源采集数据,转换数据,然后将数据发送到诸如 Elasticsearch 等“存储库。Kibana 则可以让用户在 Elasticsearch 中使用图形和图表对数据进行可视化。
为什么需要使用ELK?
ELK常用于日志收集和分析。日志主要包括系统日志、应用程序日志和安全日志。运维和开发人员可以通过日志了解服务器运行过程中发生的错误及错误产生的原因。定期分析日志可以了解服务器的运行情况、性能、安全性等。每台服务器或应用程序都会产生日志,如果每次都登录这些服务器查看日志并分析会耗费大量时间,而且效率低下,这时我们就需要思考如何将日志汇总起来统一查看。日志集中管理之后又会产生新的问题,日志量太大,日志统计和检索又成为新的问题,如何能实现高性能的检索统计呢?ELK能完美解决我们的问题。
- Elasticsearch是个开源分布式搜索引擎,它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等。
- Logstash是一个完全开源的工具,它可以对你的日志进行收集、分析,并将其存储供以后使用。
- kibana 也是一个开源和免费的工具,它可以为 Logstash 和 Elasticsearch 提供的日志分析友好的 Web 界面,可以汇总、分析和搜索重要数据日志。
windows系统下如何使用ELK?
- 下载ELK
- 安装JDK
- 启动ELK
- 将ELK注册到windows服务
下载ELK
Elasticsearch:https://www.elastic.co/cn/elasticsearch/
Logstash:https://www.elastic.co/cn/logstash/
Kibana:https://www.elastic.co/cn/kibana
下载后解压,注意:解压目录中不要有中文,如下:
由于Logstash的运行依赖于Java运行环境,所以必须安装java环境,配置JAVA_HOME环境变量。
启动ELK
由于Logstash服务依赖Elasticsearch,Kibana服务依赖Logstash和Elasticsearch,所以服务启动顺序如下:Elasticsearch -> Logstash -> Kibana
启动Elasticsearch服务
cmd进入elasticsearch目录,运行以下命令,启动ES服务,如下图:
bin\elasticsearch
看到这些内容说明ES已经启动成功,这时我们可以在浏览器中访问:http://localhost:9200/,出现以下内容说明启动成功了。
启动Logstash服务
配置Logstash服务
在logstash文件夹的bin目录里新建logstash.conf配置文件,参数内容根据自己需求自定义,我这边需要从kafka中获取日志数据,所以配置如下:
启动服务
cmd进入logstash下的bin目录,执行以下命令启动服务:
logstash -f logstash.conf
看到以上输出内容说明服务启动成功,这时我们可以在浏览器中访问:http://localhost:9600/,出现以下内容说明启动成功了。
使用 logstash 获取 springboot 控制台日志并传输到 elasticsearch
修改 pom 文件
<!-- logback 推送日志文件到logstash -->
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>5.2</version>
</dependency>
在resources下添加logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="false">
<property name="log.path" value="logs/${project.artifactId}"/>
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %X{traceId} %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
<conversionRule conversionWord="wex"
converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
<conversionRule conversionWord="wEx"
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<!-- Console log output -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- Log file debug output -->
<appender name="debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/debug.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/%d{yyyy-MM, aux}/debug.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>50MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
</encoder>
</appender>
<!-- Log file error output -->
<appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/%d{yyyy-MM}/error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>50MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
</appender>
<!--logstash配置, 用于连接logstash-->
<appender name="logstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<!--logstash ip地址-->
<!--ip 为 logstash 服务器的 ip,端口号是向 logstash 发送请求的端口(需要与下文 logstash 监控配置相同),随便指定,但端口不能被占用,并开启防火墙-->
<destination>127.0.0.1:5000</destination>
<!-- 日志输出编码 -->
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<timestamp>
<timeZone>UTC</timeZone>
</timestamp>
<pattern>
<pattern>
{
"logLevel": "%level",
"serviceName": "${springAppName:-}",
"pid": "${PID:-}",
"thread": "%thread",
"class": "%logger{40}",
"rest": "%message"
}
</pattern>
</pattern>
</providers>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
</filter>
<!--<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder"/>-->
</appender>
<!-- Level: FATAL 0 ERROR 3 WARN 4 INFO 6 DEBUG 7 -->
<root level="INFO">
<appender-ref ref="console"/>
<appender-ref ref="debug"/>
<appender-ref ref="logstash"/> <!--一定要配置 否则无法输出-->
</root>
</configuration>
SpringBoot应用输出日志
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.util.Timer;
import java.util.TimerTask;
@Slf4j
@Component
public class AppRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
log.info("任务执行, --- 当前时间戳:{}", System.currentTimeMillis());
}
}, 2000, 3500);
}
}
logstash新增连接配置
在/logstash/bin 中新建 log_to_es.conf,新增以下配置(可以复制config/logstash-sample.conf进行修改):
input {
tcp {
mode => "server"
host => "0.0.0.0"
#监控spring boot发来的请求 与spring boot中端口号相同 且不能有其他端口占用
port => 5000
#需要安装logstash-codec-json_lines插件, bin/plugin install logstash-codec-json_lines
codec => json_lines
}
}
output {
elasticsearch {
#es地址
hosts => ["http://localhost:9200"]
#索引名称
index => "index-%{+YYYY.MM.dd}"
}
#若不需要在控制台中输出,此行可以删除
stdout{codec => rubydebug}
}
修改 logstash 下的 logstash.yml(如果有必要)
修改/logstash/config 下的 logstash.yml 为当前服务器的 ip。
http.host: "192.168.xx.xx"
启动logstash
logstash -f logstash.conf
启动SpringBoot应用
这时我们在logstash控制台可以看到日志输出
启动Kibana服务
cmd进入Kibana下的bin目录,执行以下命令:
kibana
看到以上输出内容说明服务启动成功,这时我们可以在浏览器中访问:http://localhost:5601/,出现以下内容说明启动成功了。
访问 kibana,按照图中点击,访问接口,查看下文红框处,如果出现下文字样,则传输成功。
kibana汉化
早期的kibana没有提供中文包,现在的kibana已经有比较完整的中文包了,不需要从网上再下载汉化包
修改config/kibana.yml:
# 将最后一行的 i18n.locale: "en" 修改为 i18n.locale: "zh-CN"
i18n.locale: "zh-CN"
接着重启Kibana,就可以看到配置后的中文界面了。
至此,ELK在windows平台算是启动完成了。但是都是通过命令直接启动,如果电脑重启了我们还得将三个服务使用命令重启一次,太麻烦,这时我们会想到能否将三个服务加入到windows服务中,让其随着系统重启而自动重启呢?接下来我再简单说明下如何将三个服务注册到windows服务中。
将ELK注册到windows服务
安装配置elasticsearch服务
cd进入elasticsearch下bin目录,执行如下服务安装、配置命令:
elasticsearch-service install -- 安装ES
elasticsearch-service manager --配置ES
elasticsearch-service remove --卸载ES
注意:如果服务启动失败,是因为JDK版本问题,使用ES自带的JDK即可。解决方案如下:
打开bin目录下的elasticsearch-env.bat文件,找到如下代码:(从这段代码中可以看到ES会先找JAVA_HOME环境变量,如果没配置就使用ES自带的jdk。)
if defined JAVA_HOME (
set JAVA="%JAVA_HOME%\bin\java.exe"
set JAVA_TYPE=JAVA_HOME
) else (
set JAVA="%ES_HOME%\jdk\bin\java.exe"
set JAVA_HOME="%ES_HOME%\jdk"
set JAVA_TYPE=bundled jdk
)
将上面的代码修改为以下代码:
set JAVA="%ES_HOME%\jdk\bin\java.exe"
set JAVA_HOME="%ES_HOME%\jdk"
set JAVA_TYPE=bundled jdk
修改完成后,卸载原来的服务,重新注册服务即可。
安装logstash服务
创建服务启动批处理文件,logstashstart.bat,内容如下:
这时我们需要nssm工具(一款注册windows服务的工具),从官网下载后将nssm.exe放到logstash下bin目录里,cmd进入目录执行以下命令:
nssm install logstash
在依赖项中添加ES服务。因为logstash的输出配置的是Elasticsearch,如果Elasticsearch没有启动,logstash无法正常工作。添加依赖项如下,最后点击"install service"即可。
安装Kibana服务
安装kibana服务和logstash差不多,将nssm.exe放到kibana下bin目录里,cmd进入目录执行以下命令:
nssm install kibana
最后,打开windows服务,将以上三个服务启动即可。
至此,windows下安装部署ELK就全部完成了!