05_Nginx日志分析

如果不进行过滤,ES中存储的Nginx的日志是整行日志,在Kibana页面中只能查看到整行的日志,并没有其他太多的价值,所以我们需要对日志进行分割过滤,更有利于进行日志的分析。

学习本章需要具备一定的正则表达式知识

正则表达式

普通正则表达
表达式含义
. 任意一个字符
* 前面一个字符出现0次或者多次
[abc] 中括号内任意一个字符
[^adc] 非中括号内的字符
[0-9] 数字
[a-z] 小写字母
[A-Z] 大写字母
[a-zA-Z0-9] 所有的字母和数字
^xx 以xx开头
xx$ 以xx结尾
\d 数字
\s 空白字符

 

扩展正则表达式
表达式含义
? 前面的字符出现0或者1次
+ 前面的字符出现1或者多次
{n} 前面的字符匹配n次
{a,b} 前面的字符匹配a到b次
{,b} 前面的字符匹配0到b次
{a,} 前面的字符出现a到a+次
(string1 | string2) string1 或者 string2

 

这里只是简单的列举了一些正则表达式,如果想要详细学习正则表达式的可以百度,有很多文档都写的很详细。

分享一个工具,平时自己写完正则表达式可以作为测试使用  http://tool.oschina.net/regex/

 

Nginx日志分析

Nginx日志说明

'$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

  该日志未做任何修改,为Nginx默认的main日志的格式。接下来我们简单的看一下各个字段的含义

$1  访问的IP(如果经过反向代理,则该IP为反向代理服务器的IP地址)
$3  远端访问的用户
$4  访问时间
$6  请求方式
$7  访问的URL
$9  状态码
$10 请求的文件大小
$11 从哪个URL跳转过来
$12 客户端信息
$13 反向代理时获取真实IP

  参考下面一个日志

45.251.100.145 - - [20/Sep/2019:19:33:33 +0800] "GET /index.html HTTP/1.1" 200 78905343 "-" "AndroidDownloadManager/8.1.0 (Linux; U; Android 8.1.0; PACT00 Build/O11019)" "120.163.153.183"

利用Logstash去提取Nginx的日志

  1. Grok使用(?<xxx>提取内容) 来提取xxx字段
  2. 提取客户端IP:(?<clientip>[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))    # 因为nginx日志中的IP一般都是正常的IP。所以简单的匹配即可
  3. 提取时间: \[(?<requesttime>[^]+ \+[0-9]+)\]
  4. 提取请求方式:   "(?<requesttype>[A-Z]+)
  5. 提取请求的内容:(?<requesturl>[^ ]+)
  6. 提取ua:"(?<ua>[^"])"
  7. 提取真实IP: (?<realip>[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))# 该形式只能匹配一个ip,如果有多个IP会报错,目前还未找到其他形式,,暂时作为一个问题放在这里。

 

利用Kibana的Dev tools工具,对一个日志进行一个匹配

grok匹配

得出如下匹配表达式

(?<clientip>[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}) - - \[(?<requesttime>[^ ]+ \+[0-9]+)\] "(?<requesttype>[A-Z]+) (?<requesturl>[^ ]+) HTTP/\d\.\d" (?<status>[0-9]+) [0-9]+ "[^"]+" "(?<ua>[^"]+)" "(?<realip>[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})"

 

修改logstash配置文件

input {
    file {
        path => /var/log/nginx/access.log
    }
}
filter {
    grok {
        match => {
            "message" => '(?<clientip>[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}) - - \[(?<requesttime>[^ ]+ \+[0-9]+)\] "(?<requesttype>[A-Z]+) (?<requesturl>[^ ]+) HTTP/\d\.\d" (?<status>[0-9]+) [0-9]+ "[^"]+" "(?<ua>[^"]+)" "(?<realip>[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})'
        }
    }
}
output {
    elasticsearch {
        hosts => ["http://172.16.142.141:9200"]
    }
}

  

此时在去kibana面板中查看时,可以看到过滤出来的内容,但是如果正则表达式匹配的有问题的话,则显示为 - ,点开查看详细内容,在tag中可以看到_grokparsefailure(正则解析失败)

failure

如果正则表达式没有问题,只是个别这样的情况,可以选择在logstash的输出中配置,不将这样的信息输出到es中,这样也就不会再kibana中看到。

output {
    if "_grokparsefailure" not in [tags] and "_dateparsefailure" not in [tags]{
        elasticsearch {
           hosts => ["http://172.16.142.141:9200"]
        }
    }
}

当然如果这样配置之后,一些正则不能匹配的则不会发送的ES,可能会错过一些信息,所以,最好还是全部都发送到ES中,可以根据错误去修改正则表达式等

 

posted @ 2019-09-20 19:25  情浅凉心  阅读(301)  评论(0编辑  收藏  举报