在生产环境中,nginx日志格式往往使用的是自定义的格式,我们需要把logstash中的message结构化后再存储,方便kibana的搜索和统计,因此需要对message进行解析。

  本文采用grok过滤器,使用match正则表达式解析,根据自己的log_format定制。

1、nginx日志格式

  log_format配置如下:

log_format  main  '$remote_addr - $remote_user [$time_local] $http_host $request_method "$uri" "$query_string" '
'$status $body_bytes_sent "$http_referer" $upstream_status $upstream_addr $request_time $upstream_response_time '
'"$http_user_agent" "$http_x_forwarded_for"' ;

  对应的日志如下:

1.1.1.1 - - [/Jun/::: +] www.test.com GET "/api/index" "?cms=0&rnd=1692442321"   "http://www.test.com/?cp=sfwefsc"  192.168.0.122: 0.004 0.004 "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36" "-"

2、编写正则表达式

  logstash中默认存在一部分正则让我们来使用,可以访问Grok Debugger来查看,可以在 $logstash/vendor/bundle/jruby/1.9/gems/logstash-patterns-core-4.0./patterns/ 目录里面查看。

  基本定义在grok-patterns中,我们可以使用其中的正则,当然并不是所有的都适合nginx字段,这时就需要我们自定义正则,然后通过指定patterns_dir来调用。

  同时在写正则的时候可以使用Grok Debugger或者Grok Comstructor工具来帮助我们更快的调试。在不知道如何使用logstash中的正则的时候也可使用Grok Debugger的Descover来自动匹配。

  1)nginx标准日志格式

    logstash自带的grok正则中有Apache的标准日志格式:

COMMONAPACHELOG %{IPORHOST:clientip} %{HTTPDUSER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" %{NUMBER:response} (?:%{NUMBER:bytes}|-)
COMBINEDAPACHELOG %{COMMONAPACHELOG} %{QS:referrer} %{QS:agent}

    对于nginx标准日志格式,可以发现只是最后多了一个 $http_x_forwarded_for 变量。则nginx标准日志的grok正则定义为:

MAINNGINXLOG %{COMBINEDAPACHELOG} %{QS:x_forwarded_for}

  2)自定义格式

    通过log_format来匹配对应的正则如下:

%{IPV4:remote_addr} - (%{USERNAME:user}|-) \[%{HTTPDATE:log_timestamp}\] (%{HOSTNAME1:http_host}|-) (%{WORD:request_method}|-) \"(%{URIPATH1:uri}|-|)\" \"(%{URIPARM1:param}|-)\" %{STATUS:http_status} (?:%{BASE10NUM:body_bytes_sent}|-) \"(?:%{GREEDYDATA:http_referrer}|-)\" (%{STATUS:upstream_status}|-) (?:%{HOSTPORT1:upstream_addr}|-) (%{BASE16FLOAT:upstream_response_time}|-) (%{STATUS:request_time}|-) \"(%{GREEDYDATA:user_agent}|-)\" \"(%{FORWORD:x_forword_for}|-)\"

    这里面有几个是我自定义的正则:

URIPARM1 [A-Za-z0-$.+!*'|(){},~@#%&/=:;^\\_<>`?\-\[\]]*
URIPATH1 (?:/[\\A-Za-z0-$.+!*'(){},~:;=@#% \[\]_<>^\-&?]*)+
HOSTNAME1 \b(?:[-9A-Za-z_\-][-9A-Za-z-_\-]{,})(?:\.(?:[-9A-Za-z_\-][-9A-Za-z-:\-_]{,}))*(\.?|\b)
STATUS ([-.]{,}[, ]{,})+
HOSTPORT1 (%{IPV4}:%{POSINT}[, ]{,})+
FORWORD (?:%{IPV4}[,]?[ ]?)+|%{WORD}

  message是每段读进来的日志,IPORHOST、USERNAME、HTTPDATE等都是patterns/grok-patterns中定义好的正则格式名称,对照日志进行编写。

  grok pattren的语法为:%{SYNTAX:semantic},":" 前面是grok-pattrens中定义的变量,后面可以自定义变量的名称。(?:%{SYNTAX:semantic}|-)这种形式是条件判断。

  如果有双引号""或者中括号[],需要加 \ 进行转义。

  详解自定义正则:

URIPARAM \?[A-Za-z0-$.+!*'|(){},~@#%&/=:;_?\-\[\]<>]*

URIPARM1 [A-Za-z0-$.+!*'|(){},~@#%&/=:;^\\_<>`?\-\[\]]* grok-patterns中正则表达式,可以看到grok-patterns中是以“?”开始的参数,在nginx的 $query_string 中已经把“?”去掉了,所以我们这里不再需要“?”。另外单独加入日志中出现的  ^ \ _ < > ` 特殊符号

URIPATH (?:/[A-Za-z0-$.+!*'(){},~:;=@#%&_\-]*)+

URIPATH1 (?:/[\\A-Za-z0-$.+!*'(){},~:;=@#% \[\]_<>^\-&?]*)+ grok-patterns中正则表达式,grok-patterns中的URIPATH不能匹配带空格的URI,于是在中间加一个空格。另外还有 \ [ ] < > ^ 特殊符号。

HOSTNAME \b(?:[-9A-Za-z][-9A-Za-z-]{,})(?:\.(?:[-9A-Za-z][-9A-Za-z-]{,}))*(\.?|\b)

HOSTNAME1 \b(?:[-9A-Za-z_\-][-9A-Za-z-_\-]{,})(?:\.(?:[-9A-Za-z_\-][-9A-Za-z-:\-_]{,}))*(\.?|\b) 添加匹配 http_host 中带有 "-" 的字符。

HOSTPORT %{IPORHOST}:%{POSINT}

HOSTPORT1 (%{IPV4}:%{POSINT}[, ]{,})+ 在匹配 upstream_addr 字段时发现,会出现多个IP地址的情况出现,匹配多个IP地址。

STATUS ([-.]{,}[, ]{,})+ 该字段是当出现多个 upstream_addr 字段时匹配多个 http_status 。

FORWORD (?:%{IPV4}[,]?[ ]?)+|%{WORD} 当 x_forword_for 字段出现多个IP地址时匹配。

  nginx左右字段都定义完成,可以使用Grok Debugger或者Grok Comstructor工具来测试。添加自定义正则的时候,在Grok Debugger中可以勾选“Add custom patterns”。

  以上日志匹配结果为:

{
"remote_addr": [
"1.1.1.1"
],
"user": [
"-"
],
"log_timestamp": [
"06/Jun/2016:00:00:01 +0800"
],
"http_host": [
"www.test.com"
],
"request_method": [
"GET"
],
"uri": [
"/api/index"
],
"param": [
"?cms=0&rnd=1692442321"
],
"http_status": [
""
],
"body_bytes_sent": [
""
],
"http_referrer": [
"http://www.test.com/?cp=sfwefsc"
],
"port": [
null
],
"upstream_status": [
""
],
"upstream_addr": [
"192.168.0.122:80"
],
"upstream_response_time": [
"0.004"
],
"request_time": [
"0.004"
],
"user_agent": [
""Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36""
],
"client_ip": [
"2.2.2.2"
],
"x_forword_for": [
null
]
}

3、logstash的配置文件

  创建自定义正则目录

# mkdir -p /usr/local/logstash/patterns
# vi /usr/local/logstash/patterns/nginx

  然后写入上面自定义的正则

URIPARM1 [A-Za-z0-$.+!*'|(){},~@#%&/=:;_?\-\[\]]*
URIPATH1 (?:/[A-Za-z0-$.+!*'(){},~:;=@#%&_\- ]*)+
URI1 (%{URIPROTO}://)?(?:%{USER}(?::[^@]*)?@)?(?:%{URIHOST})?(?:%{URIPATHPARAM})?
NGINXACCESS %{IPORHOST:remote_addr} - (%{USERNAME:user}|-) \[%{HTTPDATE:log_timestamp}\] %{HOSTNAME:http_host} %{WORD:request_method} \"%{URIPATH1:uri}\" \"%{URIPARM1:param}\" %{BASE10NUM:http_status} (?:%{BASE10NUM:body_bytes_sent}|-) \"(?:%{URI1:http_referrer}|-)\" (%{BASE10NUM:upstream_status}|-) (?:%{HOSTPORT:upstream_addr}|-) (%{BASE16FLOAT:upstream_response_time}|-) (%{BASE16FLOAT:request_time}|-) (?:%{QUOTEDSTRING:user_agent}|-) \"(%{IPV4:client_ip}|-)\" \"(%{WORD:x_forword_for}|-)\"

  logstash.conf配置文件内容

input {
file {
path => "/data/nginx/logs/access.log"
type => "nginx-access"
start_position => "beginning"
sincedb_path => "/usr/local/logstash/sincedb"
}
}
filter {
if [type] == "nginx-access" {
grok {
patterns_dir => "/usr/local/logstash/patterns" //设置自定义正则路径
match => {
"message" => "%{NGINXACCESS}"
}
}
date {
match => [ "log_timestamp" , "dd/MMM/YYYY:HH:mm:ss Z" ]
}
         urldecode {
         all_fields => true
       }
         //把所有字段进行urldecode(显示中文)
}
}
output {
if [type] == "nginx-access" {
elasticsearch {
hosts => ["10.10.10.26:9200"]
manage_template => true
index => "logstash-nginx-access-%{+YYYY-MM}"
}
} }

4、启动logstash,然后就可以查看日志是否写入elasticsearch中。

Logstash使用grok过滤nginx日志(二)的更多相关文章

  1. Nginx filebeat+logstash+Elasticsearch+kibana实现nginx日志图形化展示

    filebeat+logstash+Elasticsearch+kibana实现nginx日志图形化展示   by:授客  QQ:1033553122   测试环境 Win7 64 CentOS-7- ...

  2. Logstash使用grok解析IIS日志

    Logstash使用grok解析IIS日志 1. 安装配置 安装Logstash前请确认Elasticsearch已经安装正确,参见RedHat6.4安装Elasticsearch5.2.0. 下载链 ...

  3. 通过filebeat、logstash、rsyslog采集nginx日志的几种方式

    由于nginx功能强大,性能突出,越来越多的web应用采用nginx作为http和反向代理的web服务器.而nginx的访问日志不管是做用户行为分析还是安全分析都是非常重要的数据源之一.如何有效便捷的 ...

  4. 使用Logstash filter grok过滤日志文件

    Logstash提供了一系列filter过滤plugin来处理收集到的log event,根据log event的特征去切分所需要的字段,方便kibana做visualize和dashboard的da ...

  5. logstash通过kafka传输nginx日志(三)

    单个进程 logstash 可以实现对数据的读取.解析和输出处理.但是在生产环境中,从每台应用服务器运行 logstash 进程并将数据直接发送到 Elasticsearch 里,显然不是第一选择:第 ...

  6. logstash 使用grok正则解析日志

    http://xiaorui.cc/2015/01/27/logstash%E4%BD%BF%E7%94%A8grok%E6%AD%A3%E5%88%99%E8%A7%A3%E6%9E%90%E6%9 ...

  7. elasticsearch+logstash+redis+kibana 实时分析nginx日志

    1. 部署环境 2. 架构拓扑 3. nginx安装 安装在192.168.176.128服务器上 这里安装就简单粗暴了直接yum安装nginx [root@manager ~]# yum -y in ...

  8. ELK实践(二):收集Nginx日志

    Nginx访问日志 这里补充下Nginx访问日志使用的说明.一般在nginx.conf主配置文件里需要定义一种格式: log_format main '$remote_addr - $remote_u ...

  9. ELK 6安装配置 nginx日志收集 kabana汉化

    #ELK 6安装配置 nginx日志收集 kabana汉化 #环境 centos 7.4 ,ELK 6 ,单节点 #服务端 Logstash 收集,过滤 Elasticsearch 存储,索引日志 K ...

随机推荐

  1. ofbiz学习笔记01--多表关联查询

    不管做什么项目,肯定会用到多表关联查询数据,从网络查询得知ofbiz有三种多表关联查询方法 实现一:Screem.xml 中的 section 里,加 <action>, 加 get-re ...

  2. MVC使用RDL报表

    MVC使用RDL报表 这次我们来演示MVC3怎么显示RDL报表,坑爹的微软把MVC升级到5都木有良好的支持报表,让MVC在某些领域趋于短板 我们只能通过一些方式来使用rdl报表. Razor视图不支持 ...

  3. Csharp Syntactic sugar

    C#语法糖(Csharp Syntactic sugar)大汇总 首先需要声明的是“语法糖”这个词绝非贬义词,它可以给我带来方便,是一种便捷的写法,编译器会帮我们做转换:而且可以提高开发编码的效率,在 ...

  4. [Usaco2008 Open] Clear And Present Danger 寻宝之路[最短路][水]

    Description     农夫约翰正驾驶一条小艇在牛勒比海上航行.     海上有N(1≤N≤100)个岛屿,用1到N编号.约翰从1号小岛出发,最后到达N号小岛.一 张藏宝图上说,如果他的路程上 ...

  5. usaco 1.2.1(指针技巧)

    ★Milking Cows 挤牛奶 三个农民每天清晨 5 点起床,然后去牛棚给 3 头牛挤奶.第一个农民在 300 时刻(从 5 点开始计时,秒为单位)给他的牛挤奶,一直到 1000 时刻.第二个农民 ...

  6. 初探中间件(middleware)

    初探中间件(middleware) 因为考虑到文章的长度, 所以 BaseHandler 的展开被推迟了. 在 BaseHandler 中隐藏着中间件的信息, 较常见的 SessionMiddlewa ...

  7. #define命令的一些高级用法

    =========================================================== define中的三个特殊符号:#,##,#@ ================= ...

  8. JavaScript判断对象的类型

    JavaScript判断对象的类型 最近阅读了一些关于JavaScript判断对象类型的文章.总结下来,主要有constructor属性.typeof操作符.instanceof操作符和Object. ...

  9. Lua里的"switch-case"语句

    Lua本身并没有提供switch-case语句,难道说我们就只能靠不断的"if ... elseif ... "这样冗长的方式来实现选择的功能么?当然不是这样的.Lua提供了功能强 ...

  10. A*算法&博弈树α-β剪枝

    A*算法&博弈树α-β剪枝 A*算法/博弈树 前阵子考试学了A*算法.博弈树和回溯,自己真是愚蠢至极,根本没就搞明白这些,所以对于这些算法问道的话就不能说清楚,也记不住,所以才有了这篇笔记.在 ...