ELK 介绍

ELK [官网](https://www.elastic.co/

ELK(elasticsearch,logstash,kibana)可以作为日志收集及分析的一整套系统,通过阿里的普及也有越来越多的公司在使用,使用下来功能还可以,这里整理记录一个部署手册

A、处理流程为:Nginx --> syslog --> Rsyslog --> omkafka --> Kafka --> Logstash --> Elasticsearch --> Kibana
B、Nginx产生日志通过syslog系统服务传给Rsyslog服务端,Rsyslog接收到日志后通过omkafka模块将日志写入Kafka,Logstash读取Kafka队列然后写入Elasticsearch,用户通过Kibana检索Elasticsearch里存储的日志
C、Rsyslog服务系统自带无需安装,所以整个流程中客户端不需要额外安装应用
D、服务端虽然Rsyslog也已安装,但默认没有omkafka模块,如果需要Rsyslog写入Kafka需要先安装这个模块
F、omkafka模块在rsyslog v8.7.0之后的版本才支持,所以需要先通过rsyslogd -v命令查看rsyslog版本

本章内容是在一台机子上配置的,并没有区分service 、 client、有条件的同学可以在多台机子上测试 【尽量使用2核4G的服务器 因为1核2G 会有问题,会出现内存 cpu 饱满的情况】

ELK 流程

elk设置为ik_smart elk syslog_日志系统

步骤

使用的是centos 系统

1、rsyslog
更新到最新版本的rsyslog
    cd /etc/yum.repos.d/
    wget http://rpms.adiscon.com/v8-stable/rsyslog.repo
    yum install rsyslog

查看版本
    rsyslog -v

启动 停止 重启
    systemctl start rsyslog
    systemctl stop rsyslog
    systemctl restart rsyslog

rsyslog 更新文档

2、安装omkafka
yum -y install rsyslog-kafka
3、配置rsyslog写日志到kafka
module(load="imudp")
input(type="imudp" port="514")
# nginx access log ==> rsyslog server(local) ==> kafka
module(load="omkafka")
template(name="nginxLog" type="string" string="%msg%")
if $inputname == "imudp" then {
    if ($programname == "nginx_access_log") then
        action(type="omkafka"
            template="nginxLog"
            broker=["120.79.36.134:9092"]
            topic="rsyslog_nginx"
            partitions.auto="on"
            confParam=[
                "socket.keepalive.enable=true"
            ]
        )
}

:rawmsg, contains, "nginx_access_log" ~

1.在 /etc/rsyslog.d/ 目录下添加一个专门处理nginx日志的配置文件[ 如 rsyslog_nginx_kafka.conf]
2.rsyslog配置文件重要配置解释如下:

A、module:加载模块,这里我们需要加载imudp模块来接收nginx服务器syslog发过来的日志数据,也需要加载omkafka模块来将日志写入到kafka
B、input:开启udp协议,端口514,也可以同时开启tcp协议,两者可以共存
C、template:定义一个模板,名字叫nginxLog,模板里可以定义日志的格式,因为我们传的已经是json了,不需要再匹配格式,所以这里不额外定义,注意模板名字要唯一
D、action:在匹配到inputname为imudp且programname为nginx_access_log(就是我们上边nginx配置里边的tag)之后的处理方式,这里的配置为匹配到的日志通过omkafka模块写入kafka集群,还有一些关于omkafka更详细的配置参考上边给出的omkafka模块官方文档
F、:rawmsg, contains:最后这一行的意思是忽略包含 nginx_access_log的日志,没有这一行的话 rsyslog 服务默认会把所有日志都记录到message里边一份,我们已经把日志输出到 kafka 了,本地就没必要再记录了

3.omkafka模块检查kafka里边topic是否存在,如果不存在则创建,无需手动创建kafka的topic

4、配置nginx日志格式
log_format  jsonlog '{'
    '"host": "$host",'
    '"server_addr": "$server_addr",'
    '"http_x_forwarded_for":"$http_x_forwarded_for",'
    '"remote_addr":"$remote_addr",'
    '"time_local":"$time_local",'
    '"request_method":"$request_method",'
    '"request_uri":"$request_uri",'
    '"status":$status,'
    '"body_bytes_sent":$body_bytes_sent,'
    '"http_referer":"$http_referer",'
    '"http_user_agent":"$http_user_agent",'
    '"upstream_addr":"$upstream_addr",'
    '"upstream_status":"$upstream_status",'
    '"upstream_response_time":"$upstream_response_time",'
    '"request_time":$request_time'
'}';


// 下面主要是 access_log  的配置
server {
    listen 80;
    server_name _;
    access_log syslog:server=你的IP:514,facility=local7,tag=nginx_access_log,severity=info jsonlog;
    root /data/wwwroot/default;
    index index.html index.htm index.php;
    #error_page 404 /404.html;
    #error_page 502 /502.html;
    location /nginx_status {
      stub_status on;
      access_log off;
      allow 127.0.0.1;
      deny all;
    }
    location ~ [^/]\.php(/|$) {
      #fastcgi_pass remote_php_ip:9000;
      fastcgi_pass unix:/dev/shm/php-cgi.sock;
      fastcgi_index index.php;
      include fastcgi.conf;
    }
    location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|flv|mp4|ico)$ {
      expires 30d;
      access_log off;
    }
    location ~ .*\.(js|css)?$ {
      expires 7d;
      access_log off;
    }
    location ~ /\.ht {
      deny all;
    }
  }

