从nginx日志中进行url解析

/v1/test?param2=v2&param3=v3&time=2019-03-18%2017%3A34%3A14
->
{'param1':'v1','param2':'v2','param3':'v3','time':'2019-03-18 17:34:14'}

nginx日志示例:

1.119.132.168 - - [18/Mar/2019:09:13:50 +0000] "POST /param1/test?param2=1&param3=2&time=2019-03-18%2017%3A34%3A14 HTTP/1.1" 200 929 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36" "-"

1 使用grok

input {

      file {

        path => [ "/var/log/nginx/access.log" ]
start_position => "beginning"
}
}
filter {
if [message] =~ /test/ {
grok {
match => { "message" => "%{IPORHOST:client_ip} (%{USER:ident}|-) (%{USER:auth}|-) \[%{HTTPDATE:access_time_raw}\] \"(?:%{WORD:verb} (/%{PARAMVALUE:param1}/test\?param2=%{PARAMVALUE:param2}&param3=%{PARAMVALUE:param3}&time=%{PARAMVALUE:send_time_raw})(?: HTTP/%{NUMBER:http_version})?|-)\" (%{NUMBER:response}|-) (?:%{NUMBER:bytes}|-) %{QS:referrer} %{QS:agent} %{QS:x_forward_for}" }
pattern_definitions => { "PARAMVALUE" => "[^& ]*" }
}
urldecode {
all_fields => true
}
date {
match => [ "access_time_raw","dd/MMM/yyyy:HH:mm:ss Z"]
target => "access_time_tmp"
}
ruby {
code => "event.set('access_time', (event.get('access_time_tmp').to_i * 1000000).to_s)
event.set('send_time', event.get('access_time'))"
}
if [send_time_raw] {
date {
match => [ "send_time_raw","yyyy-MM-dd HH:mm:ss"]
target => "send_time_tmp"
timezone => "UTC"
}
ruby {
code => "event.set('send_time', (event.get('send_time_tmp').to_i * 1000000).to_s)"
}
}
mutate {
remove_field => ["message", "ident", "auth", "verb", "bytes", "reponse", "x_forward_for", "http_version", "access_time_raw", "access_time_tmp", "path", "response", "send_time_raw", "send_time_tmp"]
}
} else {
drop {}
}
}
output {
if [param1] and [param2] and [param3] and "_grokparsefailure" not in [tags] {
stdout {codec => json}
}
}

注意:
1)对url的参数名和位置硬编码,不灵活
2)使用自定义pattern:PARAMVALUE
3)一定要使用urldecode,否则time得到的value为2019-03-18%2017%3A34%3A14,logstash中date插件使用joda解析pattern会报错,因为含有字母A;
4)如果time为空,则使用access_time;
5)不匹配的记录drop掉;
6)只有满足条件的记录才会被output;
7)在filter和output中使用if-else定义分支;
8)date插件要注意timezone,否则会按照时区偏移;

2 使用grok+ruby


input {
    file {
      path => [ "/var/log/nginx/access.log" ]
      start_position => "beginning"
    }
  }


