Um dies zu erreichen, müssen Sie ein bisschen Rubin selbst schreiben.
Aber keine Sorge, es ist einfacher als es sich anhört, Sie können einfach in die Logstash-Konfigurationsdatei rubinieren.
Erstens:
- Stellen Sie Ihren Ausgangs Codec
rubydebug
so dass es die Datenstruktur druckt - Sie werden diese identifizieren müssen, welche Felder Sie wollen.
Also für mein Beispiel (der Kürze halber snipped):
Wir sind im rData
Bereich interessiert.
"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
}
],
Wir haben auch einige Beispiele von mehr rData
Felder, wobei der Wert in rubydebug ist:
"rData" => "*\x00\[email protected]\t\b\v\x00\x00\x00\x00\x00\x00 \x04",
die in Elasticsearch Rendering endet als:
"rData": "*\u0000\[email protected]\t\b\u000b\u0000\u0000\u0000\u0000\u0000\u0000 \u0004",
So extrahieren wir dies mit event.get("response")
, so können wir die Existenz testen (notwendig, weil in meinem Fall response
Felder mit keinen Daten sein werden):
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
'
}
}
}
Hinweis - diese prüft die Länge des rData
Wert, und wenn es „lang“ ist dann nimmt sie eine IPv6-Adresse und Formate als Hex ist, und wenn es kurz ist, geht davon aus, dass es IPv4- und Formate wie die herkömmliche ist ' gepunktetes Quad.
Es fügt dann zu einem neuen Unterfeld response.decoded_rdata
hinzu, das wahrscheinlich für elasticsearch nützlicher ist als tieferes Verschachteln.
Wir haben auch einen zusätzlichen Schnipsel haben die ‚byte‘ Codierung des from
/to
/messageId
Feldes zu handhaben, die weitgehend ähnlich ist:
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(""));
'
}