1.Nginx在v1.10之后的版本才支持syslog的方式处理日志,请确保你的Nginx版本高于1.10

2.为了降低logstash的处理压力,同时也为了降低整个配置的复杂度,我们nginx的日志直接采用json格式

3.抛弃文本文件记录nginx日志,改用syslog直接将日志传输到远端的rsyslog服务器,以便我们后续的处理;这样做的另一个非常重要的好处是我们再也无需考虑nginx日志的分割和定期删除问题(一般我们为了方便管理通常会采用logrotate服务来对日志进行按天拆分和定期删除,以免磁盘被占满)

4.access_log直接输出到syslog服务,各参数解释如下:

syslog:指明日志用syslog服务接收
server:接收syslog发送日志的Rsyslog服务端地址,默认使用udp协议,端口是514
facility:指定记录日志消息的类型,例如认证类型auth、计划任务cron、程序自定义的local0-7等,没有什么特别的含义,不必深究,默认的值是local7
tag:给日志添加一个tag,主要是为了方便我们在服务端区分是哪个服务或者client传来的日志,例如我们这里给了tag:nginx_access_log,如果有多个服务同时都写日志给rsyslog,且配置了不通的tag,在rsyslog服务端就可以根据这个tag找出哪些是nginx的日志
severity:定义日志的级别,例如debug,info,notice等,默认是error
安装kafka

安装java环境

yum -y install java-1.8.0-openjdk.x86_64
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.181-3.b13.el7_5.x86_64/jre
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH

kafka

下载
    wget http://mirrors.hust.edu.cn/apache/kafka/1.1.0/kafka_2.12-1.1.0.tgz
解压并进入目录
    tar -zvxf ./kafka_2.12-1.1.0.tgz
记住你的下载kafka 的目录[我的是 /home/ELK/kafka_2.12-1.1.0]
6、目前我们已经安装了 rsyslog 以及 omkafka 、kafka

测试

重启nginx
    systemctl restart nginx
启动rsyslog
    systemctl restart rsyslogd

启动kafka 套件
    进入你解压的kafka 目录
    启动Zookeeper
    使用安装包中的脚本启动单节点Zookeeper 实例:(参数-daemon表示后台运行)
        bin/zookeeper-server-start.sh -daemon config/zookeeper.properties
    启动Kafka服务
        bin/kafka-server-start.sh config/server.properties
    后台启动kafka的话,用nohup 与&来启动

