Home » Code » 安装使用ELK进行日志查看与分析

安装使用ELK进行日志查看与分析

ELK是当前开源界比较流行的日志查看与分析工具,它实际上是Elasticsearch + Logstash + Kinaba 的组合。Elasticsearch负责存储索引与查询,Logstash进行过滤匹配,Kinaba则是可视化界面。如果日志机器与服务器分离(实际应用场景大多都是如此),还应该算上Filebeat,它被安装在日志源机器上,用于将日志发送到日志机器的Logstash中。

按照官方文档一步一步安装各个应用即可。对于Elasticsearch,如果启动失败,可能是内存过小,默认配置中jvm虚拟机需要占用4G内存,这时打开jvm.options配置文件,修改-Xms(初始化最小内存)和-Xmx(最大使用内存)的值即可。一般个人购买服务器总共都没有4G内存 😉 。一般来说Elasticsearch是比较好装的,基本没什么问题。启动后能得到以下结果,就是成功了。

curl  localhost:9200
{
  "name" : "6qi3FAK",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "6VkcO0MCQDKj710JVTwsEg",
  "version" : {
    "number" : "5.5.2",
    "build_hash" : "b2f0c09",
    "build_date" : "2017-08-14T12:33:14.154Z",
    "build_snapshot" : false,
    "lucene_version" : "6.6.0"
  },
  "tagline" : "You Know, for Search"
}

对于Logstash,安装启动也是简单的,需要详细说一下位于conf.d目录下的Pipeline配置问题。分三部分,input部分是数据源,对于本机文件,通过file来设置,对于远程Filebeats发送过来的,则通过beats项来设置。第二部分filter,是过滤设置,设置grok来进行字体匹配,一下子可能不太明白这到底要怎么写,可以通过这个网站来debug,只能根据自己的日志格式来慢慢调试获得合适的规则。规则可能比较长,而且还自定义了变量,可以把它放到安装目录下的patterns目录下(如/usr/share/logstash/patterns,文件名随便),定义好规则名称,可以直接引用。比如我的nginx日志格式是默认的main在后边添加了upstream_response_time和request_time,它的匹配规则我放在了/usr/share/logstash/patterns/nginx,内容如下:

NGUSERNAME [a-zA-Z\.\@\-\+_%]+
NGUSER %{NGUSERNAME}
NGINXACCESS %{IPORHOST:clientip} - %{NGUSERNAME:remote_user} \[%{HTTPDATE:timestamp}\] "%{WORD:verb} %{URIPATHPARAM:request} HTTP/%{NUMBER:httpversion}" %{NUMBER:status} (?:%{NUMBER:bytes}|-) (?:"(?:%{URI:referrer}|-)"|%{QS:referrer}) %{QS:agent} %{QS:xforwardedfor} (?:%{BASE10NUM:upstream_response_time}|-) %{BASE10NUM:request_time}

这个匹配规则命名为了NGINXACCESS,因此在match部分,可直接使用%{NGINXACCESS}来表示它。

另外,在匹配的时候,一般还会解析IP地址,使用geoip选项,IP地址库下载地址这里。指定数据库存储位置即可。

最后的output部分,如果有多个input源,可能想存储在不同的index(Elasticsearch中的索引,类似数据库中的库)中方便区分,可以根据不同的type来指定输出位置。在input中,如果来源是file,直接通过type参数指定,如果是beats,可以直接在客户机的filebeat配置中指定document_type。整个lotstash的Pipeline配置如下:

input {
    file {
        path => "/var/log/nginx/huanbao/access.log"
        type => "nginx_access"
    }
    beats {
        port => 5044
    }
}
filter {
    grok {
        match => {
            "message" => "%{NGINXACCESS}"
        }
    }
    urldecode {
        all_fields => true
    }
    geoip {
        source => "clientip"
        database => "/usr/share/logstash/etc/GeoLite2-Country_20170801/GeoLite2-Country.mmdb"
    }
}
output {
    if [type] == "nginx_access" {
        elasticsearch {
            hosts => ["127.0.0.1:9200"]
            index => "huanbao"
        }
    }

    if [type] == "test_nginx_access" {
        elasticsearch {
            hosts => ["127.0.0.1:9200"]
            index => "tokyo"
        }
    }
}

最后的Kibana,不需要配置什么,启动后它的Node进程默认监听的是5601端口,在nginx中配置一个域名将请求转发过去即可:

server {
    server_name elk.xxx.com;
    location / {
        proxy_pass http://localhost:5601;
        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;
    }
    error_log /var/log/nginx/kibana/error.log;
    access_log /var/log/nginx/kibana/access.log;
}

最后访问配置的域名就可以进入图形化的Kibana界面了,一开始让设置默认index,没有数据可以先不管。要查看当前所有的index,可以在Dev Tools中执行GET /_cat/indices 即得到结果。

对于客户机上的Filebeat,按官方文档操作即可,没有什么好说的。在输出到logstash那里,hosts写日志机器的IP和日志机器中logstash->input->beats中的端口,比如我上边写的是5044。可以不使用ssl的,默认也是关闭的。

最后,整个过程中遇到两个问题,一是Logstash启动后不并没有往Elasticsearch发送日志,然后不使用service来启动,直接通过命令行指定配置文件和Pipeline文件运行之得以解决,参考这里

另一个问题是Filebeat与Logstash通信出现协议错误,排查半天是自己想得有点多,因为我以为Filebeat要与Logstash通信,那么Logstash就需要指定主机地址为0.0.0.0或者*,即启动参考中的http.host = 0.0.0.0 及http.port = 5044,实际上这是多此一举的,只需要在input中指定了商品为5044就一切OK了。实际上它们之间通信用的根本不是http协议,而是一个名为lumberjack的协议。我的使用命令行启动Logstash的参数是:–path.settings /etc/logstash -f /etc/logstash/conf.d/huanbao.yml。

一切OK后,当日志累积到一定量,就可以使用它强大的图形化统计功能了,比如一定时间范围内的状态码分布:

再比如Top 50 访问IP:

这对于我们排查问题都是极有帮助的。

Leave a Reply

Your email address will not be published. Required fields are marked *

*

Time limit is exhausted. Please reload CAPTCHA.