如何使用Logstash处理多个不同类型的输入?

101
假设您有两种非常不同类型的日志,例如技术和业务日志,并且您希望:
  • 原始技术日志使用gelf输出路由到graylog2服务器,
  • JSON业务日志使用专用的elasticsearch_http输出存储到elasticsearch集群中。
我知道例如使用Syslog-NG,配置文件允许定义多个不同的输入,然后可以在分发之前单独处理它们;但是Logstash似乎不能这样做。即使可以使用两个特定的配置文件启动一个实例,所有日志都占用相同的通道并且应用相同的处理...
我应该运行与我拥有的不同类型的日志一样多的实例吗?

2
你应该接受Ben Lim的正确答案! - Ben Wheeler
3个回答

198

我需要运行与不同日志类型相同数量的实例吗?

不需要!您只需运行一个实例来处理不同类型的日志。

在logstash配置文件中,您可以使用不同的type指定每个输入。 然后在筛选器中,您可以使用if来区分不同的处理方式, 并且在输出时,您还可以使用“if”输出到不同的目的地。

input {
    file {
            type => "technical"
            path => "/home/technical/log"
    }
    file {
            type => "business"
            path => "/home/business/log"
    }
} 
filter {
    if [type] == "technical" {
            # processing .......
    }
    if [type] == "business" {
            # processing .......
    }
}
output {
    if [type] == "technical" {
            # output to gelf
    }
    if [type] == "business" {
            # output to elasticsearch
    }
}

希望这可以帮到你 :)


1
您还可以在过滤器和输出定义中使用type属性(使用相同的type => "value"语法),这应该会减少配置文件中的额外格式化。示例:https://gist.github.com/fairchild/3030472 根据文档:将“type”字段添加到此输入处理的所有事件中。类型主要用于过滤器激活。类型存储为事件本身的一部分,因此您也可以使用类型在Web界面中搜索它。 - Tony Cesaro
5
看起来Ben提供的是实现这个功能的新方式。当我在输出中使用type => "value"时,会显示以下信息:“您正在使用在stdout中设置的已弃用的配置设置”type“。已弃用的设置将继续工作,但计划从logstash中删除。您可以使用新的条件语句来实现相同的行为,例如:`if [type] ==“sometype”{stdout {...}}”。"我收回之前的评论。 :) - Tony Cesaro
1
请注意,如果输入中已经有一个类型字段,则type属性不会应用。这是一个特殊的属性,不会覆盖并且已经记录在案。我在Elastic中打开了一张工单,他们建议我使用tagsadd_field代替type - BornToCode
@BornToCode,我不太明白。你是说Ben的代码有问题吗?还是说如果日志路径是同一个文件,它就无法工作?在什么情况下它不能工作? - Ben Wheeler
2
@BenLim,楼主没有接受你的答案,但我发现它非常有帮助,给你点了赞。 - bigbadmouse
显示剩余2条评论

18

我使用了多文件输入的标签:

input {
    file {
        type => "java"
        path => "/usr/aaa/logs/stdout.log"
        codec => multiline {
            ...
        },
        tags => ["aaa"]
    }

    file {
        type => "java"
        path => "/usr/bbb/logs/stdout.log"
        codec => multiline {
                ...
        }
        tags => ["bbb"]
    }
}
output {
    stdout {
        codec => rubydebug
    }
    if "aaa" in [tags] {
        elasticsearch {
            hosts => ["192.168.100.211:9200"]
            index => "aaa"
            document_type => "aaa-%{+YYYY.MM.dd}"
        }
    }

    if "bbb" in [tags] {
        elasticsearch {
            hosts => ["192.168.100.211:9200"]
            index => "bbb"
            document_type => "bbb-%{+YYYY.MM.dd}"
        }
    }
}

1
这比被接受的答案更好:它允许在Logstash中使用多个Filebeat输入。在这种情况下,“type”属性设置为“log”,不能修改。 - Régis B.
但是这不是用最后一个标签(bbb)覆盖标签吗? 然后,如果标签是数组或单个字符串,则if语句中的两个IF都将起作用。因此从逻辑上讲,这是不正确的,但也许logstash在if语句内部有不同的逻辑。 - meso_2600

0

我认为logstash无法在输入部分读取超过2个文件。请尝试以下方法:

input {
    file {
            type => "technical"
            path => "/home/technical/log"
    }
    file {
            type => "business"
            path => "/home/business/log"
    }
 file {
            type => "business1"
            path => "/home/business/log1"
    }
} 

是的,遇到了相同的“问题”。 - meso_2600

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接