The best way to parse multiple fields is to use pipeline rules. I prefer regex over GROK, but both are supported in pipelines, along with many other methods, such as key value pairs, json parsing, CEF, or GELF parsing, just to name a few.
Pipelines give you a lot more control over the messages, and they have the advantage that they aren’t going to be deprecated, so all your hard work will be preserved for the foreseeable future.
They can be a little intimidating at first, but IMO the power they offer more than offsets the extra effort to learn how to use them. There are several good posts on pipelines and an entire library of pipeline function available via github. (https://github.com/Graylog2/graylog-plugin-pipeline-processor/tree/master/plugin/src/test/resources/org/graylog/plugins/pipelineprocessor)
Here’s an example of a regex rule that would do something similar to what you describe.
DESCRIPTION: Parsing Rule for Cisco Meraki Security Gateway Device IDS-ALERTS events.
rule “Cisco Meraki Security Gateway Parser 01.03 - IDS ALERTS”
//SAMPLE MESSAGES - IDS Alerts
//<134>1 1377449842.514782056 MX84 ids-alerts signature=129:4:1 priority=3 timestamp=1377449842.512569 direction=ingress protocol=tcp/ip src=74.125.140.132:80
//<134>1 1377448470.246576346 MX84 ids-alerts signature=119:15:1 priority=2 timestamp=1377448470.238064 direction=egress protocol=tcp/ip src=192.168.111.254:56240
//To use Sample message for simulations, copy all but the \ characters.
when
has_field(“message”)&&
contains(to_string($message.message),“ids-alerts”)
then
let result = regex((“^<\d+>.+?(\d+)\.(\d+) (\S+) (\S+) signature=(\d+:\d+:\d+) priority=(\d) timestamp=(.+) direction=(\w+) protocol=(.+) src=(\d+.\d+.\d+.\d+):(\d+)$”),to_string($message.message));
set_field(“flow_start_time”, result[“0”]);
set_field(“flow_stop_time”, result[“1”]);
set_field(“device”, result[“2”]);
set_field(“event_type”, result[“3”]);
set_field(“signature”, result[“4”]);
set_field(“priority”, result[“5”]);
set_field(“device_timestamp”, result[“6”]);
set_field(“direction”, result[“7”]);
set_field(“protocol”, result[“8”]);
set_field(“src_ip”, result[“9”]);
set_field(“src_port”, result[“10”]);
end
Hope this helps.