联调测试

进入kafka的目录

1.查看kafka是否有正常生成topic
    bin/kafka-topics.sh --list --zookeeper 127.0.0.1:2181

    如下显示正常
        __consumer_offsets
        rsyslog_nginx

2.查看topic 为 rsyslog_nginx 的是否能正常接收日志
    A、bin/kafka-console-consumer.sh --zookeeper localhost:2181 --topic rsyslog_nginx
    打开另外一个窗口:
    B、curl 127.0.0.1【你的ip】

   A、窗口下 如若正常可以显示日记记录
      {"host": "127.0.0.1","server_addr": "102.156.252.232","http_x_forwarded_for":"-","remote_addr":"120.79.207.5","time_local":"04/Sep/2018:13:40:05 +0800","request_method":"GET","request_uri":"/","status":200,"body_bytes_sent":3018,"http_referer":"-","http_user_agent":"curl/7.58.0","upstream_addr":"unix:/dev/shm/php-cgi.sock","upstream_status":"200","upstream_response_time":"0.051","request_time":0.051}

上面都成功了、我们可以继续往下安装

ELK 安装

ELK官网

Elasticsearch 安装

创建 /etc/yum.repos.d/elasticsearch.repo 内容如下

[elasticsearch-6.x]
name=Elasticsearch repository for 6.x packages
baseurl=https://artifacts.elastic.co/packages/6.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md

执行安装

yum install elasticsearch

elasticsearch 文档
目录

home: /usr/share/elasticsearch
bin:  /usr/share/elasticsearch/bin
config: /etc/elasticsearch
data: /var/lib/elasticsearch
elasticsearch 配置

vim /etc/elasticsearch/elasticsearch.yml

#设置data存放的路径为/data/es-data
path.data: /data/es-data

#设置logs日志的路径为/log/es-log
path.logs: /log/es-log

#设置内存不使用交换分区
bootstrap.memory_lock: false
#配置了bootstrap.memory_lock为true时反而会引发9200不会被监听,原因不明

#设置允许所有ip可以连接该elasticsearch
network.host: 0.0.0.0

#开启监听的端口为9200
http.port: 9200
启动
systemctl start elasticsearch
 # 查看状态
systemctl status elasticsearch
 # 设置开机启动
systemctl enable elasticsearch
开启9200端口
firewall-cmd --add-port=9200/tcp --permanent
firewall-cmd --reload
测试是否成功

curl http://127.0.0.1:9200

{
  "name" : "SGFrw0d",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "_na_",
  "version" : {
    "number" : "6.4.0",
    "build_flavor" : "default",
    "build_type" : "rpm",
    "build_hash" : "595516e",
    "build_date" : "2018-08-17T23:18:47.308994Z",
    "build_snapshot" : false,
    "lucene_version" : "7.4.0",
    "minimum_wire_compatibility_version" : "5.6.0",
    "minimum_index_compatibility_version" : "5.0.0"
  },
  "tagline" : "You Know, for Search"
}

netstat -antp | grep 9200

tcp        0      0 0.0.0.0:9200            0.0.0.0:*               LISTEN      23704/java          
tcp        0      0 127.0.0.1:46042         127.0.0.1:9200          TIME_WAIT   -

完成 elasticsearch 的安装

logstash 安装

创建 /etc/yum.repos.d/logstash.repo

[logstash-6.x]
name=Elastic repository for 6.x packages
baseurl=https://artifacts.elastic.co/packages/6.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md

执行安装

yum install logstash

logstash文档
目录

home: /usr/share/logstash
bin:  /usr/share/logstash/bin
config: /etc/logstash
data: /var/lib/logstash

测试

1、执行命令
    /usr/share/logstash/bin/logstash -e 'input { stdin { } } output { stdout {} }'
