filebeat+redis+logstash+elasticsearch+kibana搭建日志分析系统 filebeat+redis+elk搭建日志分析系统

filebeat+redis+logstash+elasticsearch+kibana搭建日志分析系统
filebeat+redis+elk搭建日志分析系统

各个组件作用:

  filebeat:具有日志收集功能,是下一代的Logstash收集器,但是filebeat更轻量,占用资源更少,适合客户端使用。

  redis:Redis 服务器通常都是用作 NoSQL 数据库,不过 logstash 只是用来做消息队列。

  logstash:主要是用来日志的搜集、分析、过滤日志的工具,支持大量的数据获取方式。一般工作方式为c/s架构,client端安装在需要收集日志的主机上,server端负责将收到的各节点日志进行过滤、修改等操作在一并发往elasticsearch上去。

  elasticsearch:Elasticsearch是个开源分布式搜索引擎,提供搜集、分析、存储数据三大功能。它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等。

  kibana:Kibana可以为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,可以帮助汇总、分析和搜索重要数据日志。

https://www.elastic.co下载相应的安装包

1、filebeat安装配置:

  vim /usr/local/ELK/filebeat-6.3.1-linux-x86_64/filebeat.yml

 1 - type: log
 2 
 3   # Change to true to enable this input configuration.
 4   enabled: true
 5 
 6   paths:
 7     - '/data/nginx-logs/*access*'    #定义日志路径
 8   #json.keys_under_root: true    #默认这个值是FALSE的,也就是我们的json日志解析后会被放在json键上。设为TRUE,所有的keys就会被放到根节点。
 9   #json.overwrite_keys: true    #是否要覆盖原有的key,这是关键配置,将keys_under_root设为TRUE后,再将overwrite_keys也设为TRUE,就能把filebeat默认的key值给覆盖了。
10   #fields_under_root: true    #如果该选项设置为true,则新增fields成为*目录,而不是将其放在fields目录下,自定义的field会覆盖filebeat默认的field。
11   #exclude_lines: ['^DBG',"^$"]     #排除以DBG开头和空行
12   tags: ["json_nginxaccess"]    #列表中添加标签,用过过滤
13   document_type: json-nginxaccess    #设定Elasticsearch输出时的document的type字段 可以用来给日志进行分类。Default: log
14   tail_files: true    #Filebeat从文件尾开始监控文件新增内容,非从头开始
15 
16   #fields:
17   #    log_source: nginx
18 
19 - type: log
20   enabled: true
21   paths:
22     - '/data/nginx-logs/*error*'
23   #json.keys_under_root: true
24   #json.overwrite_keys: true
25   tags: ["json_nginxerror"]
26   document_type: json-nginxerror
27   
28   
29 output.redis:
30   hosts: ["192.168.32.231"]    #输出到redis的机器
31   port: 6379    #redis端口号
32   db: 2    #redis数据库的一个整数索引标识,redis不同于mysql有一个库的名字。redis总共0-15默认16个库。
33   timeout: 5    #连接超时时间
34   key: "default_list"    #以default_list的keys传输到redis

    启动filebeat

  集群机器启动filebeat,通过key传到redis,logstash通过tags用来过滤

  ##redis安装启动步骤略

  /usr/local/ELK/filebeat-6.3.1-linux-x86_64/filebeat &

2、elasticsearch集群的安装启动

  修改配置文件 vim /usr/local/ELK/elasticsearch-6.3.0/config/elasticsearch.yml

 1 cluster.name: cc-cluster    #集群名称(自定义)
 2 node.name: cc-1    #节点名称(自定义)
 3 node.master: true    #是否有资格成为master主节点,如只做存储则为false
 4 node.data: true    #是否做存储节点,当这两个都为false时,该节点作为client
 5 path.data: /usr/local/ELK/elasticsearch-6.3.0/data    #数据存储目录
 6 path.logs: /usr/local/ELK/elasticsearch-6.3.0/logs    #日志存储目录
 7 network.host: 192.168.32.231    #监听本地ip
 8 http.port: 9200    #http监听端口
 9 #transport.tcp.port: 9300    #tcp通讯端口
