Parse ISO 8601 duration format (PT(n)H(n)M(n)S)

You can use grok to parse it

grok { match => { "duration" => "^P(%{NUMBER:[@metadata][duration][y]}Y)?(%{NUMBER:[@metadata][duration][m]}M)?(%{NUMBER:[@metadata][duration][d]}D)?(T(%{NUMBER:[@metadata][duration][h]}H)?(%{NUMBER:[@metadata][duration][min]}M)?(%{NUMBER:[@metadata][duration][sec]}S)?)?" } }

If a group is surrounded by ()? then it can occur zero or more times, i.e. it is optional. Each of the six fields field is parsed by an expression like

(%{NUMBER:[@metadata][duration][y]}Y)?

Plus the Time part is optional, so there is an extra ()? around that.

Note that this has no problem with an invalid specification like "P" with no fields defined. Also NUMBER does not allow comma in numbers so it will fail for "P0,3H", but "P0.333H" is OK. If you need to accept commas it gets more complicated.

No duration that includes years, months or days can be unambiguously converted to seconds (think leap second and leap year) unless it is anchored to form a time interval. To do the conversion for the T fields you can use

    ruby {
        code => '
            hours = event.get("[@metadata][duration][h]").to_f
            mins = event.get("[@metadata][duration][min]").to_f
            secs = event.get("[@metadata][duration][sec]").to_f
            event.set("durationInSecs", 3600 * hours + 60 * mins + 1 * secs)
        '
    }