I'm Parsing an XML stream that I'm parsing with Logstash. I have one section of the message that is repetitive and in varying lengths 0 to 24 is the highest I've seen so far:
<anomaly> <typeI>5.243618,20.591172,off</typeI> <typeII>off</typeII> <model id="nanori">0.000000,169.577650</model> <model id="kisorapubu">0.000000,100.000000</model> <model id="cenanoge">41.351352,300.157450</model> </anomaly>
In my filter I first use the xml plugin:
xml {
store_xml => "false"
source => "message"
xpath => [
"/event/detail/anomaly/typeII/text()", "Anom_TypeII",
"/event/detail/anomaly/typeI/text()", "Anom_TypeI",
"/event/detail/anomaly/model/@id", "Anom_ModelName",
"/event/detail/anomaly/model/text()", "Anom_ModelValues",
]
}
Which roles up the model into two arrays, Anom_ModelName and Anom_ModelValues (Taken from kibana)
Anom_ModelName: nanori, kisorapubu, cenanoge
Anom_ModelValues: 0.000000,169.577650 0.000000,100.000000 41.351352,300.157450
I then use an if statement to break those fields up into model named specific output and threshold values.
if [Anom_ModelName][0] =~ /.+/ {
csv {
source => "[Anom_ModelValues][0]"
columns => ["Model_Out", "Model_Thres"]
separator => ","
skip_empty_columns => "true"
}
mutate {
convert => { "Model_Out" => "float" }
convert => { "Model_Thres" => "float" }
add_field => {
"Model_%{Anom_ModelName[0]}Output" => "%{Model_Out}"
"Model%{Anom_ModelName[0]}_Threshold" => "%{Model_Thres}"
}
remove_field => [ "Model_Out", "Model_Thres"]
}
}
And then I copy and paste that, so far I've only done it for the first 11 models, but I know there is probably a much cleaner way using Ruby. And I've tried to implement something like Iteration in Logstash but failed miserably. Oh, and one slight problem, I don't know Ruby. Any help?