如下显示:
        OpenJDK 64-Bit Server VM warning: If the number of processors is expected to increase from one, then you should configure the number of parallel GC threads appropriately using -XX:ParallelGCThreads=N
    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 errors to the console
    [WARN ] 2018-09-04 14:19:28.990 [LogStash::Runner] multilocal - Ignoring the 'pipelines.yml' file because modules or command line options are specified
    [INFO ] 2018-09-04 14:19:30.464 [LogStash::Runner] runner - Starting Logstash {"logstash.version"=>"6.4.0"}
    [INFO ] 2018-09-04 14:19:34.749 [Converge PipelineAction::Create<main>] pipeline - Starting pipeline {:pipeline_id=>"main", "pipeline.workers"=>1, "pipeline.batch.size"=>125, "pipeline.batch.delay"=>50}
    [INFO ] 2018-09-04 14:19:35.070 [Converge PipelineAction::Create<main>] pipeline - Pipeline started successfully {:pipeline_id=>"main", :thread=>"#<Thread:0x7d5aeb3 run>"}
    The stdin plugin is now waiting for input:
    [INFO ] 2018-09-04 14:19:35.175 [Ruby-0-Thread-1: /usr/share/logstash/lib/bootstrap/environment.rb:6] agent - Pipelines running {:count=>1, :running_pipelines=>[:main], :non_running_pipelines=>[]}
    [INFO ] 2018-09-04 14:19:36.012 [Api Webserver] agent - Successfully started Logstash API endpoint {:port=>9600}


  随便输入一个 如 sss 回车 会显示如下
   {
       "host" => "asdasdsadasdasddvdffdfdf",
       "message" => "sss",
      "@version" => "1",
      "@timestamp" => 2018-09-04T06:20:09.211Z
  }

logstash 则正常

logstash 配置

cat /etc/logstash/logstash.conf 配置【从kafka队列中拿消息(input),输出到 全文搜索引擎elasticsearch上 】

input {
    kafka {
        bootstrap_servers => "121.29.207.9:9092"
        topics => ["rsyslog_nginx"]
    }
}
filter {
    mutate {
        gsub => ["message", "\\x", "\\\x"]
    }
    json {
        source => "message"
    }
    date {
        match => ["time_local","dd/MMM/yyyy:HH:mm:ss Z"]
        target => "@timestamp"
    }
}
output {
    elasticsearch {
        hosts => ["120.79.207.5"]
        index => "rsyslog-nginx-%{+YYYY.MM.dd}"
    }
}

启动带上配置启动

/usr/share/logstash/bin/logstash -f /etc/logstash/logstash.conf
kibana 安装

创建 /etc/zypp/repos.d/kibana.reo

[kibana-6.x]
name=Kibana repository for 6.x packages
baseurl=https://artifacts.elastic.co/packages/6.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md

执行安装

yum install kibana

kibana文档
目录

home: /usr/are/kibana 
bin:  /usr/share/kibana/bin
config: /etc/kibana
data: /var/lib/kibana

开放5601端口

firewall-cmd --add-port=5601/tcp --permanent
firewall-cmd --reload
启动
systemctl start kibana
 # 查看状态 

systemctl status kibana
 # 设置开机启动 

systemctl enable kibana

访问:

你的ip:5601

看到如下的页面

elk设置为ik_smart elk syslog_kafka_02

打开Kibana添加rsyslog-nginx-*的Index,并选择timestamp,创建Index Pattern

进入Discover页面,可以很直观的看到各个时间点请求量的变化,根据左侧Field实现简单过滤,例如我们想查看所有访问状态为404的uri,可以点击request_uri和status后边的add,这两项的内容将出现在右侧,然后点击status下边404状态码后边的加号,则只查看状态为404的请求,点击上方auto-refresh可以设置页面自动刷新时间

到目前为止就已经搭建完成了