最近我部署了ELK,并开始通过logstash frowarder从nginx转发日志。
问题是,在elasticsearch (1.4.2)/kibana(4)中,请求的"bytes"值映射为字符串。
I使用随处可见的标准配置
为nginx日志添加了新的模式:
NGUSERNAME [a-zA-Z.@-+_%]+
NGUSER %{NGUSERNAME}
NGINXACCESS %{IPORHOST:http_host} %{IPORHOST:clientip} [%{HTTPDATE:timestamp}] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" %{NUMBER:response} (?:%{NUMBER:bytes}|-) %{QS:referrer} %{QS:agent} %{NUMBER:request_time:float} %{NUMBER:upstream_time:float}
NGINXACCESS %{IPORHOST:http_host} %{IPORHOST:clientip} [%{HTTPDATE:timestamp}] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" %{NUMBER:response} (?:%{NUMBER:bytes}|-) %{QS:referrer} %{QS:agent} %{NUMBER:request_time:float}
为logstash添加这些配置
input {
lumberjack {
port => 5000
type => "logs"
ssl_certificate => "/etc/logstash/tls/certs/logstash-forwarder.crt"
ssl_key => "/etc/logstash/tls/private/logstash-forwarder.key"
}
}
filter {
if [type] == "syslog" {
grok {
match => { "message" => "%{SYSLOGTIMESTAMP:syslog_timestamp} %{SYSLOGHOST:syslog_hostname} %{DATA:syslog_program}(?:[%{POSINT:syslog_pid}])?: %{GREEDYDATA:syslog_message}" }
add_field => [ "received_at", "%{@timestamp}" ]
add_field => [ "received_from", "%{host}" ]
}
syslog_pri { }
date {
match => [ "syslog_timestamp", "MMM d HH:mm:ss", "MMM dd HH:mm:ss" ]
}
} else if [type] == "nginx" {
grok {
match => { "message" => "%{NGINXACCESS}" }
}
date {
match => [ "timestamp" , "dd/MMM/YYYY:HH:mm:ss Z" ]
}
geoip {
source => "clientip"
}
}
}
output {
elasticsearch_http {
host => localhost
}
}
但在elsticsearch中,我看到的是字符串,即使我定义"bytes"为long
(?:%{NUMBER:bytes:long}|-)
有人知道如何将"字节"存储为数字类型吗?
谢谢
您在(?:%{NUMBER:bytes:long}|-)
的正确轨道上,但是"long"不是有效的数据类型。引用grok文档(重点是我的):
您可以选择向您的grok模式添加数据类型转换。默认情况下,所有语义都保存为字符串。如果您希望转换语义的数据类型,例如,将字符串更改为整数,然后使用目标数据类型作为后缀。例如
%{NUMBER:num:int}
,它将num
语义从字符串转换为整数。目前唯一支持的转换是int
和float
。
请注意,这并不控制在Elasticsearch端索引中实际使用的数据类型,只控制发送到Elasticsearch的JSON文档的数据类型(这可能会影响ES使用的映射)。在JSON上下文中,int型和long型没有区别;标量值可以是数字、bool或字符串。