ELK的日志解决方案
一、ELK
-
介绍
ELK是一个流行的日志解决方案,它由三个开源工具组成:Elasticsearch、Logstash和Kibana。下面是这些工具的简单介绍以及它们在日志解决方案中的作用:
- Elasticsearch:Elasticsearch是一个分布式的搜索和分析引擎,它可以用于存储、搜索和分析大规模的日志数据。它提供了强大的全文搜索和实时分析能力,使得用户能够快速地查询和分析日志数据。
- Logstash:Logstash是一个用于数据收集、转换和传输的工具。它可以从多种来源收集日志数据,对数据进行过滤、转换和丰富,然后将数据发送到Elasticsearch等目标存储中。Logstash支持多种输入和输出,包括文件、数据库、消息队列等。
- Kibana:Kibana是一个用于可视化和分析数据的工具,它与Elasticsearch集成,可以帮助用户创建丰富的图表、仪表板和报表,从而更直观地理解和分析日志数据。
-
工作流程
- 数据收集:使用Logstash从各种来源收集日志数据,可以是服务器日志、应用程序日志、网络设备日志等。
- 数据处理:Logstash对收集到的数据进行过滤、转换和丰富,以便更好地适应后续的分析和查询需求。
- 数据存储:将处理后的数据存储到Elasticsearch中,Elasticsearch提供了强大的搜索和分析能力,可以帮助用户快速地查询和分析日志数据。
- 数据可视化:使用Kibana创建图表、仪表板和报表,帮助用户更直观地理解和分析日志数据,从而发现潜在的问题和趋势。
接下来,我们来搭建一个ELK。
二、Elasticsearch
-
查找镜像后拉取镜像
[root@woniu software]# pwd /usr/local/software [root@woniu software]# docker search elasticsearch:7.17.7 [root@woniu software]# docker pull elasticsearch:7.17.7
-
创建elk目录,elk目录下创建elasticsearch,logstash,plugins目录
[root@woniu elk]# ls elasticsearch logstash plugins
-
进elasticsearch目录创建conf,data,plugins目录
[root@woniu elasticsearch]# ls conf data plugins
-
在conf目录下新建elasticsearch.yml编辑以下内容
http: host: 0.0.0.0 cors: enabled: true allow-origin: "*" xpack: security: enabled: falsedocker search elasticsearch:7.17.7
-
查看vm.max_map_count数量,如果是65530则需要改大一点,防止ES启不起来
[root@woniu elasticsearch]# sysctl -a|grep vm.max_map_count ... vm.max_map_count = 65530 [root@woniu elasticsearch]# sysctl -w vm.max_map_count=262144
-
给elasticsearch目录下文件所有权限,不给ES会报错
[root@woniu elk]# chmod 777 elasticsearch/**
-
创建运行容器
docker run -itd \ --name es \ --privileged \ --network wn_docker_net \ --ip 172.18.12.70 \ -p 9200:9200 \ -p 9300:9300 \ -e "discovery.type=single-node" \ -e ES_JAVA_OPTS="-Xms2g -Xmx2g" \ -v /usr/local/software/elk/elasticsearch/conf/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \ -v /usr/local/software/elk/elasticsearch/data:/usr/share/elasticsearch/data \ -v /usr/local/software/elk/elasticsearch/plugins:/usr/share/elasticsearch/plugins \ elasticsearch:7.17.7
-
浏览器访问192.168.102.100:9200(你自己的虚拟机ip:9200),出来如下结果就表示成功
三、Kibana
-
查询、拉取镜像(为了保证和ES版本匹配,这里也用7.17.7)
[root@woniu software]# pwd /usr/local/software [root@woniu software]# docker search kibana:7.17.7 [root@woniu software]# docker pull kibana:7.17.7
-
创建、运行容器
docker run -it \ --name kibana \ --privileged \ --network wn_docker_net \ --ip 172.18.12.71 \ -e "ELASTICSEARCH_HOSTS=http://192.168.102.100:9200" \ -p 5601:5601 \ -d kibana:7.17.7
-
使用5601端口号访问,在右边选择Dev Tools可以进行查询
-
配置ES的分词器ik(https://github.com/medcl/elasticsearch-analysis-ik/releases?page=3)
首先去那个网站下载ik.zip
进容器在/usr/share/elasticsearch/plugins目录下面创建一个目录ik
[root@woniu elasticsearch]# docker exec -it es bash root@868ee4081312:/usr/share/elasticsearch# cd plugins/ root@868ee4081312:/usr/share/elasticsearch/plugins# mkdir ik root@868ee4081312:/usr/share/elasticsearch/plugins# ls ik
退出容器,把下载好的zip拷贝进去
[root@woniu elasticsearch]# docker cp elasticsearch-analysis-ik-7.17.7.zip es:/usr/share/elasticsearch/plugins/ik/
进容器解压
root@868ee4081312:/usr/share/elasticsearch/plugins/ik# unzip elasticsearch-analysis-ik-7.17.7.zip
解压后删除原zip
root@868ee4081312:/usr/share/elasticsearch/plugins/ik# rm -rf elasticsearch-analysis-ik-7.17.7.zip
重启容器
[root@woniu elasticsearch]# docker restart es
然后中文就可以正确分词了
四、Logstash
-
查找并拉取镜像
[root@woniu software]# pwd /usr/local/software [root@woniu software]# docker search logstash:7.17.7 [root@woniu software]# docker pull logstash:7.17.7
-
创建运行容器(这次用文件拷贝的方式,挂载容易报错)
docker run -it \ --name logstash \ --privileged \ -p 5044:5044 \ -p 9600:9600 \ --network wn_docker_net \ --ip 172.18.12.72 \ -v /etc/localtime:/etc/localtime \ -d logstash:7.17.7
-
把容器里的3个配置文件拷出来修改
[root@woniu logstash]# docker cp logstash:/usr/share/logstash/config/logstash.yml logstash.yml [root@woniu logstash]# docker cp logstash:/usr/share/logstash/config/pipelines.yml pipelines.yml [root@woniu logstash]# docker cp logstash:/usr/share/logstash/pipeline/logstash.conf logstash.conf [root@woniu logstash]# ls logstash.conf logstash.yml pipelines.yml
[root@woniu logstash]# vim logstash.yml path.logs: /usr/share/logstash/logs config.test_and_exit: false config.reload.automatic: false http.host: "0.0.0.0" xpack.monitoring.elasticsearch.hosts: [ "http://192.168.102.100:9200" ]
[root@woniu logstash]# vim pipelines.yml # This file is where you define your pipelines. You can define multiple. # # For more information on multiple pipelines, see the documentation: # # https://www.elastic.co/guide/en/logstash/current/multiple-pipelines.html # - pipeline.id: main path.config: "/usr/share/logstash/pipeline/logstash.conf"
[root@woniu logstash]# vim logstash.conf input { tcp { mode => "server" host => "0.0.0.0" port => 5044 codec => json_lines } } filter{ } output { elasticsearch { hosts => ["192.168.102.100:9200"] #elasticsearch的ip地址 index => "ssc-logs" #索引名称 } stdout { codec => rubydebug } }
-
拷贝回容器里
[root@woniu logstash]# docker cp logstash.yml logstash:/usr/share/logstash/config [root@woniu logstash]# docker cp pipelines.yml logstash:/usr/share/logstash/config/ [root@woniu logstash]# docker cp logstash.conf logstash:/usr/share/logstash/pipeline
-
重启容器
[root@woniu logstash]# docker restart logstash
-
访问192.168.102.100:9600(你自己的虚拟机ip:9600),出现如下页面表示成功
五、Spring Boot整合ELK
-
引入依赖(ES和Logback)
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>
<dependency> <groupId>net.logstash.logback</groupId> <artifactId>logstash-logback-encoder</artifactId> <version>7.3</version> </dependency>
-
ES实体类(主要是看注解)
-
application.yml配置
spring: data: elasticsearch: repositories: enabled: true elasticsearch: uris: http://192.168.102.100:9200
-
dao接口(里面可以声明方法,像jpa一样)
@Repository public interface IBookDocDao extends ElasticsearchRepository<BookDoc, Long> { List<BookDoc> findBookDocsByAuthorOrTitleOrIntroduction(String author, String title, String introduction); }
-
service方法(IBookService,就是普通的mybatis-plus的service接口,注入了实现类)
@Service public class BookDocServiceImpl implements IBookDocService { @Autowired private IBookDocDao bookDocDao; @Autowired private IBookService ibs; @Override public void loadFromDb() { List<Book> books = ibs.findAll(); books.forEach(book->{ BookDoc bookDoc = new BookDoc(); bookDoc.setAuthor(book.getAuthor()); bookDoc.setId(book.getId()); bookDoc.setTitle(book.getTitle()); bookDoc.setIntroduction(book.getIntroduction()); bookDoc.setIsbn(book.getIsbn()); bookDoc.setCreateTime(book.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate()); bookDocDao.save(bookDoc); }); System.out.println("数据导入ES成功...."); } @Override public List<BookDoc> findAll() { Iterable<BookDoc> all = bookDocDao.findAll(); List<BookDoc> list = StreamSupport.stream(all.spliterator(), false) .collect(Collectors.toList()); return list; } @Override public List<BookDoc> findByStr(String bookStr) { return bookDocDao.findBookDocsByAuthorOrTitleOrIntroduction(bookStr, bookStr, bookStr); } }
-
然后再定义Controller方法,刚开始使用loadFromDb()把图书数据放到ES里,然后就能用findAll()或者findByStr(bookStr)去从ES里查询数据了,bookStr可以匹配作者、标题、简介。
-
接下来讲一下Logstash的配置,在resources目录下新建logback-spring.xml,里面内容按下面方式配置,然后在yml文件开启日志就行了
<?xml version="1.0" encoding="UTF-8"?> <!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 --> <!-- scan:当此属性设置为true时,配置文档如果发生改变,将会被重新加载,默认值为true --> <!-- scanPeriod:设置监测配置文档是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。 当scan为true时,此属性生效。默认的时间间隔为1分钟。 --> <!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 --> <configuration scan="true" scanPeriod="10 seconds"> <!--1. 输出到控制台--> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <!--此日志appender是为开发使用,只配置最低级别,控制台输出的日志级别是大于或等于此级别的日志信息--> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>DEBUG</level> </filter> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} -%5level ---[%15.15thread] %-40.40logger{39} : %msg%n</pattern> <!-- 设置字符集 --> <charset>UTF-8</charset> </encoder> </appender> <!-- 2. 输出到文件 --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!--日志文档输出格式--> <append>true</append> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} -%5level ---[%15.15thread] %-40.40logger{39} : %msg%n</pattern> <charset>UTF-8</charset> <!-- 此处设置字符集 --> </encoder> </appender> <!--3. LOGSTASH config --> <appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender"> <destination>192.168.102.100:5044</destination> <encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder"> <!--自定义时间戳格式, 默认是yyyy-MM-dd'T'HH:mm:ss.SSS<--> <timestampPattern>yyyy-MM-dd HH:mm:ss</timestampPattern> <customFields>{"appname":"QueryApp"}</customFields> </encoder> </appender> <root level="DEBUG"> <appender-ref ref="CONSOLE"/> <appender-ref ref="FILE"/> <appender-ref ref="LOGSTASH"/> </root> </configuration>