Hi
I'm moving slowly in this new wold of elastic stack.
I'm currently stuck on a parsing issue with my xml file (ip and nickname removed) :
<inspircdstats>
<userlist>
<user>
<nickname>User1</nickname>
<ipaddress>2a01a:b:c:d:e:f</ipaddress>
<metadata>
<meta name="cloaked_host"/>
<meta name="ssl_cert">vtrsE No certificate was found.</meta>
</metadata>
</user>
<user>
<nickname>User2</nickname>
<ipaddress>90.255.255.255</ipaddress>
<metadata>
<meta name="cloaked_host"/>
</metadata>
</user>
<user>
<nickname>User3</nickname>
<ipaddress>92.255.255.255</ipaddress>
<metadata>
<meta name="cloaked_host"/>
<meta name="ssl_cert">vtrsE No certificate was found.</meta>
</metadata>
</user>
</userlist>
</inspircdstats>
The Metadata name "ssl_cert" means that User1 and User3 are connected over TLS.
User2 is not (metadata/meta[@name='ssl_cert'] is empty).
My current results :
{
"tags" => [
[0] "multiline",
[1] "inspircduser"
],
"host" => "elk",
"timestamp" => 2021-04-12T13:42:12.000Z,
"IpAddress" => [
[0] "2a01a:b:c:d:e:f",
[1] "90.255.255.255",
[2] "92.255.255.255"
],
"type" => "xml",
"NickName" => [
[0] "User1",
[1] "User2",
[2] "User3"
],
"@timestamp" => 2021-04-12T13:53:43.973Z,
"SecureConnection" => [
[0] "vtrsE No certificate was found.",
[1] "vtrsE No certificate was found."
],
"@version" => "1",
"path" => "/tmp/abx_2021-04-12_154212.xml"
}
But, because all arrays don't have the same size (Nickame and IpAddress have 3 values, and SecureConnection only 2)
So it looks like User1 and User2 are on a secure connection which is false.
Obviously, it fails when i'm apply my xml + transpose filter :
xml {
source => "message"
store_xml => false
target => "root"
suppress_empty => false
xpath => [
"/inspircdstats/userlist/user/nickname/text()", "NickName",
"/inspircdstats/userlist/user/ipaddress/text()", "IpAddress",
"/inspircdstats/userlist/user/metadata/meta[@name='ssl_cert']/text()", "SecureConnection"
]
}
ruby {
code => "
event.set('results', [event.get('NickName'), event.get('IpAddress'), event.get('SecureConnection')].transpose)
"
}
split { field => "results" }
mutate {
add_field => {
"nickname" => "%{[results][0]}"
"ipaddress" => "%{[results][1]}"
"secure" => "%{[results][2]}"
}
}
The goal is to generate one event for each user :
{
"host" => "elk",
"timestamp" => 2021-04-12T13:42:12.000Z,
"@timestamp" => 2021-04-12T13:53:43.973Z,
"NickName" => "User1"
"IpAddress" => "2a01a:b:c:d:e:f",
"SecureConnection" => "vtrsE No certificate was found."
"@version" => "1",
"path" => "/tmp/abx_2021-04-12_154212.xml"
}
{
"host" => "elk",
"timestamp" => 2021-04-12T13:42:12.000Z,
"@timestamp" => 2021-04-12T13:53:43.973Z,
"NickName" => "User2"
"IpAddress" => "90.255.255.255",
"SecureConnection" => "Null"
"@version" => "1",
"path" => "/tmp/abx_2021-04-12_154212.xml"
}
{
"host" => "elk",
"timestamp" => 2021-04-12T13:42:12.000Z,
"@timestamp" => 2021-04-12T13:53:43.973Z,
"NickName" => "User3"
"IpAddress" => "92.255.255.255",
"SecureConnection" => "vtrsE No certificate was found."
"@version" => "1",
"path" => "/tmp/abx_2021-04-12_154212.xml"
}
I tried with the suppress_empty = false option on xml block, same result.
Is there a way to tell xpath to set an empty value on the array if the optionnal field is not found ?