You could stash the directory name in a ruby class variable (so that it can be accessed from both ruby filter instances)
if [message] =~ "^$|<DIR>| File\(s\)| Dir\(s\)" { drop {} }
if "Directory of" in [message] {
grok { match => { "message" => "Directory of %{GREEDYDATA:dirName}" } }
ruby { code => '@@dirName = event.get("dirName")' }
drop {}
}
grok { match => { "message" => "^(?<[@metadata][timestamp]>\d{2}/\d{2}/\d{4} \d{2}:\d{2} (AM|PM))%{SPACE}%{NOTSPACE:filesize} (?<[@metadata][filename]>[^\n]*)" } }
mutate { convert => { "filesize" => "integer" } }
date { match => [ "[@metadata][timestamp]", "MM/dd/yyyy hh:mm aa" ] }
ruby { code => 'event.set("filename", @@dirName + "\\" + event.get("[@metadata][filename]"))' }
}
which will produce things like
"filesize" => 40960,
"filename" => "C:\\Windows\\ADFS\\Microsoft.IdentityServer.Deployment.Core.dll",
"message" => "04/30/2021 09:24 AM 40,960 Microsoft.IdentityServer.Deployment.Core.dll",
"@timestamp" => 2021-04-30T13:24:00.000Z
Not sure if you want to use @timestamp for the timestamp.
You will need pipeline.workers set to 1 and pipeline.ordered set to auto (the default in 7.0) or true.