文档章节

自定义filter 绕过logstash的date插件处理UTC时间

二两豆腐
 二两豆腐
发布于 2016/09/30 14:40
字数 993
阅读 5.8K
收藏 2

码上生花,ECharts 作品展示赛正式启动!>>>

马上十一了,吾等无心工作,一心只想尽快的为祖国母亲庆生,等待之余放出来一个我解决logstash日期filter的实践。
使用logstash  @timestamp 取出来的日志格式为UTC时间,也就是说比中国的用户早了8个小时,这样导致我们在查询的时候的时候不能按照我们我们自己时间进行查询,还得做把这个时间减去8个小时。带来了很大的不便,尝试了设定时区依然无法更改这个日期,所以只能自己通过其他方式diy了。    

既然这样,采用不使用它的@timestamp的方法,那就自己新增字段,曲线救国。

nginx的日志配置格式为:

 log_format access ‘$remote_addr – $remote_user [$time_local] "$request" "$status $body_bytes_sent "$http_referer" '"$http_user_agent" $http_x_forwarded_for';


首先放出来一条常见的nginx日志记录
 

127.0.0.1 - - [30/Sep/2016:14:18:33 +0800] "GET / HTTP/1.1" 200 396 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0"

看到了吧,30/Sep/2016:14:18:33 +0800  这一段就是访问的真正时间,也就是$time_local 这个字段匹配出来的,这个格式是ISO8601格式,但是我们常用的是yyyy-MM-dd格式的,nginx的日志格式又没法变更,如果想变更的话,只能修改nginx的源码,重新打包nginx安装,比较麻烦。既然这样,我们就手工的去解析这个字符串,然后组装成我们需要的格式,再进行输出出去。

首先增加三个字段,年月日均指向%{timestamp},

add_field => {"access_year" => "%{timestamp}"}
add_field => {"access_month" => "%{timestamp}"}
add_field => {"access_day" => "%{timestamp}"}


这三个字段可以在任何的filter中,但是要在grok filter下面,例如我放在了urldecode中,如下

urldecode {
        add_field => {"access_year" => "%{timestamp}"}
                add_field => {"access_month" => "%{timestamp}"}
                add_field => {"access_day" => "%{timestamp}"}
        all_fields => true
    }

然后通过定义正则表达式,分别把年月日匹配出来

mutate{
        
        gsub =>[
            "access_year","[\W\w]*/|:[\s\S]*",""
        ]
        gsub => [
             "access_month","[(\d+/)|(/\d+)]|:[\s\S]*",""   
        ]
        gsub =>[
             "access_day","/[\s\S]*|:[\s\S]*",""
            ]
    }

实际上以上正则表达式也就是字符串30/Sep/2016:14:18:33 +0800中的年月日匹配出来

匹配出年

匹配出月

匹配出日

但是这时候我们匹配出来的月份是用英文表示的而不是数字,可以通过translate来进行转换
 

translate{
        exact => true
        regex => true
        dictionary => [
            "Jan","01",
            "Feb","02",
            "Mar","03",
            "Apr","04",
            "May","05",
            "Jun","06",
            "Jul","07",
            "Aug","08",
            "Sep","09",
            "Oct","10",
            "Nov","11",
            "Dec","12"
        ]
        field => "access_month"
        destination => "access_month_temp"
    }

    最后就可以增加一个我们最终显示的字段,通过把以上临时字段进行任意的组装
 

   alter{
        add_field => {"access_date"=>"%{access_year}-%{access_month_temp}-%{access_day}"}

        remove_field=>["access_year","access_month","access_day","access_month_temp","bytes","ident","auth"]
        remove_tag=>["tags"]
    }

上述增加了一个access_date字段,这个字段出来的格式就是yyyy-MM-dd的,然后通过remove_fileld把中间的临时字段都给删除掉,这样通过logstash添加到redis或者mongodb中的access_date字段就是我们想要的格式了。这个格式可以根据我们的需求随便定义和拼装。
我使用的部分完整文件如下

input { stdin { }
        file {
                path => "/usr/local/nginx/logs/gateway_access.log"
        start_position => beginning
        }
}