filter {
if [message] =~ /test/ {
grok {
match => { "message" => "%{IPORHOST:client_ip} (%{USER:ident}|-) (%{USER:auth}|-) \[%{HTTPDATE:access_time_raw}\] \"(?:%{WORD:verb} (%{URIPATHPARAM:request}|-)(?: HTTP/%{NUMBER:http_version})?|-)\" (%{NUMBER:response}|-) (?:%{NUMBER:bytes}|-) %{QS:referrer} %{QS:agent}" }
}
urldecode {
all_fields => true
}
date {
match => [ "access_time_raw","dd/MMM/yyyy:HH:mm:ss Z"]
target => "access_time_tmp"
}
ruby {
code => "event.set('access_time', (event.get('access_time_tmp').to_i * 1000000).to_s)
event.set('send_time', event.get('access_time'))"
}
if [request] {
ruby {
          init => "
          def convertName(name)
              result = ''
              name.each_char{|ch| result += (if ch < 'a' then '_' + ch.downcase else ch end)}
              result
          end
          "
code => "
event.set('param1', event.get('request').split('?')[0].split('/')[1])
pairs = event.get('request').split('?')[1].split('&')
pairs.each{ |item| arr=item.split('='); event.set(arr[0], arr[1])}
"
}
if [time] {
date {
match => [ "time","yyyy-MM-dd HH:mm:ss"]
target => "send_time_tmp"
timezone => "UTC"
}
ruby {
code => "event.set('send_time', (event.get('send_time_tmp').to_i * 1000000).to_s)"
}
}
}
mutate {
remove_field => ["message", "ident", "auth", "verb", "bytes", "reponse", "x_forward_for", "http_version", "access_time_raw", "access_time_tmp", "path", "response", "time", "send_time_tmp"]
}
} else {
drop {}
}
}
output {
if [param1] and [param2] and [param3] and "_grokparsefailure" not in [tags] {
stdout {codec => json}
}
}

注意:
1)直接使用默认的nginx日志的grok pattern;
2)在ruby中直接按照key=value进行解析,更灵活;
3)自定义函数;

logstash的ruby代码中getter和setter必须使用代码,比如event.get('field'),不能使用event['field'],因为

[2019-03-19T17:15:32,729][ERROR][logstash.filters.ruby ] Ruby exception occurred: Direct event field references (i.e. event['field'] = 'value') have been disabled in favor of using event get and set methods (e.g. event.set('field', 'value')). Please consult the Logstash 5.0 breaking changes documentation for more details.

3 使用grek+kv

input {
file {
path => [ "/data/tmp/access.log" ]
start_position => "beginning"
}
} filter {
if [message] =~ /dataone\/u1/ {
grok {
match => { "message" => "%{IPORHOST:client_ip} (%{USER:ident}|-) (%{USER:auth}|-) \[%{HTTPDATE:access_time_raw}\] \"(?:%{WORD:verb} (%{URIPATHPARAM:request}|-)(?: HTTP/%{NUMBER:http_version})?|-)\" (%{NUMBER:response}|-) (?:%{NUMBER:bytes}|-) %{QS:referrer} %{QS:agent}" }
}
kv {
source => "request"
field_split => "&?"
value_split => "="
}
urldecode {
all_fields => true
}
date {
match => [ "access_time_raw","dd/MMM/yyyy:HH:mm:ss Z"]
target => "access_time_tmp"
}
ruby {
code => "event.set('access_time', (event.get('access_time_tmp').to_i * 1000000).to_s)
event.set('send_time', event.get('access_time'))"
}
if [send_time_raw] {
date {
match => [ "send_time_raw","yyyy-MM-dd HH:mm:ss"]
target => "send_time_tmp"
}
ruby {
code => "event.set('send_time', (event.get('send_time_tmp').to_i * 1000000).to_s)"
}
}
mutate {
remove_field => ["message", "ident", "auth", "verb", "bytes", "reponse", "x_forward_for", "http_version", "access_time_raw", "access_time_tmp", "path", "response", "send_time_raw", "send_time_tmp"]
}
} else {
drop {}
}
}

参考:https://www.elastic.co/guide/en/logstash/current/plugins-filters-kv.html

