Skip to main content

Script

Control Flow

Synopsis​

Executes custom scripts and optimized built-in functions to transform and manipulate log data.

Schema​

- script:
source: <string>
lang: <string>
params: <map[string]any>
function: <string>
name: <string>
description: <text>
filter: <script>
if: <script>
id: <ident>
ignore_failure: <boolean>
on_failure: <processor[]>
on_success: <processor[]>
tag: <string>

Configuration​

The following fields are used to define the processor:

FieldRequiredDefaultDescription
sourceY*-Inline script code. Read by the golang/go and javascript/js engines
langY*-Scripting language: "golang" (or "go"), "javascript" (or "js"), or "vmetric"
paramsN-Map of parameters available to the script
functionY*-Name of the predefined function to run. Required by, and only used by, the vmetric engine
nameY*-Name of a Library script to run instead of inline code, written without spaces. When set, lang and source are ignored. See Library Scripts
descriptionN-Explanatory note
filterN-Cribl-style JavaScript truthiness expression evaluated after if. A falsy result silently skips the processor. Distinct from if, which uses the native expression language
ifN-Condition to run
ignore_failureNfalseSee Handling Failures
on_failureN-See Handling Failures
on_successN-See Handling Success
tagN-Identifier
disabledNfalseWhen true, the processor is skipped and the event continues to the next one. Lets you take a processor out of the path without removing its configuration

* = either name, or lang with the field its engine reads: source for the golang/go and javascript/js engines, function for vmetric. Without name, lang is genuinely required: a missing or unrecognized value fails with unsupported script language.

Details​

warning

This processor runs on the Director only. The Agent binary is built without it, so an Agent-side pipeline that configures it fails at runtime with a not supported error rather than skipping the step. Put it in a pipeline the Director runs — a route pipeline or a target postprocessing pipeline — not in an Agent's preprocessing chain.

The processor supports three script engines, selected with lang. Each has its own reference page under Scripting.

JavaScript​

lang: javascript (or js) runs a full script body in a sandboxed JavaScript interpreter. The event is exposed as __e: use __e.field for simple names and __e['field.name'] for names containing dots. Remove a field with delete __e['field']. Values supplied through params arrive as a params object.

A large function library is available under a C namespace — network tests, text parsing, time formatting, masking, encoding and CSV lookups.

- script:
lang: js
source: |
__e.normalized = __e.field.toLowerCase();

Full reference: JavaScript.

Go​

lang: golang (or go) runs a script through a sandboxed bytecode VM. The syntax is Go-like, but this is not Go and the Go standard library is not available. The event is bound to a global named event, and five modules — text, math, times, json and rand — are available through import.

- script:
lang: go
source: |
text := import("text")
event.normalized = text.to_lower(event.field)

Full reference: Go.

Built-in​

lang: vmetric calls one of thirteen functions compiled into the product, named in the function field. These skip script compilation entirely and should be preferred over an equivalent custom script.

- script:
lang: vmetric
function: getNetworkTransport()

Full reference: Built-in Functions.

Library Scripts​

name runs a script kept on the Scripts tab of the Library instead of inline code. The language and the code both come from the Library entry, so the processor's own lang and source are ignored. params reaches the script the same way it reaches an inline one.

- script:
name: NormalizeUser
params:
threshold: 70

Write the name without spaces: a director finds a Library entry by its name with every space removed, so a script named Normalize User is referenced as NormalizeUser.

A director receives a Library script only when a pipeline it runs references it, and only from director version 2.2.0. Otherwise the processor fails with library script "…" not found. Library scripts can be written in JavaScript, Go, PowerShell or Bash, but a director runs only the JavaScript and Go ones: a PowerShell or Bash script fails with script language "…" is not supported by this director yet.

The debugger does not run Library scripts, since it runs on the platform rather than on a director. A processor that names one fails there with library script "…" not found.

Signing​

On a fleet-managed director, one that takes its configuration from the platform, a script runs only when it is signed, unless the organization allows unsigned scripts (see below):

  • A Library script is signed with Sign script on the Scripts tab or on its detail page, which records that this exact code was reviewed. Changing the script's code or language clears the signature. The signature ships to the director beside the script, and the director checks it against the organization's signing keys before it runs any of the code.
  • Inline source cannot be signed, so it is treated as unsigned.
  • Built-in functions (lang: vmetric) are part of the product and always run.

Unsigned scripts, inline or from the Library, run only when Allow unsigned scripts to run is turned on in Content Settings. It is off by default. Otherwise the processor fails with script is not signed by a trusted key and unsigned scripts are not allowed on this director, and ignore_failure and on_failure apply as they do to any other failure.

A director that runs from its local configuration, without fleet management, does not check signatures.

Filter and Condition​

filter and if both gate the processor, and they take different languages. filter is a JavaScript expression evaluated after if, in which a bare field name resolves against the event; if uses DataStream's own expression language. A falsy filter skips the processor silently.

Failure Behavior​

The two script engines differ in what a partial failure leaves behind. JavaScript writes to the event as the script runs, so a script that throws halfway leaves its earlier changes in place. Go writes the event back only on success, so a failed script changes nothing.

Examples​

Go​

Classify by a numeric threshold...

- script:
lang: go
source: |
confidence := event["threat.indicator.confidence"]
if !is_undefined(confidence) && confidence > 70 {
event["threat.level"] = "high"
}

JavaScript​

Normalize a field and tag it with a threshold from params...

{
"user": "John.Doe",
"score": 85
}
- script:
lang: js
params:
threshold: 70
source: |
__e.user = __e.user.toLowerCase();
__e.high = __e.score > params.threshold;

Fields are read and written directly on the event via __e...

{
"user": "john.doe",
"score": 85,
"high": true
}

Built-in​

Process time fields efficiently...

- script:
lang: vmetric
function: processTimeFields("log.time", "log.timestamp", "log.times")

Library Script​

Run a signed Library script by name, passing it a threshold...

- script:
name: ClassifyThreat
params:
threshold: 70

Composite​

Combine a built-in function with custom logic...

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