我有一个protobuf,我试图通过logstash提供。有些值看起来是二进制格式的:
通过rubydebug
编解码器
我得到的价值如下:
rData => '\xD8:\xC9$'
这似乎是因为protobuf
模板有:
optional :bytes, :rData, 5
其中......在锡上执行的操作 - 将原始字节传递给logstash,后者假定它们是文本。
因此,rData
行将解码为216.58.201.36
,这是www.google.com
的响应。
如何在弹力搜索中将其转换为有用的格式?
答案 0 :(得分:0)
为了实现这一目标,你需要自己写一点红宝石。
但不要担心,它比听起来容易,你可以将ruby内联到logstash配置文件中。
首先:
rubydebug
,以便打印数据结构 - 您需要这样来识别您想要的字段。 所以对于我的例子(为了简洁起见):
我们对rData
字段感兴趣。
"socketProtocol" => 1,
"@timestamp" => 2017-12-12T10:26:41.910Z,
"requestorId" => "",
"port" => 47788,
"response" => {
"rcode" => 0,
"rrs" => [
[0] {
"rType" => 1,
"rData" => "\xD8:\xC9$",
"rClass" => 1,
"rName" => "www.google.com.",
"rTtl" => 300
}
],
我们还有一些较长rData
字段的示例,其中rubydebug中的值为:
"rData" => "*\x00\x14P@\t\b\v\x00\x00\x00\x00\x00\x00 \x04",
最终将其呈现为Elasticsearch:
"rData": "*\u0000\u0014P@\t\b\u000b\u0000\u0000\u0000\u0000\u0000\u0000 \u0004",
因此,我们使用event.get("response")
提取此内容,以便我们可以测试存在(必要时,因为在我的用例中会有response
字段没有数据):
filter {
if [response] {
ruby {
code =>
# response rData can be a different things.
#usually an ipV4 address, or an ipv6.
#But they're usually written in different formats - ipv4 is dotted quads,
#where ipv6 is hex and double-bytes
#so we look at the (unpacked) string length, and see if there are 4 (or more) 'uint64s' in there.
#and substitute accordingly.
'
response = event.get("response")
if ( response and response["rrs"] and response["rrs"][0] and response["rrs"][0]["rData"] )
rdata = response["rrs"][0]["rData"]
hex_value = rdata.unpack("H*").join("")
ip_value = rdata.unpack("C4").join(".")
length_rdata = rdata.unpack("L*").length
if ( length_rdata >= 4 )
event.set("[response][decoded_rdata]", hex_value )
else
event.set("[response][decoded_rdata]", ip_value)
end
end
'
}
}
}
注意 - 这会测试rData
值的长度,如果长度超过"然后假设它是一个ipv6地址并格式化为十六进制,如果它是短的,则假设它的ipv4和格式为传统的“点缀”和#39;四。
然后它添加到一个新的子域response.decoded_rdata
,这可能对弹性搜索更有用,而不是嵌套更深。
我们还有一个额外的代码片段来处理'字节' from
/ to
/ messageId
字段的编码大致相似:
ruby {
code =>
#take to and from fields, and assume they're packed IP addresses.
#take messageId and convert to hex.
'event.set("from", event.get("from").unpack("C4").join("."));
event.set("to", event.get("to").unpack("C4").join("."));
event.set("messageId", event.get("messageId").unpack("H*").join(""));
'
}