filter{

     grok { #通过GROK来自动解析APACHE日志格式
         match => { "message" => "%{COMMONAPACHELOG}" }
    }
    #date{
    #   locale => "en"
    #   timezone => "Asia/Shanghai"
    #   match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
    #}
    kv {
        source => "request"
        field_split => "&?"
        value_split => "="
    }
    urldecode {
        add_field => {"access_year" => "%{timestamp}"}
                add_field => {"access_month" => "%{timestamp}"}
                add_field => {"access_day" => "%{timestamp}"}
        all_fields => true
    }
    mutate{
        
        gsub =>[
            "access_year","[\W\w]*/|:[\s\S]*",""
        ]
        gsub => [
             "access_month","[(\d+/)|(/\d+)]|:[\s\S]*",""   
        ]
        gsub =>[
             "access_day","/[\s\S]*|:[\s\S]*",""
            ]
    }
    translate{
        exact => true
        regex => true
        dictionary => [
            "Jan","01",
            "Feb","02",
            "Mar","03",
            "Apr","04",
            "May","05",
            "Jun","06",
            "Jul","07",
            "Aug","08",
            "Sep","09",
            "Oct","10",
            "Nov","11",
            "Dec","12"
        ]
        field => "access_month"
        destination => "access_month_temp"
    }
    alter{
        add_field => {"access_date"=>"%{access_year}-%{access_month_temp}-%{access_day}"}

        remove_field=>["access_year","access_month","access_day","access_month_temp","bytes","ident","auth"]
        remove_tag=>["tags"]
    }
}
output {
    stdout { codec => rubydebug }
    mongodb {
            collection => "pagelog"
            database => "statistics"
        uri => "mongodb://192.168.1.52:27017"
    }
}

 

 

© 著作权归作者所有

二两豆腐
粉丝 22
博文 105
码字总数 88374
作品 0
朝阳
高级程序员
私信 提问
加载中
请先登录后再评论。
Logstash filter 插件之 date

使用 date 插件解析字段中的日期,然后使用该日期或时间戳作为事件的 logstash 时间戳。对于排序事件和导入旧数据,日期过滤器尤其重要。如果您在事件中没有得到正确的日期,那么稍后搜索它们...

osc_ugxmmsvy
2019/06/24
7
0
filter - date 日期插件

为什么要用插件: 我们希望日志展示的时间就是日志生成的时间,一般日志中都会附加时间,这样方便根据时间查找问题。但在logstash中,默认使用时间值来表示日志的时间,@timestampdate@time...

osc_fhvb0ylb
2019/01/25
5
0
Logstash读取Kafka数据写入HDFS详解

强大的功能,丰富的插件,让logstash在数据处理的行列中出类拔萃 通常日志数据除了要入ES提供实时展示和简单统计外,还需要写入大数据集群来提供更为深入的逻辑处理,前边几篇ELK的文章介绍过...

运维咖啡吧
2019/03/20
931
1
[译]你应该了解的5个 Logstash Filter 插件

原文:5 Logstash Filter Plugins You Need to Know About 译者:neal1991 welcome to star my articles-translator , providing you advanced articles translation. Any suggestion, plea......

neal
2017/10/25
0
0
logstash 写入数据到elasticsearch 索引相差8小时解决办法

问题说明 Logstash用的UTC时间, logstash在按每天输出到elasticsearch时,因为时区使用utc,造成每天8:00才创建当天索引,而8:00以前数据则输出到昨天的索引 # 使用logstash写入elasticsear...

osc_rnrep3wi
2019/08/21
9
0

没有更多内容

加载失败,请刷新页面

加载更多

C# 扩展TaskScheduler实现独立线程池,支持多任务批量处理,互不干扰,无缝兼容Task

为什么编写TaskSchedulerEx类? 因为.NET默认线程池只有一个线程池,如果某个批量任务一直占着大量线程,甚至耗尽默认线程池,则会严重影响应用程序域中其它任务或批量任务的性能。 特点: ...

osc_yizwdm15
昨天
5
0
PowerMock使用详解

1. PowerMock是什么? PowerMock是一个Java模拟框架,用于解决测试问题。 举个例子,你在使用Junit进行单元测试时,并不想让测试数据进入数据库,怎么办?这个时候就可以使用PowerMock,拦截...

osc_jpwyxabk
昨天
15
0
【C语言期末实训】学生学籍管理系统

目录:一,设计要求1,总体要求:2,具体功能:二,设计框架三,程序代码1,声明函数和头文件2,声明结构体3,声明全局变量4,主体启动函数5,主菜单...

osc_2g1pfwhe
昨天
8
0
使用Celery遇到的坑

通过Celery操作云通讯,发送短信验证码报错{'172001':'网络错误'}针对Windows系统,Mac系统不晓得 1、检查是否取消全局证书验证 import ssl# 全局取消证书验证ssl._create_default_http...

osc_7dwwmolq
昨天
5
0
使用Celery遇到的坑

通过Celery操作云通讯,发送短信验证码报错{'172001':'网络错误'}针对Windows系统,Mac系统不晓得 1、检查是否取消全局证书验证 import ssl# 全局取消证书验证ssl._create_default_http...

osc_lhwd57ou
昨天
19
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部