美文网首页ELK文集Elasticsearch
Logstash使用grok解析IIS日志

Logstash使用grok解析IIS日志

作者: mvpboss1004 | 来源:发表于2017-04-04 10:33 被阅读281次

    Logstash使用grok解析IIS日志

    1. 安装配置

    安装Logstash前请确认Elasticsearch已经安装正确,参见RedHat6.4安装Elasticsearch5.2.0
    下载链接为:logstash-5.2.0.rpm
    下载完成后,rpm -i logstash-5.2.0.rpm即可安装。
    Logstash默认的配置文件位置为./config/etc/logstash/,后者已经存在,但直接运行依然会报错:

    WARNING: Could not find logstash.yml which is typically located in $LS_HOME/config or /etc/logstash. You can specify the path using --path.settings. Continuing using the defaults
    Could not find log4j2 configuration at path /usr/share/logstash/config/log4j2.properties. Using default config which logs to console
    

    简单起见,直接在Logstash根目录创建软链接即可:

    cd /usr/share/logstash
    ln -s /etc/logstash ./config
    

    设置配置文件实时生效,从而不用频繁地启停Logstash。修改/etc/logstash/logstash.yml
    config.reload.automatic: true

    2. 运行

    与Elasticsearch、Kibana不同,Logstash默认并不作为系统服务安装,我们也不建议作为服务启动。主要原因为:大多数情况下,Elasticsearch、Kibana在每台服务器上只有一个实例,可以作为服务启动;而一个Logstash实例一般只服务于一个数据流,因此一台服务器上经常运行多个实例。
    编写一个配置文件helloworld.conf进行测试。注意,不要把该文件放在/etc/logstash/conf.d下,以避免不同实例间产生混淆,因为该文件夹是Logstash默认读取的文件夹。简单起见,可直接放在Logstash根目录下。

    input { 
        stdin {} 
    }
    output { 
        stdout {}
    }
    

    这是一个命令行输入、命令行输出的Logstash实例,运行成功则说明已配置正确:
    bin/logstash -f helloworld.conf
    虽然如此,很多时候我们还是希望各个Logstash实例能随系统而启动并在后台运行。将其加入计划任务即可:
    @reboot nohup /usr/share/logstash/bin/logstash -f /usr/share/logstash/helloworld.conf > /dev/null &

    3. grok filter解析IIS日志

    Logstash处理日志的核心部分是各种各样的filter插件,其中最强大的是grok。在这里不得不吐槽一下,我工作中最常用的语言是Python,做个网页常用Javascript,最近为了Hadoop家族又把Java捡起来了。而grok filter只支持Ruby,难不成就为这个grok filter还得再学个Ruby……
    幸好,grok可以通过自定义正则表达式进行拓展,结合其他基本filter,基本可以解决常见的日志。grok内置的正则表达式位于:/usr/share/logstash/vendor/bundle/jruby/1.9/gems/logstash-patterns-core-4.0.2/patterns/,可以逐个文件查看,看看有没有可用的正则表达式。
    IIS日志的格式举例如下,实际中的字段随IIS服务器的配置而不同:

    #Fields: date time c-ip cs-username s-ip s-port cs-method cs-uri-stem cs-uri-query sc-status sc-win32-status sc-bytes cs-bytes time-taken cs-version cs-host cs(User-Agent) cs(Referer)
    2010-07-30 01:06:43 192.168.0.102 - 192.168.0.102 80 GET /css/rss.xslt - 304 0 140 358 0 HTTP/1.1 www.mvpboss1004.com Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+5.1;+Trident/4.0;+InfoPath.2;+360SE) -
    

    grok-patterns文件中,有我们需要的基本正则表达式。编辑iis文件,放在patterns文件夹下:

    IIS_LOG %{TIMESTAMP_ISO8601:@timestamp} %{IP:c_ip} %{NOTSPACE:cs_username} %{IP:s_ip} %{NUMBER:s_port} %{WORD:cs_method} %{URIPATH:cs_uri_stem} %{NOTSPACE:cs_uri_query} %{NUMBER:sc_status} %{NUMBER:sc_winstatus} %{NUMBER:sc_bytes} %{NUMBER:cs_bytes} %{NUMBER:time_taken} %{NOTSPACE:cs_version} %{NOTSPACE:cs_host} %{NOTSPACE:cs_useragent} %{NOTSPACE:cs_referer}
    

    通过引用已有的正则表达式,我们可以构建复杂的正则表达式,语法为%{REGEXP:fieldname},从而将一条IIS日志解析成17个字段。而且,IIS_LOG这个正则表达式也可以被别的正则表达式引用,只需将其放在patterns文件夹下。
    在运行前,可以在grok debugger上调试正则表达式,以确保其正确性。
    修改helloworld.conf

    input {
        stdin {
        }
    }
    filter {
        grok {
            match => { "message" => "%{IIS_LOG}" }
        }
    }
    output { 
        stdout {
            codec => rubydebug
        }
    }
    

    再次运行并将上述IIS日志样例输入到命令行,可以得到解析结果:

    mvpboss1004@mvpboss1004-MIIX-700:/usr/share/logstash$ sudo bin/logstash -f helloworld.conf 
    Sending Logstash's logs to /var/log/logstash which is now configured via log4j2.properties
    The stdin plugin is now waiting for input:
    2010-07-30 01:06:43 192.168.0.102 - 192.168.0.102 80 GET /css/rss.xslt - 304 0 140 358 0 HTTP/1.1 www.mvpboss1004.com Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+5.1;+Trident/4.0;+InfoPath.2;+360SE) -
    {
          "cs_version" => "HTTP/1.1",
              "s_port" => "80",
           "cs_method" => "GET",
                "s_ip" => "192.168.0.102",
             "cs_host" => "www.mvpboss1004.com",
            "cs_bytes" => "358",
        "cs_useragent" => "Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+5.1;+Trident/4.0;+InfoPath.2;+360SE)",
         "cs_uri_stem" => "/css/rss.xslt",
             "message" => "2010-07-30 01:06:43 192.168.0.102 - 192.168.0.102 80 GET /css/rss.xslt - 304 0 140 358 0 HTTP/1.1 www.mvpboss1004.com Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+5.1;+Trident/4.0;+InfoPath.2;+360SE) -",
                "c_ip" => "192.168.0.102",
          "time_taken" => "0",
        "cs_uri_query" => "-",
           "sc_status" => "304",
          "@timestamp" => 2017-02-09T15:37:19.384Z,
            "sc_bytes" => "140",
            "@version" => "1",
                "host" => "mvpboss1004-MIIX-700",
         "cs_username" => "-",
        "sc_winstatus" => "0",
          "cs_referer" => "-"
    }
    

    4. 输出到Elasticsearch

    现在已经验证了解析的正确性,我们将输出从stdout改为elasticsearch。生产环境中,还需要考虑以下问题:

    • 输出中带有一些Logstash附加的字段,这是我们不一定需要的,需要将其过滤掉;
    • message字段是原始的输入日志,我们建议以以下方法进行处理:
    • 如果解析正确,把结果放入mvpboss1004这一index,并过滤掉message;
    • 如果解析错误,把结果放入failure这一index,保留所有的字段以查找错误原因。

    过滤的问题,可以使用mutate filter。条件判断的问题,grok会为解析失败的日志打上_grokparsefailurede的标签,可以利用这一标签判断是否进行过滤及输出的index。修改helloworld.conf

    input {
        stdin {
        }
    }
    filter {
        grok {
            match => { "message" => "%{IIS_LOG}" }
        }
        if !([tags] and "_grokparsefailure" in [tags]) {
            mutate {
                remove_field => ["message", "@version", "host"]
            }
        }
    }
    output {
        if [tags] and "_grokparsefailure" in [tags] {
            elasticsearch {
                hosts => ["99.1.36.164"]
                index => "failure"
                document_type => "iislog"
            }
        } else {
            elasticsearch {
                hosts => ["99.1.36.164"]
                index => "mvpboss1004"
                document_type => "iislog"
            }
        }
    }
    

    相关文章

      网友评论

        本文标题:Logstash使用grok解析IIS日志

        本文链接:https://www.haomeiwen.com/subject/ahuaottx.html