10 #transport.tcp.compres: true
11 gateway.recover_after_nodes: 2    #一个集群中的N个节点启动后,才允许进行恢复处理
12 #gateway.recover_after_time: 5    #设置初始化恢复过程的超时时间,超时时间从上一个配置中配置的N个节点启动后算起
13 gateway.expected_nodes: 1    # 设置这个集群中期望有多少个节点.一旦这N个节点启动(并且recover_after_nodes也符合),立即开始恢复过程(不等待recover_after_time超时)
14 bootstrap.memory_lock: true    #锁定内存,阻止操作系统管理内存,可以有效的防止内存数据被交换到磁盘空间,交换过程中磁盘会抖动,会对性能产生较大的影响。因为ES是基于JAVA开发的可以能过垃圾回收器来单独管理内存,所以关闭操作系统级别的内存管理可以提升性能
15 bootstrap.system_call_filter: false    #关闭操作系统内核验证
16 
17 discovery.zen.ping.unicast.hosts: ["192.168.32.231","192.168.32.230","192.168.32.232"]    #集群初始化连接列表,节点启动后,首先通过连接初始化列表里的地址去发现集群。
18 discovery.zen.minimum_master_nodes: 2    #为了防止集群脑裂,目前的策略是当且仅当节点有超过半数的master候选者存活时(当前两台master),集群才会进行master选举

  master节点

  主要功能是维护元数据,管理集群各个节点的状态,数据的导入和查询都不会走master节点,所以master节点的压力相对较小,因此master节点的内存分配也可以相对少些;但是master节点是最重要的,如果master节点挂了或者发生脑裂了,你的元数据就会发生混乱,那样你集群里的全部数据可能会发生丢失,所以一定要保证master节点的稳定性。
  data node

  是负责数据的查询和导入的,它的压力会比较大,它需要分配多点的内存,选择服务器的时候最好选择配置较高的机器(大内存,双路CPU,SSD... 土豪~);data node要是坏了,可能会丢失一小份数据。
  client node

  是作为任务分发用的,它里面也会存元数据,但是它不会对元数据做任何修改。client node存在的好处是可以分担下data node的一部分压力;为什么client node能分担data node的一部分压力?因为es的查询是两层汇聚的结果,第一层是在data node上做查询结果汇聚,然后把结果发给client node,client node接收到data node发来的结果后再做第二次的汇聚,然后把最终的查询结果返回给用户;所以我们看到,client node帮忙把第二层的汇聚工作处理了,自然分担了data node的压力。
  这里,我们可以举个例子,当你有个大数据查询的任务(比如上亿条查询任务量)丢给了es集群,要是没有client node,那么压力直接全丢给了data node,如果data node机器配置不足以接受这么大的查询,那么就很有可能挂掉,一旦挂掉,data node就要重新recover,重新reblance,这是一个异常恢复的过程,这个过程的结果就是导致es集群服务停止... 但是如果你有client node,任务会先丢给client node,client node要是处理不来,顶多就是client node停止了,不会影响到data node,es集群也不会走异常恢复。
  对于es 集群为何要设计这三种角色的节点,也是从分层逻辑去考虑的,只有把相关功能和角色划分清楚了,每种node各尽其责,才能发挥出分布式集群的效果。

  根据业务需求配置master、client、node。启动elasticsearch

  /usr/local/ELK/elasticsearch-6.3.0/bin/elasticsearch -d

  查看集群状态

  curl  http://192.168.32.231:9200/_cat/nodes?v
  ip             heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
  192.168.32.231           20          88   2    0.61    0.43     0.37 mdi       *      cc-1  # *为主节点
  192.168.32.230           29          62   0    0.00    0.00     0.00 mdi       -      cc-2
  192.168.32.232           35          52   1    0.04    0.06     0.05 mdi       -      cc-3

  

 可能遇到的问题:
问题1:max file descriptors [4096] for elasticsearch process likely too low, increase to at least [65536]
max number of threads [1024] for user [lishang] likely too low, increase to at least [2048]
解决:
shell>sudo vi /etc/security/limits.conf
*        hard    nofile           65536
*        soft    nofile           65536
 
        elk soft memlock unlimited
        elk hard memlock unlimited

问题2:max number of threads [1024] for user [lish] likely too low, increase to at least [2048]
解决:
shell>sudo vi /etc/security/limits.d/90-nproc.conf 
*          soft    nproc     20480

*          hard    nproc     20480

问题3:max virtual memory areas vm.max_map_count [65530] likely too low, increase to at least [262144]
解决:
shell>sudo vi /etc/sysctl.conf 
vm.max_map_count = 262144

shell>sudo sysctl -p