【原创】大数据基础之Logstash(3)应用之file解析(grok/ruby/kv)的更多相关文章

  1. 【原创】大数据基础之Zookeeper(2)源代码解析

    核心枚举 public enum ServerState { LOOKING, FOLLOWING, LEADING, OBSERVING; } zookeeper服务器状态:刚启动LOOKING,f ...

  2. 【原创】大数据基础之Logstash(1)简介、安装、使用

    Logstash 6.6.2 官方:https://www.elastic.co/products/logstash 一 简介 Centralize, Transform & Stash Yo ...

  3. 【原创】大数据基础之Logstash(4)高可用

    logstash高可用体现为不丢数据(前提为服务器短时间内不可用后可恢复比如重启服务器或重启进程),具体有两个方面: 进程重启(服务器重启) 事件消息处理失败 在logstash中对应的解决方案为: ...

  4. 【原创】大数据基础之Logstash(3)应用之http(in和out)

    一个logstash很容易通过http打断成两个logstash实现跨服务器或者跨平台间数据同步,比如原来的流程是 logstash: nginx log -> kafka 打断成两个是 log ...

  5. 【原创】大数据基础之Logstash(2)应用之mysql-kafka

    应用一:mysql数据增量同步到kafka 1 准备mysql测试表 mysql> create table test_sync(id int not null auto_increment, ...

  6. 【原创】大数据基础之Logstash(5)监控

    有两种方式来监控logstash: api ui(xpack) When you run Logstash, it automatically captures runtime metrics tha ...

  7. 【原创】大数据基础之Logstash(6)mongo input

    logstash input插件之mongodb是第三方的,配置如下: input { mongodb { uri => 'mongodb://mongo_server:27017/db' pl ...

  8. 【原创】大数据基础之词频统计Word Count

    对文件进行词频统计,是一个大数据领域的hello word级别的应用,来看下实现有多简单: 1 Linux单机处理 egrep -o "\b[[:alpha:]]+\b" test ...

  9. 【原创】大数据基础之Impala(1)简介、安装、使用

    impala2.12 官方:http://impala.apache.org/ 一 简介 Apache Impala is the open source, native analytic datab ...

随机推荐

  1. Android五大布局

    原文地址:http://blog.51cto.com/liangruijun/632532 https://www.cnblogs.com/devinzhang/archive/2012/01/19/ ...

  2. 一个强大的VS代码搜索工具

    最近一直在寻找一款VS代码搜索插件,终于找到了一个不错的,仅支持vs2012以上. https://marketplace.visualstudio.com/items?itemName=mario- ...

  3. luogu 2480 古代猪文 数论合集(CRT+Lucas+qpow+逆元)

    一句话题意:G 的 sigma d|n  C(n d) 次幂  mod 999911659 (我好辣鸡呀还是不会mathjax) 分析: 1.利用欧拉定理简化模运算 ,将上方幂设为x,则x=原式mod ...

  4. 函数语法:原生JS获取数组的索引值index

    var lis = document.getElementsByTagName("li"); for(var i=0;i<lis.length;i++) { lis[i].i ...

  5. MySQL数据库的版本更新方法

    MySQL数据库的版本更新很快,新的特性也随之不断的更新,更主要的是解决了很多影响我们应用的BUG,为了让我们的MySQL变得更美好,我们有必要去给它升级,尽管你会说它现在已经跑得很好很稳定完全够用了 ...

  6. rpmlib(PayloadIsLzma) <= 4.4.6-1 is needed【转载】

    以下为转载,但是有改动,原作者在一处写错了,将高写成了低,直接差之毫厘,谬之千里. 环境: centos el5 背景: 由于个人比较喜欢用软件的最新版本,在重新安装服务器上的 xdg-open(还有 ...

  7. 更新glibc版本,有问题,有三篇博客的命令看不懂

    https://blog.csdn.net/glongljl/article/details/80156243 https://blog.csdn.net/officercat/article/det ...

  8. Spring学习1:Spring基本特性

    http://longliqiang88.github.io/2015/08/14/Spring%E5%AD%A6%E4%B9%A01%EF%BC%9ASpring%E5%9F%BA%E6%9C%AC ...

  9. springboot+layui实现PC端用户的增删改查 & 整合mui实现app端的自动登录和用户的上拉加载 & HBuilder打包app并在手机端下载安装

    springboot整合web开发的各个组件在前面已经有详细的介绍,下面是用springboot整合layui实现了基本的增删改查. 同时在学习mui开发app,也就用mui实现了一个简单的自动登录和 ...

  10. android listView功能简介

    本文参考连接:http://blog.csdn.net/kesenhoo/article/details/7196920 android中listView是非常常用的组建,下边就经常用到的功能做一下简 ...