详解用ELK来分析Nginx服务器日志的方法

2019-10-17 19:32:20丽君

                host => "10.173.xx.xx"
                port => 8001
                password => pass
                data_type => "list"
                key => "logstash:redis"
        }
}
log_indexer的配置

log_indexer的配置就比较麻烦了,需要配置的有三个部分

input: 负责从redis中获取日志数据
filter: 负责对日志数据进行分析和结构化
output: 负责将结构化的数据存储进入elasticsearch
input部分

input {
    redis {
        host => "10.173.xx.xx"
        port => 8001
        password => pass
        data_type => "list"
        key => "logstash:redis"
    }
}

其中的redis配置当然要和agent的一致了。

filter部分
解析文本可以使用grokgrok debug进行分析,参照着之前的log格式,需要一个个进行日志分析比对。这个grok语法写的还是比较复杂的,还好有在线grok比对工具可以使用。比对前面的GET和POST的日志格式,修改出来的grok语句如下:

%{IPORHOST:http_host} %{IPORHOST:server_ip} %{IPORHOST:client_ip} [%{HTTPDATE:timestamp}] "%{WORD:http_verb} (?:%{PATH:baseurl}?%{NOTSPACE:params}(?: HTTP/%{NUMBER:http_version})?|%{DATA:raw_http_request})" (%{NOTSPACE:params})?|- %{NUMBER:http_status_code} (?:%{NUMBER:bytes_read}|-) %{QS:referrer} %{QS:agent} %{NUMBER:time_duration:float} %{NUMBER:time_backend_response:float}


这里使用了一点小技巧,params的使用,为了让GET和POST的参数都反映在一个参数上,在对应的GET和POST的参数的地方,都设计使用params这个参数进行对应。

好了,现在params中是请求的参数。比如source=ios&uid=123。但是呢,最后做统计的时候,我希望得出的是“所有source值为ios的调用”,那么就需要对参数进行结构化了。而且我们还希望如果接口中新加入了一个参数,不用修改logstash_indexer就可以直接使用,方法就是使用kv,kv能实现对一个字符串的结构进行k=v格式的拆分。其中的参数prefix可以为这个key在统计的时候增加一个前缀,include_keys可以设置有哪些key包含在其中,exclude_keys可以设置要排除哪些key。

kv {
  prefix => "params."
  field_split => "&"
  source => "params"
}

好了,现在还有一个问题,如果请求中有中文,那么日志中的中文是被urlencode之后存储的。我们具体分析的时候,比如有个接口是/api/search?keyword=我们,需要统计的是keyword被查询的热门顺序,那么就需要解码了。logstash牛逼的也有urldecode命令,urldecode可以设置对某个字段,也可以设置对所有字段进行解码。