3、logstash配置启动

  vim /usr/local/ELK/logstash-6.3.0/conf/filebeat_redis.conf

  nginx日志为json格式

  log_format json '{"@timestamp":"$time_iso8601",'
                  '"host":"$server_addr",'
                  '"service":"nginxTest",'
                  '"trace":"$upstream_http_ctx_transaction_id",'
                  '"log":"log",'
                  '"clientip":"$remote_addr",'
                  '"remote_user":"$remote_user",'
                  '"request":"$request",'
                  '"http_user_agent":"$http_user_agent",'
                  '"size":$body_bytes_sent,'
                  '"responsetime":$request_time,'
                  '"upstreamtime":"$upstream_response_time",'
                  '"upstreamhost":"$upstream_addr",'
                  '"http_host":"$host",'
                  '"url":"$uri",'
                  '"domain":"$host",'
                  '"xff":"$http_x_forwarded_for",'
                  '"referer":"$http_referer",'
                  '"status":"$status"}';

 1 input {
 2     redis {
 3         data_type => "list"  #支持三种 data_type(实际上是redis_type),不同的数据类型会导致实际采用不同的 Redis 命令操作:1、list => BLPOP 2、channel => SUBSCRIBE 3、pattern_channel => PSUBSCRIBE 
 4         key => "default_list"  #filebeat定义的key
 5         host => "192.168.32.231"
 6         port => 6379
 7         db => 2
 8         threads => 1
 9         #codec => json
10         #type => "json-nginxaccess"
11     }
12 }
13 
14 
15 filter {
16     json {
17         source => "message"
18         remove_field => ["beat"]
19         #remove_field => ["beat","message"]
20     }
21 
22     geoip {
23                source => "clientip"
24     }
25 
26     geoip {
27         source => "clientip"
28         target => "geoip"
29         #database => "/root/GeoLite2-City_20170704/GeoLite2-City.mmdb"
30         add_field => [ "[geoip][coordinates]", "%{[geoip][longitude]}" ]
31         add_field => [ "[geoip][coordinates]", "%{[geoip][latitude]}"  ]
32     }
33 
34     grok {
35                 match => ["message","%{TIMESTAMP_ISO8601:isotime}"]
36         }
37     date {
38         locale => "en"
39         match => ["isotime","ISO8601"]
40         #match => ["isotime","dd/MMM/yyyy:HH:mm:ss Z"]
41         target => "@timestamp"
42     }
43     
44         mutate {
45                 convert => [ "[geoip][coordinates]", "float"]
46                 remove_field => ["message"]
47                 #remove_field => ["@timestamp"]
48         }
49 }
50 
51 output {
52     if "json_nginxaccess" in [tags] {
53             elasticsearch {
54                     #hosts => ["127.0.0.1:9200"]
55                     hosts => ["192.168.32.230:9200","192.168.32.231:9200","192.168.32.232:9200"]
56                     #index => "logstash-%{type}-%{+YYYY.MM.dd}"
57                     index => "logstash-json-nginxaccess-%{+YYYY.MM.dd}"
58                     document_type => "%{[@metadata][type]}"
59                     #flush_size => 2000
60                     #idle_flush_time => 10
61                     sniffing => true
62                     template_overwrite => true
63             }
64     }
65 
66     if "json_nginxerror" in [tags] {
67             elasticsearch {
68                     #hosts => ["127.0.0.1:9200"]
69                     hosts => ["192.168.32.230:9200","192.168.32.231:9200","192.168.32.232:9200"]
70                     #index => "logstash-%{type}-%{+YYYY.MM.dd}"
71                     index => "logstash-json-nginxerror-%{+YYYY.MM.dd}"
72                     document_type => "%{type}"
73                     #flush_size => 2000
74                     #idle_flush_time => 10
75                     sniffing => true
76                     template_overwrite => true
77             }
78     }
79         stdout {
80                 codec => "rubydebug"
81         }
82 }

   /usr/local/ELK/logstash-6.3.0/bin/logstash -f /usr/local/ELK/logstash-6.3.0/conf/filebeat_redis.conf -t 测试配置文件启动是否正常

  nohup /usr/local/ELK/logstash-6.3.0/bin/logstash -f /usr/local/ELK/logstash-6.3.0/conf/filebeat_redis.conf 2>&1 & 启动logstash

  启动之后,查看elasticsearch索引是否生成

   curl http://192.168.32.231:9200/_cat/indices?v

4、配置kibana

  server.port: 5601

  server.host: "192.168.32.231"

  elasticsearch.url: "http://192.168.32.231:9200"

  通过浏览器访问 192.168.32.231:5601

添加索引

filebeat+redis+logstash+elasticsearch+kibana搭建日志分析系统
filebeat+redis+elk搭建日志分析系统

查看索引

filebeat+redis+logstash+elasticsearch+kibana搭建日志分析系统
filebeat+redis+elk搭建日志分析系统

 

5、nginx反向代理配置

  因为免费的 ELK 没有任何安全机制,所以这里使用了 Nginx 作反向代理,避免用户直接访问 Kibana 服务器。加上配置 Nginx 实现简单的用户认证,一定程度上提高安全性。另外,Nginx 本身具有负载均衡的作用,能够提高系统访问性能。

   

 1 upstream kibana_server {
 2         server  127.0.0.1:5601 weight=1 max_fails=3  fail_timeout=60;
 3 }
 4 
 5 server {
 6         listen 80;
 7         server_name www.cc.com;
 8         auth_basic "Restricted Access";      # 验证
 9         auth_basic_user_file /etc/nginx/htpasswd.users;             # 验证文件
10         location / {
11         proxy_pass http://kibana_server;
12         proxy_http_version 1.1;
13         proxy_set_header Upgrade $http_upgrade;
14         proxy_set_header Connection 'upgrade';
15         proxy_set_header Host $host;
16         proxy_cache_bypass $http_upgrade;
17         }
18 }