The Docker command docker stats can be given a JSON template:

docker stats --no-stream --format "{\"name\":\"{{ .Name }}\",\"memory\":\"{{ .MemUsage }}\",\"memPerc\":\"{{ .MemPerc }}\",\"netIO\":\"{{.NetIO}}\",\"blockIO\":\"{{.BlockIO}}\",\"PIDs\":\"{{.PIDs}}\"}"

The output lines (expanded here with jq):

{
  "name": "elastalert",
  "memory": "41.54MiB / 125.9GiB",
  "memPerc": "0.03%",
  "netIO": "145MB / 223MB",
  "blockIO": "35.7MB / 28.7kB",
  "PIDs": "2"
}

It is JSON (at least) but still not very machine-readable, because of packing pairs of numbers with units.

Action convert understands memory units, so we can convert these into units of our choice. But first, it's necessary to split the pairs separated with slashes:

- extract:
    input-field: memory
    remove: true
    pattern: '(\S+) / (\S+)'
    output-fields:
    - mem_used
    - mem_total
- extract:
    input-field: netIO
    remove: true
    pattern: '(\S+) / (\S+)'
    output-fields:
    - io_sent
    - io_recv
- extract:
    input-field: blockIO
    remove: true
    pattern: '(\S+) / (\S+)'
    output-fields:
    - block_read
    - block_write

We now have four new variables, each as a number followed by a unit (e.g. mem_used is "41.54MiB")

These can be converted directly into our chosen unit, which is "GiB" (abbreviated as "G") for memory and "MiB" (abbreviated as "M") for I/O:

- convert:
  - mem_used: G
  - mem_total: G
  - io_sent: M
  - io_recv: M
  - block_read: M
  - block_write: M

The resulting data now looks like this:

{
  "name": "elastalert",
  "mem_used": 0.04056640625,
  "mem_total": 125.9,
  "io_sent": 138.28277587890625,
  "io_recv": 212.66937255859375,
  "block_read": 34.046173095703125,
  "block_write": 0.027370452880859375
}

The full pipe definition is here:

name: docker-stats
input:
    exec:
        command: docker stats --no-stream --format "{\"name\":\"{{ .Name }}\",\"memory\":\"{{ .MemUsage }}\",\"memPerc\":\"{{ .MemPerc }}\",\"netIO\":\"{{.NetIO}}\",\"blockIO\":\"{{.BlockIO}}\",\"PIDs\":\"{{.PIDs}}\"}"
actions:
- extract:
    input-field: memory
    remove: true
    pattern: '(\S+) / (\S+)'
    output-fields:
    - mem_used
    - mem_total
- extract:
    input-field: netIO
    remove: true
    pattern: '(\S+) / (\S+)'
    output-fields:
    - io_sent
    - io_recv
- extract:
    input-field: blockIO
    remove: true
    pattern: '(\S+) / (\S+)'
    output-fields:
    - block_read
    - block_write
- convert:
  - mem_used: G
  - mem_total: G
  - io_sent: M
  - io_recv: M
  - block_read: M
  - block_write: M
- remove: [memPerc, PIDs]
output:
    write: console