Go
Set lang: golang (or go) on the Script processor to run a
script against each event through a sandboxed bytecode VM.
- script:
lang: go
source: |
text := import("text")
event.host = text.to_lower(event.host)
This is a Go-like scripting language, not Go. The syntax is familiar — :=, if, for, func,
maps and slices — but the Go standard library is not available, and neither are packages, goroutines,
channels, structs, interfaces or pointers. A script is a bare sequence of statements: there is no
package clause and no main function.
The Event
The event is bound to a global named event, a map keyed by field name:
- script:
lang: go
source: |
if event.bytes > 0 {
event.kilobytes = event.bytes / 1024
}
| Operation | Syntax |
|---|---|
| Read a field | event.status |
| Read a field whose name contains a dot | event["source.ip"] |
| Write a field | event.status = "ok" |
| Delete a field | delete(event, "status") |
| Test for a field | !is_undefined(event.status) |
A field that is not present reads as undefined.
The script receives a converted copy of the event and the result is written back after the script finishes successfully. A script that fails, or that exhausts its time budget, leaves the event exactly as it arrived — see Failure Behavior.
Replacing event with anything other than a map fails the processor. So does building a structure that
refers back to itself.
Parameters
Values under params are available as a params map:
- script:
lang: go
params:
threshold: 70
source: |
event.high = event.score > params.threshold
params is a fresh copy on every event. Writes to it are discarded when the event finishes.
Modules
Five modules are available through import:
| Module | Provides |
|---|---|
text | String manipulation, regular expressions, conversion |
math | Numeric functions and constants |
times | Durations, formatting, date arithmetic |
json | encode, decode, and their indented variants |
rand | Pseudo-random numbers |
Import each one before use:
- script:
lang: go
source: |
text := import("text")
json := import("json")
parsed := json.decode(event.payload)
event.user = text.to_lower(parsed.user)
Two functions are deliberately withheld:
times.sleepis removed. A sleeping script would hold a pipeline worker for its full duration without the time budget being able to interrupt it. Calling it fails the script.json.encodeis replaced with a version that rejects self-referential and excessively nested input rather than recursing until the process runs out of stack.
Importing any other module — or importing a file from disk — is not possible.
The built-in string() conversion is also replaced with a guarded version. It behaves the same way on
ordinary values.
Limits
| Constraint | Value |
|---|---|
| Time budget per event | 50 milliseconds |
| Maximum source size | 64 KiB |
| Allocation cap | 50,000 objects |
| Constant pool | 1,000 entries |
All four are fixed and cannot be changed from the pipeline configuration. The time budget is substantially tighter than the JavaScript engine's one second, which makes this engine a poor choice for anything that iterates over a large collection.
A script that exceeds the allocation cap fails with an allocation-limit error rather than consuming memory. A source body over 64 KiB is rejected before it is compiled.
Scripts hold no state between events. Use the Cache Set and Cache Get processors where a value has to survive across events.
Failure Behavior
The engine writes back to the event only after the script has run to completion. A script that fails partway through changes nothing — a compile error, a runtime error, an allocation-limit breach and a timeout all leave the event exactly as it arrived.
This is the opposite of the JavaScript engine, which writes to the event as the script runs and so leaves partial modifications behind when a script throws.
The event continues down the pipeline either way. The processor records the failure in the
_ingest.on_failure_* fields and runs its on_failure
chain, unless ignore_failure is set.
Compilation
Each distinct source string is compiled to bytecode once and reused for every event that reaches it,
across every pipeline that happens to contain the identical text.
Examples
Derive a transport name from a port... | |
The event is written back once the script completes... | |
Parse an embedded JSON payload and promote two of its fields... | |