Skip to main content

Built-in Functions

Set lang: vmetric on the Script processor to call a function compiled into the product. These bypass script compilation entirely, so where one covers the transformation you need, it is the cheapest way to perform it.

- script:
lang: vmetric
function: sumNetworkBytes()

The function is named in the function field, not source. Naming a function that does not exist fails the processor.

Calling Convention

function takes a call expression: a name, then a parenthesized argument list. Arguments are positional, separated by commas, and each one is a field name — surrounding double quotes are stripped, and whitespace around each argument is trimmed.

function: sumFields("network.bytes", "source.bytes", "destination.bytes")

Several functions take no positional arguments and read their configuration from params instead. The table below marks which.

Functions

FunctionArgumentsEffect
getNetworkTransport()NoneReads network.iana_number and writes the protocol name to network.transport
sumNetworkBytes()NoneWrites source.bytes + destination.bytes to network.bytes
sumNetworkPackets()NoneWrites source.packets + destination.packets to network.packets
sumFields(target, first, second)Three field namesAdds two numeric fields and writes the result to the target field
processTimeFields(main, temp, array)Three field namesNormalizes a time field, using the second and third for intermediate and multi-value handling
translateSyslogPriority()NoneSplits syslog.priority into severity.code and facility.code
translateSyslogFacilityCodeToName()paramsMaps syslog.facility.code to syslog.facility.name
translateSyslogSeverityCodeToName()paramsMaps syslog.severity.code to syslog.severity.name
lowerCaseVendorKeys()NoneRewrites every key under vendor in lowercase
findHostNameBySerial()NoneResolves host.name from observer.serial_number against a configured mapping
setEventDetails(field, remove)Field name, then "true" or "false"Populates the event.* classification fields from params, keyed on the named field's value
aristaEnrichment()paramsPopulates the event.* classification fields from params, keyed on vendor.class
dropEmptyFields()paramsRemoves fields whose value matches any entry in the configured list

Functions that find nothing to act on make no change and do not fail — getNetworkTransport() on an event without network.iana_number, or a syslog translation with no matching code in params, both leave the event untouched. setEventDetails() is the exception; see Event Classification.

Details

Network Transport

getNetworkTransport() recognizes eleven IANA protocol numbers:

Numbernetwork.transportNumbernetwork.transport
0hopopt47gre
1icmp50esp
2igmp51ipv6-icmp
6tcp112vrrp
8egp132sctp
17udp

Any other number leaves network.transport unset.

Syslog Name Translation

The two translation functions take their mapping from params, keyed by the code as a string:

Map severity codes to names...

{
"syslog.severity.code": 3
}
- script:
lang: vmetric
function: translateSyslogSeverityCodeToName()
params:
"0": emergency
"1": alert
"2": critical
"3": error

A code with no entry in params is left alone...

{
"syslog.severity.code": 3,
"syslog.severity.name": "error"
}
warning

The three syslog functions do not chain. translateSyslogPriority() writes severity.code and facility.code at the top level, while the two translation functions read syslog.severity.code and syslog.facility.code. Nothing bridges the two paths.

Running the priority split first therefore leaves the prefixed fields untouched, and each translator then looks up the key "0" — so every event is either left alone or mapped to whatever 0 means in your params, with no error either way.

To use them together, rename the two fields between the calls with a Rename step: severity.code to syslog.severity.code, and facility.code to syslog.facility.code.

Event Classification

setEventDetails() writes five fields from a params map — event.category, event.kind, event.outcome, event.type and event.provider — keyed on the value of the field named in its first argument.

aristaEnrichment() is keyed on vendor.class and writes four of them: event.kind, event.category, event.type and event.provider. For that function event.outcome is an input rather than an output — where the resulting event.category includes network or intrusion_detection, it appends allowed to event.type for an outcome of success, and denied for failure.

warning

setEventDetails() writes all five fields even when the lookup misses. It stops early only when the source field is empty; a value that is simply not a key in params still produces five event.* fields, each set to null. A pipeline keyed on something like event.code will therefore stamp five null fields onto every event whose code is not in the map.

aristaEnrichment() does not do this — it returns before writing anything when vendor.class is absent from params.

Pass "true" as the second argument to setEventDetails() to delete the source field afterwards.

Classify by message ID and drop the original field...

- script:
lang: vmetric
function: setEventDetails("event.code", "true")
params:
"4624":
category: authentication
kind: event
outcome: success
type: start
provider: Microsoft-Windows-Security-Auditing

Dropping Empty Fields

dropEmptyFields() reads the list of values that count as empty from a values key under params, and removes every field holding one of them:

- script:
lang: vmetric
function: dropEmptyFields()
params:
values: ["", "-", "N/A", "null"]

Examples

Total the byte counters...

{
"source.bytes": 1200,
"destination.bytes": 3400
}
- script:
lang: vmetric
function: sumNetworkBytes()

The sum lands in network.bytes...

{
"source.bytes": 1200,
"destination.bytes": 3400,
"network.bytes": 4600
}

Chain a built-in function with a script that refines its result...

- script:
lang: vmetric
function: getNetworkTransport()
- script:
lang: js
source: |
const t = __e['network.transport'];
if (t === 'tcp' || t === 'udp') {
__e['network.type'] = 'ip_traffic';
}