zoukankan      html  css  js  c++  java
  • ELK服务基础

    官方文档

    什么是ELK?

      通俗来讲,ELK是由Elasticsearch、Logstash、Kibana三个开源软件组成的一个组合体,这三个软件当中,每个软件用于完成不同的功能,ELK又称为ELK stack,官方域名为static.co,ELK-stack的主要优点有如下几个:
    处理方式灵活:elasticsearch是实时全文索引,具有强大的搜索功能。
    配置相对简单:elasticsearch全部使用JSON接口,logstash使用模板配置,kibana的配置文件部分更简单。
    检索性能高效:基于优秀的设计,虽然每次查询都是实时,但是也可以达到百亿级数据的查询秒级响应。
    集群线性扩展:elasticsearch和logstash都可以灵活线性扩展。
    前端操作绚丽:kibana的前端设计比较绚丽,而且操作简单。

    什么是Elasticsearch:

      是一个高度可扩展的开源全文搜索和分析引擎,它可实现数据的实时全文搜索、支持分布式可实现高可用、提供API接口,可以处理大规模日志数据,比如Nginx、Tomcat、系统日志等功能。

    什么是Logstash:

      可以通过插件实现日志收集和转发,支持日志过滤,支持普通log、自定义json格式的日志解析。

    什么是Kibana:

      主要是通过接口调用elasticsearch的数据,并进行前端数据可视化的展现。

    Beats 比 logstash 更轻量级,不需要装java环境。

    1. elasticsearch 部署

    环境初始化

    最小化安装 Centos-7.2-x86_64操作系统的虚拟机,vcpu-2,内存4G或更多,操作系统盘50G,主机名设置规则
    为linux-hostX.example.com,其中host1和host2为elasticsearch服务器,为保证效果特额外添加一块单独的
    数据磁盘大小为50G并格式化挂载到/data。

    1.1 主机名和磁盘挂载

    # 修改主机名
    hostnamectl set-hostname linux-hostx.example.com && rebbot
    hostnamectl set-hostname linux-host2.example.com && rebbot
    
    # 磁盘挂载
    mkdir /data
    mkfs.xfs /dev/sdb 
    blkid /dev/sdb
    /dev/sdb: UUID="bb780805-efed-43ff-84cb-a0c59c6f4ef9" TYPE="xfs" 
    
    vim /etc/fstab
    UUID="bb780805-efed-43ff-84cb-a0c59c6f4ef9" /data xfs   defaults        0 0
    mount -a
    
    # 各服务器配置本地域名解析
    vim /etc/hosts
    192.168.182.137 linux-host1.example.com
    192.168.182.138 linux-host2.example.com
    

    1.2 关闭防火墙和SELinux,调整文件描述符

    1.3 设置epel源、安装基本操作命令并同步时间

    yum install -y net-tools vim lrzsz tree screen lsof tcpdump wget ntpdate
    cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
    # 添加计划任务
    echo "*/5 * * * * ntpdate time1.aliyun.com &>/dev/null && hwclock-w" >> /var/spool/cron/root
    systemctl restart crond
    

    1.4 安装elasticsearch

    在host1和host2分别安装elasticsearch
    在两台服务器准备java环境:
    方式一:直接使用yum安装openjdk
    yum install java-1.8.0*
    方式二:本地安装在oracle官网下载rpm安装包
    yum localinstall jdk-8u92-linux-x64.rpm
    方式三:下载二进制包自定义profile环境变量

    tar xvf jdk-8u121-linux-x64.tar.gz -C /usr/local/
    ln -sv /usr/local/jdk-8u121-linux-x64 /usr/local/jdk
    vim /etc/profile
    
    java -version
    

    安装elasticsearch

    yum install jdk-8u121-linux-x64.rpm elasticsearch-5.4.0.rpm 

    1.5 配置elasticsearch

    grep  "^[a-Z]" /etc/elasticsearch/elasticsearch.yml 
    cluster.name: elk-cluster
    node.name: elk-node1
    path.data: /data/elkdata
    path.logs: /data/logs
    bootstrap.memory_lock: true
    network.host: 192.168.152.138
    http.port: 9200
    discovery.zen.ping.unicast.hosts: ["192.168.152.138", "192.168.152.139"]

    另外一个节点,只需要更改节点名称和监听地址即可:

    grep  "^[a-Z]" /etc/elasticsearch/elasticsearch.yml 
    cluster.name: elk-cluster
    node.name: elk-node2
    path.data: /data/elkdata
    path.logs: /data/logs
    bootstrap.memory_lock: true
    network.host: 192.168.152.139
    http.port: 9200
    discovery.zen.ping.unicast.hosts: ["192.168.152.138", "192.168.152.139"]

    创建数据和日志目录并授权:

    mkdir /data/elkdata
    mkdir /data/logs
    chown -R elasticsearch.elasticsearch /data/

    在启动脚本中修改,开启内存锁定参数:

    vim /usr/lib/systemd/system/elasticsearch.service
    LimitMEMLOCK=infinity
    

    注意:不开启内存锁定参数,会因为 bootstrap.memory_lock: true 这个参数而启不来。

    调整内存大小,默认是2g:

    vim /etc/elasticsearch/jvm.options 
    -Xms2g
    -Xmx2g
    

    注意:

    将Xmx设置为不超过物理RAM的50%,以确保有足够的物理RAM留给内核文件系统缓存。
    elasticsearch内存最高不要超过32G。
    https://www.elastic.co/guide/en/elasticsearch/reference/current/heap-size.html

    启动服务:

    systemctl restart elasticsearch.service 
    systemctl enable elasticsearch.service

    # 检查状态

    curl -sXGET http://192.168.152.139:9200/_cluster/health?pretty=true
    

    2.elasticsearch插件之head部署

    插件是为了完成不同的功能,官方提供了一些插件但大部分是收费的,另外也有一些开发爱好者提供的插件,可以实现对elasticsearch集群的状态监控与管理配置等功能。

    在elasticsearch5.x版本以后不再支持直接安装head插件,而是需要通过启动一个服务方式,git地址:https://github.com/mobz/elasticsearch-head

    # NPM 的全称是Node-Package Manager,是随同NodeJS一起安装的包管理和分发工具,它很方便让JavaScript开发者下载、安装、上传以及管理以及安装的包。

    安装部署:

    cd /usr/local/src
    git clone git://github.com/mobz/elasticsearch-head.git
    cd elasticsearch-head/
    yum install npm -y
    npm install grunt -save
    ll node_modules/grunt # 确认生成文件
    npm install # 执行安装
    npm run start & 后台启动服务
    

    修改elasticsearch服务配置文件:

    开启跨域访问支持,然后重启elasticsearch服务

    vim /etc/elasticsearch/elasticsearch.yml
    http.cors.enabled: true #最下方添加
    http.cors.allow-origin: "*"
    

    重启服务:

    systemctl restart elasticsearch
    systemctl enable elasticsearch
    

    粗得是主分片,其他的是副分片是细的 用于备份。

    2.1 docker 版本启动head插件

    安装docker:

    yum install docker -y
    systemctl start docker && systemctl enable docker
    

    下载镜像: 

    docker run -p 9100:9100 mobz/elasticsearch-head:5
    

    如果已有镜像,则导入镜像:

    # docker load < elasticsearch-head-docker.tar.gz 
    

    查看镜像:

    docker images
    

    启动镜像:

    docker run -d -p 9100:9100 docker.io/mobz/elasticsearch-head:5
    

    监控脚本:

    vim els-cluster-monitor.py 
    #!/usr/bin/env python
    #coding:utf-8
    
    import smtplib
    from email.mime.text import MIMEText
    from email.utils import formataddr
    import subprocess
    body=""
    false="false"
    obj=subprocess.Popen(("curl -sXGET http://192.168.152.139:9200/_cluster/health?pretty=true"),shell=True,stdout=subprocess.PIPE)
    data=obj.stdout.read()
    data1=eval(data)
    status = data1.get("status")
    if status == "green":
        print "50"
    else:
        print "100"
    
    注意:
    如果通过head做数据浏览,
    /var/lib/docker/overlay2/840b5e6d4ef64ecfdccfad5aa6d061a43f0efb10dfdff245033e90ce9b524f06/diff/usr/src/app/_site/vendor.js
    /var/lib/docker/overlay2/048d9106359b9e263e74246c56193a5852db6a5b99e4a0f9dd438e657ced78d3/diff/usr/src/app/_site/vendor.js
    
    更改application/x-www-form-urlencoded 为 application/json

    3.logstash部署

    logstash环境准备及安装:

    Logstash是一个开源的数据收集引擎,可以水平伸缩,而且logstash整个ELK当中拥有最多插件的一个组件,其可以接收来自不同来源的数据并统一输出到指定的且可以是多个不同目的地。

    环境准备:

    关闭防火墙和selinux,并且安装java环境

    sed -i '/SELINUX/s/enforcing/disabled/' /etc/selinux/config
    yum install jdk-8u121-linux-x64.rpm
    

    安装logstash:

    yum install logstash-5.3.0.rpm -y
    

    # 权限更改为logstash用户和组,否则启动的时候日志报错

    chown logstash.logstash /usr/share/logstash/data/queue -R
    

    测试logstash:

    测试标准输入和输出:

    /usr/share/logstash/bin/logstash -e 'input{ stdin{} } output{stdout{ codec=>rubydebug}}' #标准输入和输出
    hello
    {
        "@timestamp" => 2017-11-18T13:49:41.425Z,	#当前事件的发生时间,
          "@version" => "1",	#事件版本号,一个事件就是一个ruby对象
              "host" => "linux-host2.example.com",	#标记事件发生在哪里
           "message" => "hello"		#消息的具体内容
    }
    
    # 时间不用管它,浏览器会帮我们转换得。
    

    # 压缩文件

    /usr/share/logstash/bin/logstash -e 'input{ stdin{} } output{file{path=>"/tmp/test-%{+YYYY.MM.dd}.log.tar.gz" gzip=>true}}'
    

    # 测试输出到elasticsearch

    /usr/share/logstash/bin/logstash -e 'input{ stdin{} } output{ elasticsearch {hosts => ["192.168.152.138:9200"] index => "logstash-test-%{+YYYY.MM.dd}"}}'
    

    # 索引存放位置

    ll /data/elkdata/nodes/0/indices/
    total 0
    drwxr-xr-x. 8 elasticsearch elasticsearch 65 Nov 18 20:17 W8VO0wNfTDy9h37CYpu17g
    

    # 删除索引有两种方式:

    一种是elasticsearch,一种是通过api
    

    logstash配置文件之收集系统日志:

    # 配置文件说明:conf结尾,名字自定义,一个配置文件可以收集多个日志
    vim /etc/logstash/conf.d/system.conf
    input {
    file {
       path => "/var/log/messages"
       type => "systemlog"		# 日志类型
       start_position => "beginning"	#第一次从头收集,之后从新添加的日志收集
       stat_interval => "2"		# 多长时间去收集一次,两秒
     }
    }
    
    output {
       elasticsearch {	# 定义插件名称
        hosts => ["192.168.152.138:9200"]	
        index => "logstash-systemlog-%{+YYYY.MM.dd}"	# 为什么要加logstash,主要是后期再地图上显示客户端显示城市,模板上必须要以logstash开头
      }
    }
    

    更改/var/log/messages权限:

    # 由于logstash对message没有读得权限
    chmod 644 /var/log/messages
    

    检查配置文件是否有报错:

    # /usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/system.conf -t
    WARNING: Could not find logstash.yml which is typically located in $LS_HOME/config or /etc/logstash. You can specify the path using --path.settings. Continuing using the defaults
    Could not find log4j2 configuration at path /usr/share/logstash/config/log4j2.properties. Using default config which logs to console
    Configuration OK
    15:43:39.440 [LogStash::Runner] INFO  logstash.runner - Using config.test_and_exit mode. Config Validation Result: OK. Exiting Logstash
    # 启动服务:
    systemctl restart logstash

    # 启动成功后,显示logstash-systemlog:

    # 添加到kibana:

    4.kibana部署

    kibana可以单独安装到一台服务器

    yum install kibana-5.4.0-x86_64.rpm -y
    
    更改配置文件:
    grep "^[a-Z]" /etc/kibana/kibana.yml
    server.port: 5601	#端口
    server.host: "192.168.152.138"	#监听地址
    elasticsearch.url: "http://192.168.152.139:9200"	#URL地址
    
    # 查看kibana状态
    http://192.168.152.138:5601/status
    
    # 启动kibana
    systemctl restart kibana
    systemctl enable kibana
    

    # kibana 匹配:
    [logstash-test]-YYYY.MM.DD

    # 显示

    5. if判断多个type类型

    cat /etc/logstash/conf.d/system.conf 
    input {
    file {
       path => "/var/log/messages"
       type => "systemlog"
       start_position => "beginning"
       stat_interval => "2"
     }
    
    
    file {
       path => "/var/log/lastlog"
       type => "system-last"
       start_position => "beginning"
       stat_interval => "2"
    }}
    
    output {
       if [type] == "systemlog"{
       elasticsearch {
        hosts => ["192.168.152.138:9200"]
        index => "logstash-systemlog-%{+YYYY.MM.dd}"
      }
       file{
        path => "/tmp/last.log"
     }}  
      if [type] == "system-last" {
       elasticsearch {
        hosts => ["192.168.152.138:9200"]
        index => "logstash-lastmlog-%{+YYYY.MM.dd}"
     }}
    }
    
    # 检查配置是否正确
    /usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/system.conf -t
    # 重启服务
    systemctl restart logstash
    

    在elastic-head查看节点:

    添加到kibana:

    6.收集nginx访问日志

    部署nginx服务:

    编辑配置文件并准备web页面:

    # 添加到nginx.conf
    vim conf/nginx.conf
    
    # 添加json格式的日志
    log_format access_json '{"@timestamp":"$time_iso8601",'
            '"host":"$server_addr",'
            '"clientip":"$remote_addr",'
            '"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"}';
    access_log  /var/log/nginx/access.log access_json;
    
    # 添加站点
    location /web{
        root html;
        index index.html index.htm;
    }
    
    # 创建目录
    mkdir /usr/local/nginx/html/web
    
    # 首页文件
    echo 'Nginx webPage!' > /usr/local/nginx/html/web/index.html  
    
    # 不stop,日志格式会乱
    /usr/local/nginx/sbin/nginx -s stop
    
    # 授权
    chown nginx.nginx /var/log/nginx
    
    # 启动
    /usr/local/nginx/sbin/nginx 
    
    # 查看访问日志
    [root@linux-host2 conf]# tail -f /var/log/nginx/access.log 
    {"@timestamp":"2017-11-20T23:51:00+08:00","host":"192.168.152.139","clientip":"192.168.152.1","size":0,"responsetime":0.000,"upstreamtime":"-","upstreamhost":"-","http_host":"192.168.152.139","url":"/web/index.html","domain":"192.168.152.139","xff":"-","referer":"-","status":"304"}

    模拟访问:

    # 模拟多个访问
    yum install httpd-tools -y 
    # 一千个请求,每次处理100个,共10次处理完。
    ab -n1000 -c100 http://192.168.152.139/web/index.html

    添加logstash配置:

    vim /etc/logstash/conf.d/nginx-accesslog.conf   
    input {
       file {
         path => "/var/log/nginx/access.log"
         type => "nginx-access-log"
         start_position => "beginning"
         stat_interval => "2"
       }
    }
    
    output {
       elasticsearch {
         hosts => ["192.168.152.139:9200"]
         index => "logstash-nginx-access-log-%{+YYYY.MM.dd}"
       }
    }
    
    # 检查配置文件:
    /usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/nginx-accesslog.conf -t
    
    # 重启logstash
    systemctl restart logstash
    

    查看是否已添加到es:

     

    添加到kibana:

    7.Tomcat日志转json并收集

    服务器部署tomcat服务:
    安装java环境,并自定义一个web界面进行测试。
    配置java环境并部署Tomcat:

    yum install jdk-8u121-linux-x64.rpm
    cd /usr/local/src
    [root@linux-host1 src]# tar -xf apache-tomcat-8.0.27.tar.gz 
    [root@linux-host1 src]# cp -rf apache-tomcat-8.0.27 /usr/local/
    [root@linux-host1 src]# ln -sv /usr/local/apache-tomcat-8.0.27/ /usr/local/tomcat
    "/usr/local/tomcat" -> "/usr/local/apache-tomcat-8.0.27/"
    [root@linux-host1 webapps]# mkdir /usr/local/tomcat/webapps/webdir
    [root@linux-host1 webapps]# echo "Tomcat Page" > /usr/local/tomcat/webapps/webdir/index.html
    [root@linux-host1 webapps]# ../bin/catalina.sh start
    Using CATALINA_BASE:   /usr/local/tomcat
    Using CATALINA_HOME:   /usr/local/tomcat
    Using CATALINA_TMPDIR: /usr/local/tomcat/temp
    Using JRE_HOME:        /usr
    Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
    Tomcat started.
    [root@linux-host1 webapps]# ss -lnt | grep 8080
    LISTEN     0      100         :::8080                    :::*  
    

    配置tomcat的server.xml配置文件:

    [root@linux-host1 conf]# diff server.xml server.xml.bak 
    136,137c136,137
    <                prefix="tomcat_access_log" suffix=".log"
    <              pattern="{"clientip":"%h","ClientUser":"%l","authenticated":"%u","AccessTime":"%t","method":"%r","status":"%s","SendBytes":"%b","Query?string":"%q","partner":"%{Refere}i","Agentversion":"%{User-Agent}i"}"/>
    ---
    >                prefix="localhost_access_log" suffix=".txt"
    >                pattern="%h %l %u %t "%r" %s %b" />
    
    [root@linux-host1 conf]# ../bin/startup.sh stop
    Using CATALINA_BASE:   /usr/local/tomcat
    Using CATALINA_HOME:   /usr/local/tomcat
    Using CATALINA_TMPDIR: /usr/local/tomcat/temp
    Using JRE_HOME:        /usr
    Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
    Tomcat started.
    [root@linux-host1 conf]# ../bin/startup.sh start
    Using CATALINA_BASE:   /usr/local/tomcat
    Using CATALINA_HOME:   /usr/local/tomcat
    Using CATALINA_TMPDIR: /usr/local/tomcat/temp
    Using JRE_HOME:        /usr
    Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
    Tomcat started.
    

    查看日志:

    [root@linux-host1 tomcat]# tail -f logs/tomcat_access_log.2017-11-21.log | jq
    {
      "clientip": "192.168.152.1",
      "ClientUser": "-",
      "authenticated": "-",
      "AccessTime": "[21/Nov/2017:23:45:45 +0800]",
      "method": "GET /webdir2/ HTTP/1.1",
      "status": "304",
      "SendBytes": "-",
      "Query?string": "",
      "partner": "-",
      "Agentversion": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36"
    }
    {
      "clientip": "192.168.152.1",
      "ClientUser": "-",
      "authenticated": "-",
      "AccessTime": "[21/Nov/2017:23:45:45 +0800]",
      "method": "GET /webdir2/ HTTP/1.1",
      "status": "200",
      "SendBytes": "13",
      "Query?string": "",
      "partner": "-",
      "Agentversion": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36"
    }

    添加logstash配置:

    [root@linux-host2 ~]# vim /etc/logstash/conf.d/tomcat_access.conf 
    input {
       file {
         path => "/usr/local/tomcat/logs/tomcat_access_log.*.log"
         type => "tomcat-accesslog"
         start_position => "beginning"
         stat_interval => "2"
       }
    }
    
    output {
       if [type] == "tomcat-accesslog" {
       elasticsearch {
         hosts => ["192.168.152.138:9200"]
         index => "logstash-tomcat152139-accesslog-%{+YYYY.MM.dd}"
       }}
    }
    
    
    # 检查配置文件:
    /usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/nginx-accesslog.conf -t
    

    注意:

    path => "/usr/local/tomcat/logs/tomcat_access_log.*.log "中一定不要有空格,不然会找不到索引,血得教训。

    path日志 * 代表匹配所有日志,如果需要直观定位哪台机器的索引,可以添加后两位的ip地址。

    查看es:

    添加到kiban:

    测试并发:

    [root@linux-host2 tomcat]# ab -n10000 -c100 http://192.168.152.139:8080/webdir/index.html
    This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
    Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
    Licensed to The Apache Software Foundation, http://www.apache.org/
    
    Benchmarking 192.168.152.139 (be patient)
    Completed 1000 requests
    Completed 2000 requests
    Completed 3000 requests
    Completed 4000 requests
    Completed 5000 requests
    Completed 6000 requests
    Completed 7000 requests
    Completed 8000 requests
    Completed 9000 requests
    Completed 10000 requests
    Finished 10000 requests
    
    
    Server Software:        Apache-Coyote/1.1
    Server Hostname:        192.168.152.139
    Server Port:            8080
    
    Document Path:          /webdir/index.html
    Document Length:        12 bytes
    
    Concurrency Level:      100
    Time taken for tests:   17.607 seconds
    Complete requests:      10000
    Failed requests:        0
    Write errors:           0
    Total transferred:      2550000 bytes
    HTML transferred:       120000 bytes
    Requests per second:    567.96 [#/sec] (mean)
    Time per request:       176.068 [ms] (mean)
    Time per request:       1.761 [ms] (mean, across all concurrent requests)
    Transfer rate:          141.44 [Kbytes/sec] received
    
    Connection Times (ms)
                  min  mean[+/-sd] median   max
    Connect:        0   22  24.1     11     158
    Processing:    19  154 117.4    116    2218
    Waiting:        1  141 113.7     95    2129
    Total:         19  175 113.6    142    2226
    
    Percentage of the requests served within a certain time (ms)
      50%    142
      66%    171
      75%    204
      80%    228
      90%    307
      95%    380
      98%    475
      99%    523
     100%   2226 (longest request)
    

    8.收集java日志

    使用codec的multiline插件实现多行匹配,这是一个可以将多行进行合并的插件,而且可以使用what指定将匹配到的行与前面的行合并还是和后面的行合并,
    https://www.elastic.co/guide/en/logstash/current/plugins-codecs-multiline.html

    在elasticsearch服务器部署logstash示例:

    chown logstash.logstash /usr/share/logstash/data/queue -R
    ll -d /usr/share/logstash/data/queue
    cat /etc/logstash/conf.d/java.conf
    input{
    	stdin{
    	codec=>multiline{
    	pattern=>"^["	#当遇到[开头的行时候将多行进行合并
    	negate=>true #true 为匹配成功进行操作,false为不成功进行操作
    	what=>"previous" #与上面的行合并,如果是下面的行合并就是next
    	}}
    }
    filter{ #日志过滤,如果所有的日志都过滤就写这里,如果只针对某一个过滤就写在input里面的日志输入里面
    }
    output{
    	stdout{
    	codec=>rubydebug
    }}
    

    测试匹配代码:

    /usr/share/logstash/bin/logstash -e 'input { stdin { codec => multiline { pattern => "^[" negate => true what => "previous" }}} output { stdout { codec => rubydebug}}'

    注意:如果匹配空行,使用$

    测试匹配输出:

    日志格式:

    [root@linux-host1 ~]# tail /data/logs/elk-cluster.log 
    [2017-11-23T00:11:09,559][INFO ][o.e.c.m.MetaDataMappingService] [elk-node1] [logstash-nginx-access-log-2017.11.22/N8AF_HmTSiqBiX7pNulkYw] create_mapping [elasticsearch-java-log]
    [2017-11-23T00:11:10,777][INFO ][o.e.c.m.MetaDataCreateIndexService] [elk-node1] [elasticsearch-java-log-2017.11.22] creating index, cause [auto(bulk api)], templates [], shards [5]/[1], mappings []
    [2017-11-23T00:11:11,881][INFO ][o.e.c.m.MetaDataMappingService] [elk-node1] [elasticsearch-java-log-2017.11.22/S5LpdLyDRCq3ozqVnJnyBg] create_mapping [elasticsearch-java-log]
    [2017-11-23T00:11:12,418][INFO ][o.e.c.r.a.AllocationService] [elk-node1] Cluster health status changed from [YELLOW] to [GREEN] (reason: [shards started [[elasticsearch-java-log-2017.11.22][3]] ...]).

    生产配置文件:

    vim /etc/logstash/conf.d/java.conf 
    input {
       file {
         path => "/data/logs/elk-cluster.log"
         type => "elasticsearch-java-log"
         start_position => "beginning"
         stat_interval => "2"
         codec => multiline
         { pattern => "^["
         negate => true
         what => "previous" }
    }}
    
    output {
       if [type] == "elasticsearch-java-log" {
       elasticsearch {
         hosts => ["192.168.152.138:9200"]
         index => "elasticsearch-java-log-%{+YYYY.MM.dd}"
       }}
    }
    

    验证语法:

    /usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/java.conf -t
    
    WARNING: Could not find logstash.yml which is typically located in $LS_HOME/config or /etc/logstash. You can specify the path using --path.settings. Continuing using the defaults
    Could not find log4j2 configuration at path /usr/share/logstash/config/log4j2.properties. Using default config which logs to console
    Configuration OK
    00:06:47.228 [LogStash::Runner] INFO  logstash.runner - Using config.test_and_exit mode. Config Validation Result: OK. Exiting Logstash

    重启服务:

    systemctl restart logstash
    

    查看es状态:

    添加到kibana:

    kibana展示:

    9.收集TCP日志

    如果一些日志丢失,可以通过这种方式来进行了补一些日志。
    https://www.elastic.co/guide/en/logstash/current/plugins-inputs-tcp.html

    # 测试配置文件

    vim /etc/logstash/conf.d/tcp.conf
    input {
    	tcp {
    		port => 5600
    		mode => "server"
    		type => "tcplog"
    	}
    } 
    
    output {
    	stdout {
    		codec => rubydebug
    	}
    }
    

    # 验证配置是否正确语法

    /usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/tcp.conf -t
    

    # 启动

    /usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/tcp.conf
    

    在其他服务器安装nc命令:

    NetCat简称nc,在网络工具中有“瑞士军刀”美誉,其功能实用,是一个简单、可靠的网络工具,可通过TCP或UDP协议传输读写数据,另外还具有很多其他功能。

    yum install nc -y
    

    # 发送数据

    echo "nc test"|nc 192.168.56.16 9889
    

    验证logstash是否接收到数据:

    {
        "@timestamp" => 2017-11-23T15:36:50.938Z,
              "port" => 34082,
          "@version" => "1",
              "host" => "192.168.152.138",
           "message" => "tcpdata",
              "type" => "tcplog"
    }
    

    通过nc命令发送一个文件:

    nc 192.168.152.139 5600 < /etc/passwd
    

    通过伪设备的方式发送消息:

    在类Unix操作系统中,设备节点并不一定要对应物理设备。没有这种对应关系的设备是伪设备。操作系统运用了它们提供的多种功能,tcp只是dev下面众多伪设备当中的一种设备。

    echo "伪设备" > /dev/tcp/192.168.152.139/5600
    echo "2222" > /dev/tcp/192.168.152.139/5600
    

    生产配置:

    vim /etc/logstash/conf.d/tomcat_tcp.conf 
    input {
       file {
         path => "/usr/local/tomcat/logs/tomcat_access_log.*.log"
         type => "tomcat-accesslog"
         start_position => "beginning"
         stat_interval => "2"
       }
       tcp {
             port => 5600
             mode => "server"
             type => "tcplog"
       }
    }
    
    output {
       if [type] == "tomcat-accesslog" {
       elasticsearch {
         hosts => ["192.168.152.138:9200"]
         index => "logstash-tomcat152139-accesslog-%{+YYYY.MM.dd}"
       }}
       if [type] == "tcplog" {
       elasticsearch {
         hosts => ["192.168.152.138:9200"]
         index => "tcplog-test152139-%{+YYYY.MM.dd}"
       }}
    }
    

    查看ES:

    查看kibana:

    发送数据:

    11.架构规划

      在下面的图当中从左向右看,当要访问ELK日志统计平台的时候,首先访问的是两天Nginx+keepalived做的负载高可用,访问的地址是keepalived的IP,当一台nginx代理服务器挂掉之后也不影响访问,然后nginx将请求转发到kibana,kibana再去elasticsearch获取数据,elasticsearch是两台做的集群,数据会随机保存在任意一台elasticsearch服务器,redis服务器做数据的临时保存,避免web服务器日志量过大的时候造成的数据收集与保存不一致导致的日志丢失,可以临时保存到redis,redis可以是集群,然后再由logstash服务器在非高峰时期从redis持续的取出即可,另外有一台mysql数据库服务器,用于持久化保存特定的数据,web服务器的日志由filebeat收集之后发送给另外的一台logstash,再有其写入到redis即可完成日志的收集,从图中可以看出,redis服务器处于前端结合的最中间,其左右都要依赖于redis的正常运行,那么我们就先从部署redis开始,然后将日志从web服务器收集到redis,在安装elasticsearch、kibana和从redis提取日志的logstash。

    12. logstash收集日志并写入redis

    用一台服务器按照部署redis服务,专门用于日志缓存使用,用于web服务器产生大量日志的场景,例如下面的服务器内存即将被使用完毕,查看是因为redis服务保存了大量的数据没有被读取而占用了大量的内存空间。
    如果占用内存太多,这时候需要添加logstash服务器了,增加读取速度。

    安装并配置redis:

    redis安装参考链接

    ln -sv /usr/local/src/redis-4.0.6 /usr/local/redis
    cp src/redis-server /usr/bin/
    cp src/redis-cli /usr/bin/
    
    bind 192.168.152.139
    daemonize yes   # 允许后台启动
    # 打开save "",save 全部禁止
    save ""
    #save 900 1
    #save 300 10
    #save 60 10000
    # 开启认证
    requirepass 123456 
    
    启动:
    redis-server /usr/local/redis/redis.conf
    
    测试:
    [root@linux-host2 redis-4.0.6]# redis-cli -h 192.168.152.139
    192.168.152.139:6379> KEYS *
    (error) NOAUTH Authentication required.
    192.168.152.139:6379> auth 123456
    OK
    192.168.152.139:6379> KEYS
    (error) ERR wrong number of arguments for 'keys' command
    192.168.152.139:6379> KEYS *
    (empty list or set)
    192.168.152.139:6379> 
    

    配置logstash将日志写入至redis:

    将tomcat服务器的logstash收集之后的tomcat访问日志写入到redis服务器,然后通过另外的logstash将redis服务器的数据取出再写入elasticsearch服务器。

    官方文档:
    www.elastic.co/guide/en/logstash/current/plugins-outputs-redis.html

    redis-cli -h 192.168.152.139 -a 123456
    LLEN rsyslog-5612
    LPOP rsyslog-5612 # 弹一条
    
    查看数据:
    redis-cli -h 192.168.152.139 -a 123456
    #查询数据
    SELECT 1
    #查看数据
    KEYS *
    

    logstash配置:

    input {
      redis {
    	data_type => "list"
    	host => "192.168.152.139"
    	db => "1"
    	port => "6379"
    	key => "rsyslog-5612"
    	password => "123456"
      }
    }
    
    output {
      elasticsearch {
        hosts => ["192.168.152.139:9200"]
    	index => "redis-rsyslog-5612-%{+YYYY.MM.dd}"
      }
    }
    

    待补充:

    通过rsyslog收集haproxy日志:
    在centos 6及之前的版本叫做syslog,centos7开始叫做rsyslog,根据官方的介绍,rsyslog(2013年版本)可以达到每秒转发百万条日志的级别,官方网址http://www.rsyslog.com/,确认系统安装的版本命令如下:
    
    安装:
    yum install gcc gcc-c++ pcre pcre-devel openssl openss-devel -y
    
    make TARGET=linux2628 USER_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 PREFIX=/usr/local/haproxy
    
    make install PREFIX=/usr/local/haproxy
    
    # 查看版本
    /usr/local/haproxy/sbin/haproxy -v
    
    准备启动脚本:
    vim /usr/lib/systemd/system/haproxy.service
    [Unit]
    Description=HAProxy Load Balancer
    After=syslog.target network.target
    
    [Service]
    EnvironmentFile=/etc/sysconfig/haproxy
    ExecStart=/usr/sbin/haproxy-systemd-wrapper -f /etc/sysconfig/haproxy.cfg -p /run/haproxy.pid $OPTIONS
    ExecReload=/bin/kill -USR2 $MAINPID
    
    [Install]
    WantedBy=multi-user.target
    
    
    [root@linux-host2 haproxy-1.7.9]# cp /usr/local/src/haproxy-1.7.9/haproxy-systemd-wrapper /usr/sbin/
    [root@linux-host2 haproxy-1.7.9]# cp /usr/local/src/haproxy-1.7.9/haproxy /usr/sbin/
    
    vim /etc/sysconfig/haproxy #系统级配置文件
    OPTIONS=""
    
    mkdir /etc/haproxy
    
    vim /etc/sysconfig/haproxy.cfg
    global
    maxconn 100000
    chroot /usr/local/haproxy
    uid 99
    gid 99
    daemon
    nbproc 1
    pidfile /usr/local/haproxy/run/haproxy.pid
    log 127.0.0.1 local6 info
    
    defaults
    option http-keep-alive
    option forwardfor
    maxconn 100000
    mode http
    timeout connect 300000ms
    timeout client	300000ms
    timeout server 	300000ms
    
    listen stats
    mode http
    bind 0.0.0.0:9999
    stats enable
    log global
    stats uri	/haproxy-status
    stats auth 	headmin:123456
    
    #frontend web_port
    frontend web_port
    	bind 0.0.0.0:80
    	mode http
    	option httplog
    	log global
    	option forwardfor
    	
    ###################ACL Setting###################
    	acl pc 			hdr_dom(host) -i www.elk.com
    	acl mobile		hdr_dom(host) -i m.elk.com
    ###################USE ACL ######################
    	use_backend		pc_host		if pc
    	use_backend		mobile_host	if mobile
    #################################################
    
    backend pc_host
    	mode	http
    	option	httplog
    	balance	source
    	server	web1 192.168.56.11:80 check inter 2000 rise 3 fall 2 weight 1 
    
    
    backend mobile_host
    	mode	http
    	option 	httplog
    	balance source
    	server web1	192.168.56.11:80 check inter 2000 rise 3 fall 2 weight 1
    	
    
    
    vim /etc/rsyslog.conf    
    $ModLoad imudp
    $UDPServerRun 514
    
    $ModLoad imtcp
    $InputTCPServerRun 514
    
    local6.* 	@@192.168.152.139:5160
    
    
    重新启动rsyslog服务:
    systemctl restart rsyslog
    
    input{
     syslog {
       type => "rsyslog-5612"
       port => "5160"
     }
    }
    
    output {
      stdout {
         codec => rubydebug
      }
    }
    
    ###########################
    input{
     syslog {
       type => "rsyslog-5612"
       port => "5160"
     }
    }
    output {
     if [type] == "rsyslog-5612"{
       elasticsearch {
         hosts => ["192.168.152.139:9200"]
    	 index => "rsyslog-5612-%{+YYYY.MM.dd}"
       }}
    }
    

    使用filebeat替代logstash收集日志

    Filebeat是轻量级单用途的日志收集工具,用于在没有安装java的服务器上专门收集日志,可以将日志转发到logstash、elasticsearch或redis等场景中进行下一步处理。
    官网下载地址:https://www.elastic.co/downloads/beats/filebeat
    官方文档:https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-configuration-details.html
     
    确定日志格式为json格式:
    先访问web服务器,以产生一定的日志,然后确认是json格式:
    ab -n100 -c100 http://192.168.56.16:8080/web
     
    安装:
    yum -y install filebeat-5.4.0-x86_64.rpm
     
     
    https://www.elastic/guide/en/beats/filebeat/current/filebeat-configuration-details.html
     
     
    [root@linux-host2 src]# grep -v "#" /etc/filebeat/filebeat.yml | grep -v "^$"
    filebeat.prospectors:
    - input_type: log
      paths:
        - /var/log/*.log
        - /var/log/messages
      exclude_lines: ["^DBG","^$"]  #如果有空行,日志往数据写会报错
      document_type: system-log-5612 #日志类型
    output.file:
      path: "/tmp"
      name: "filebeat.txt"
    [root@linux-host2 src]# systemctl restart filebeat
     
    测试使用echo形式:
    echo "test" >> /var/log/messages
     
    [root@linux-host2 src]# tail -f /tmp/filebeat
    {"@timestamp":"2017-12-21T15:45:05.715Z","beat":{"hostname":"linux-host2.example.com","name":"linux-host2.example.com","version":"5.4.0"},"input_type":"log","message":"Dec 21 23:45:01 linux-host2 systemd: Starting Session 9 of user root.","offset":1680721,"source":"/var/log/messages","type":"system-log-5612"}
     
    logstash收集日志并吸入redis:
     
    输出到redis:
    output.redis:
      hosts: ["192.168.56.12:6379"]
      db: "1" #使用第几个库
      timeout: "5" #超时时间
      password: "123456" #redis密码
      key: "system-log-5612" #为了后期日志处理,建议自定义
     
    查看数据:
    SELECT 3
    KYES *
    LLEN system-log-5612
    RPOP system-log-5612
     
     
    从redis取日志:
    input {
      redis {
          data_type => "list"
          host => "172.20.8.13"
          db => "1"
          port => "6379"
          key => "system-log-0840"
          password => "123456"
      }
    }
    output {
      if [type] == "system-log-0840" {
        elasticsearch {
          hosts => ["172.20.8.12:9200"]
          index => "system-log-0840-%{+YYYY.MM.dd}"
        }
      }
    }
     
    logstash 一般是每秒几百行的数据,redis每秒钟上百万行数据

    监控redis数据长度

    实际环境当中,可能会出现redis当中堆积了大量的数据而logstash由于种种原因未能及时提取日志,此时会导致redis服务器的内存被大量使用,甚至出现如下内存即将被使用完毕的情景:
    查看redis中的日志队列长度发现有大量的日志堆积在redis当中:
    
    安装redis模块:
    yum install python-pip -y
    pip install redis
    
    报警脚本:
    #!/usr/bin/env python
    #coding:utf-8
    #Author
    import redis
    def redis_conn():
        pool = redis.ConnectionPool(host="192.168.56.12",port=6379,db=1,password=123456)
    	conn = redis.Redis(connection_pool=pool)
    	data = conn.llen('tomcat-accesslog-5612')
    	print(data)
    redis_conn()
    

     结合logstash进行输出测试

    vim beats.conf
    input{
        beats{
    	    port => 5044
    	}
    }
    
    output{
        stdout {
    	    codec => rubydebug
    	}
    }
    
    #将输出改为文件进行临时输出测试
    output{
        file{
    	    path => "/tmp/filebeat.txt"
    	}
    }
    
    
    filebeat配置文件由redis更改为logstash:
    output.logstash:
      hosts: ["192.168.56.11:5044"] #logstash 服务器地址,可以是多个
      enabled: true #是否开启输出至logstash,默认即为true
      worker: 2 #工作线程数
      compression_level: 3 #压缩级别
      loadbalance: true #多个输出的时候开启负载
    
    
    
    配置logstash的配置文件收集beats的文件,再存入redis:
    vim beats.conf
    input{
        beats{
    	    port => 5044
    	}
    }
    
    output{
      if [type] == "filebeat-system-log-5612"{
      redis {
          data_type => "list"
    	  host => "192.168.56.12"
    	  db => "3"
    	  port => "6379"
    	  key => "filebeat-system-log-5612-%{+YYYY.MM.dd}"
    	  password => "123456"
      }}
    }
    
    
    由redis中取数据,并写入elastsearch:
    vim redis-es.yaml
    input {
      redis {
          data_type => "list"
    	  host => "192.168.56.12"
    	  db = > "3"
    	  port => "6379"
    	  key => "filebeat-system1-log-5612"
    	  password => "123456"
      }
    }
    
    output {
      if [type] == "filebeat-system1-log-5612" {
      elasticsearch {
        hosts => ["192.168.56.11:9200"]
    	index => "filebeat-system1-log-5612-%{+YYYY.MM.dd}"
      }}
    }
    

    filebeat收集tomcat日志

    filebeat配置中添加如下配置:
    - input_type: log
      paths:
        - /usr/local/tomcat/logs/tomcat_access_log.*.log
      document_type: tomcat-accesslog-5612
     
     
    grep -v "#" /etc/filebeat/filebeat.yml | grep -v "^$"
    filebeat.prospectors:
    - input_type: log
      paths:
        - /var/log/messages
        - /var/log/*.log
      exclude_lines: ["^DBG","^$"]
      document_type: filebeat-system-log-5612
    - input_type: log
      paths:
        - /usr/local/tomcat/logs/tomcat_access_log.*.log
      document_type: tomcat-accesslog-5612
    output.logstash:
      hosts: ["192.168.56.11:5044"]
      enabled: true
      worker: 2
      compression_level: 3
     
    logstash收集redis中的日志,传给redis:
    vim beats.conf
    input{
        beats{
            port => 5044
        }
    }
     
    output{
      if [type] == "filebeat-system-log-5612"{
      redis {
          data_type => "list"
          host => "192.168.56.12"
          db => "3"
          port => "6379"
          key => "filebeat-system-log-5612-%{+YYYY.MM.dd}"
          password => "123456"
      }}
      if [type] == "tomcat-accesslog-5612" {
          redis {
          data_type => "list"
          host => "192.168.56.12"
          db => "4"
          port => "6379"
          key => "tomcat-accesslog-5612"
          password => "123456"
      }}
    }
     
    LPOP验证一下redis:
     
     
    由redis中取数据,并写入elastsearch:
    vim redis-es.yaml
    input {
      redis {
          data_type => "list"
          host => "192.168.56.12"
          db => "3"
          port => "6379"
          key => "filebeat-system1-log-5612"
          password => "123456"
      }
      redis {
          data_type => "list"
          host => "192.168.56.12"
          db => "4"
          port => "6379"
          key => "tomcat-accesslog-5612"
          password => "123456"
      }
    }
     
    output {
      if [type] == "filebeat-system1-log-5612" {
      elasticsearch {
        hosts => ["192.168.56.11:9200"]
        index => "filebeat-system1-log-5612-%{+YYYY.MM.dd}"
      }}
      if [type] == "tomcat-accesslog-5612" {
      elasticsearch {
        hosts => ["192.168.56.12:9200"]
        index => "tomcat-accesslog-5612-%{+YYYY.MM.dd}"
      }}
    }
     
     
    添加到kibana:

    添加代理

    添加haproxy代理:
    
    ##################ACL Setting#################
    	acl pc		hdr_dom(host) -i www.elk.com
    	acl mobile	hdr_dom(host) -i m.elk.com
    	acl kibana	hdr_dom(host) -i www.kibana5612.com
    ##################USE ACL######################
    	use_backend	pc_host			if pc
    	use_backend mobile_host		if mobile
    	use_backend kibana_host		if kibana
    ###############################################
    
    backend kibana_host
    	mode http
    	option httplog
    	balance source
    	server web1 127.0.0.1:5601 check inter 2000 rise 3 fall 2 weight 1
    
    kibana配置:
    server.port: 5601
    server.host: "127.0.0.1"
    elasticsearch.url: "http://192.168.56.12:9200"
    
    systemctl start kibana
    systemctl enable kibana
    
    
    Nginx代理并授权:
    vim nginx.conf 
    include /usr/local/nginx/conf/conf.d/*.conf;
    
    vim /usr/local/nginx/conf/conf.d/kibana5612.conf
    upstream kibana_server {
    	server 127.0.0.1:5601 weight=1 max_fails=3 fail_timeout=60;
    }
    
    server {
    	listen 80;
    	server_name www.kibana5611.com;
    	location /{
    	proxy_pass http://kibana_server;
    	proxy_http_version 1.1;
    	proxy_set_header Upgrade $http_upgrade;
    	proxy_set_header Connection 'upgrade';
    	proxy_set_header Host $host;
    	proxy_cache_bypass $http_upgrade;
    	}
    }
    
    yum install httpd-tools -y
    #第一次需要加-c
    htpasswd -bc /usr/local/nginx/conf/htpasswd.users luchuangao 123456
    #第二次需要把-c去掉,否则会覆盖原有得。
    htpasswd -b /usr/local/nginx/conf/htpasswd.users luchuangao 123456
    #查看tail /usr/local/nginx/conf/htpasswd.users
    ...
    #授权
    chown nginx.nginx /usr/local/nginx/conf/htpasswd.users
    #重启服务
    /usr/local/nginx/sbin/nginx -s reload
    
    添加进nginx配置文件:
    vim /usr/local/nginx/conf/conf.d/kibana5612.conf
    upstream kibana_server {
    	server 127.0.0.1:5601 weight=1 max_fails=3 fail_timeout=60;
    }
    
    server {
    	listen 80;
    	server_name www.kibana5611.com;
    	auth_basic "Restricted Access";
    	auth_basic_user_file /usr/local/nginx/conf/htpasswd.users;
    	location /{
    	proxy_pass http://kibana_server;
    	proxy_http_version 1.1;
    	proxy_set_header Upgrade $http_upgrade;
    	proxy_set_header Connection 'upgrade';
    	proxy_set_header Host $host;
    	proxy_cache_bypass $http_upgrade;
    	}
    }
    

    elk定时删除索引

    http://www.iyunw.cn/archives/elk-mei-ri-qing-chu-30-tian-suo-yin-jiao-ben/

  • 相关阅读:
    谈谈系统
    快速发展的Swift是否将淘汰Objective-C?
    XCode环境变量及路径设置
    Windows server2008 搭建ASP接口访问连接oracle数据库全过程记录--备用
    Swift2.0新特性--文章过时重置
    【XCode7+iOS9】http网路连接请求、MKPinAnnotationView自定义图片和BitCode相关错误--备用
    移动App双周版本迭代策略
    ti8168平台的tiler memory
    图像处理之二维码生成-qr
    大数据之网络爬虫-一个简单的多线程爬虫
  • 原文地址:https://www.cnblogs.com/luchuangao/p/7831255.html
Copyright © 2011-2022 走看看