Skip to main content

Function Library — Lookups

The C.Lookup family reads a CSV file from inside a JavaScript script. Four constructors differ only in how they match the key column:

ConstructorMatching
C.Lookup(file, keyColumn, columns, ignoreCase)Exact string match
C.LookupIgnoreCase(file, keyColumn, columns)Exact match, case-insensitive
C.LookupCIDR(file, keyColumn, columns)The key column holds CIDR ranges
C.LookupRegex(file, keyColumn, columns)The key column holds regular expressions

Each returns an object with a single match() method. Where the key column is omitted, the file's first column is used. Where the column list is omitted or empty, every column is available.

For enrichment across a whole pipeline, prefer the Lookup processor and Scheduled Lookup Sources — those are managed, refreshed on a schedule, and visible in the interface. These functions are for a lookup that only makes sense inside a larger piece of script logic.

Matching

match() behaves differently according to what you pass as its second argument:

CallReturns
match(value)true where a row matches
match(value, 'column')That column's value, or undefined
match(value, ['a', 'b'])An object holding those columns
match(value, [])An object holding every available column

Resolve a site name and an owner from a host inventory...

{
"host": "web-01"
}
- script:
lang: js
source: |
const hosts = C.Lookup('inventory.csv', 'host');
const row = hosts.match(__e.host, ['site', 'owner']);
if (row !== undefined) {
__e.site = row.site;
__e.owner = row.owner;
}

A host with no row leaves the event unchanged...

{
"host": "web-01",
"site": "ams-1",
"owner": "platform"
}

Details

Files

A relative path resolves against the Director's configured lookup directory; an absolute path is used as given.

Files are read once and cached, and re-read when the file's modification time or size changes.

A file larger than 10 MB is not loaded. Neither is one that is missing or unreadable. In each case the constructor still succeeds and returns a lookup that never matches — it does not throw, and nothing in the pipeline reports the problem. Where a lookup silently produces no results, check the file first.

Resolution Order

Where several rows match the same input, exact and regular-expression lookups both take the last matching row in file order.

CIDR lookups take the most specific match — the longest prefix — and fall back to the last row in file order where two ranges are equally specific. A bare address in the key column is treated as a single-host range.

Regular Expressions

C.LookupRegex() compiles each row's key column as a pattern and tests the input against it. Each pattern gets 100 milliseconds to match; one that exceeds it is treated as a non-match for that row rather than failing the script.

warning

A blank line anywhere in a file used with C.LookupRegex() makes match(value) return true for every input, because the empty pattern matches everything. Column lookups are unaffected. Strip trailing blank lines from regular-expression lookup files.

Reuse

Build the lookup once per script and reuse the handle:

const geo = C.LookupCIDR('subnets.csv', 'cidr');
__e.site = geo.match(__e['source.ip'], 'site');
__e.dest_site = geo.match(__e['destination.ip'], 'site');