- 6 minutes to read

Formula Search Field Expression Plugin

The Formula plugin extracts values from a Log Event by combining functions, much like a formula in Microsoft Excel. Use it when a single plugin isn't enough: to extract and then transform a value, to combine values from the body and the context, to count or sum, or to look up a value in a SQL database.

  • ✅ Extract from the message body, context properties, and Log Event fields in one expression
  • ✅ Nest functions: the result of one function is the content of the next
  • ✅ Convert, alter, test, and calculate on the extracted values

Tip

Start with a dedicated plugin such as XPath or JSON Path when it can do the job; see Choose a plugin. Use Formula when you need to combine or transform.


How a Formula Is Evaluated

A formula is evaluated from the inside out. A source function reads data from the Log Event; every other function takes content (the output of the function inside it) and returns new content. The final result becomes the Search Field values.

graph LR A["Log Event"] --> B["Source<br/>body, context, field"] B --> C["Extract<br/>xPath, jsonPath, regex, csv"] C --> D["Convert, Alter,<br/>Logical, Math"] D --> E["Search Field values"] style A fill:#2678BD style B fill:#3F827B style C fill:#E47528 style D fill:#9E59BB style E fill:#93d16d

Diagram: a formula reads a source from the Log Event, extracts values, optionally transforms or tests them, and returns the Search Field values.

Nesting, Step by Step

Input

<Orders>
<Id>3</Id>
<Id>6</Id>
</Orders>

Formula

count(xPath('/Orders/Id', body))

Evaluation

  1. body returns the whole message body.
  2. xPath('/Orders/Id', body) returns two values: 3 and 6.
  3. count(...) counts them.

Result

2

Formula count of two XPath matches in the Test Expression tab
The nested formula returns 2, one value counted per matching Id element.


Formula language rules

These rules apply to every function. Function pages link here instead of repeating them.

Rule Details Example
Content The data a function works on: a source function (body, context, field) or the result of another function. toUpperCase(context('Region'))
body has no parentheses Write body, not body(). regex('\d+', body)
Strings use single quotes Every text argument is enclosed in '…'. Numbers are written as is. substring(0, 3, body)
Escape a single quote by doubling it A literal ' inside a string is written ''. jsonPath('ord''erid', body)
Backslashes are written once Regular expressions use normal .NET syntax; don't double backslashes. regex('\d+', body)
# and spaces in regular expressions Formula regular expressions ignore unescaped whitespace and treat # as the start of a comment, and matching ignores case. Write a literal # as [#] or \# and a literal space as \s or [ ]. 'Order#.*' silently runs as 'Order'. context(regex('Order[#].*'))
context(regex(...)) must match the whole key The text the pattern matches is used as the key to read, so a partial match such as '^Order[#]' finds nothing. End the pattern with .*. context(regex('Order[#].*'))
Function names are case-insensitive xpath, xPath, and XPATH all work. The reference tables write them in camelCase; examples show them exactly as typed in their screenshot. jsonpath('a[*].b', body)
Several values flow through Extract functions can return several values. The next function handles each value, and Math functions aggregate them. count(jsonPath('a[*].b', body))
Search Field values are unique The values stored on a Search Field are unique; duplicates are collapsed. The test bench shows the Number of unique matches. Inside a formula, Math functions still see how often each value occurred; see unique below. 3 6 6 → 3, 6
Logical functions return true or no value equal, notEqual, startsWith, and endsWith return true when the condition holds, and no value when it doesn't. When one argument returns several values, one match is enough; add an unquoted true as the last argument to require every value to match. startsWith('U', regex('GMT\|UTC', body)) → true
XPath ignores namespaces Element names match without namespace prefixes or declarations. xPath('Orders/Order/Id', body) on <ns0:Orders …>

Escaping Single Quotes

Input

{"ord'erid":"123","name":"John Doe"}

Formula

jsonPath('ord''erid', body)

Result

123

Escaped single quote in a jsonPath formula
The key ord'erid is written ord''erid inside the quoted JSONPath expression.


Function reference

Each function has its own page with parameters, return values, and examples.

Source

Read data from the Log Event.

Function Returns
body The whole message body as text
context('Key') The value of one context property
context(regex('Key pattern')) The values of all context properties whose whole key matches the regular expression
contextKey(regex('Key pattern')) The keys (not the values) of the context properties that match
field('fieldName') The value of a Log Event field (case-sensitive name)

Extract

Pick values out of structured or unstructured content.

Function Returns
csv(headerRowsToSkip, 'delimiter', columnIndex, 'commentSymbol', content) The values of one column (zero-based) of delimited text
jsonPath('expression', content) The values that match a JSONPath expression
jsonPathKey('expression', content) The property names (keys) that match a JSONPath expression
regex('expression', content) The whole matches of a regular expression
regexGroup('expression', 'groups', content) The captured groups of a regular expression
sqllookup('connectionStringId', 'database', 'table', 'searchColumn', 'resultColumn', content) A value looked up in a SQL Server table
xPath('expression', content) The values that match an XPath 1.0 expression
xPath2('expression', content) The values that match an XPath 2.0 expression

Convert

Change the encoding or case of content.

Function Returns
base64decode(content [, 'source encoding']) Decoded text from base64
base64encode(content [, 'input encoding']) Base64 text
convert('source encoding', 'target encoding', content) Content re-encoded from one character encoding to another
toLowerCase(content) Lowercase text
toUpperCase(content) Uppercase text

Alter

Change text.

Function Returns
concat(content, ..., content) All arguments joined into one string
removebom(content) Content without a leading byte order mark (BOM)
replace('oldValue', 'newValue', content) Content with every occurrence of a text replaced
replaceregex('pattern', 'newValue', content) Content with every regular expression match replaced
substring(startIndex, length, content) Part of the text, from a zero-based start index

Logical

Test content.

Function Returns
equal('expression', content [, matchAllValues]) true when content equals the expression
notEqual('expression', content [, matchAllValues]) true when content differs from the expression
isnull(content, 'default') The default when content is null or empty, else the content
startsWith('expression', content [, matchAllValues]) true when content starts with the expression
endsWith('expression', content [, matchAllValues]) true when content ends with the expression

Math

Aggregate values. The optional unique argument is an unquoted true or false: with false, a value that occurs several times counts every time (two invoice lines of 100 → sum = 200); with true, identical values count once (→ 100). Values are compared as text, so 100 and 100.00 are different. The default differs per function, as shown below; leave it false for totals.

Function Returns
avg(content [, unique]) The average of the numeric values; unique defaults to false
count(content [, unique]) The number of values; unique defaults to true
length(content [, unique]) The length in characters of the content; unique defaults to true
max(content [, unique]) The largest numeric value; unique defaults to true
min(content [, unique]) The smallest numeric value; unique defaults to true
sum(content [, unique]) The sum of the numeric values; unique defaults to false

Performance

  • Every formula runs for every matching Log Event during logging and re-index; keep formulas as short as the job allows.
  • Use xPath (XPath 1.0, forward-only reader) for large XML; use xPath2 only when you need XPath 2.0 features.
  • sqllookup queries SQL Server for each evaluation; see sqllookup before using it on high-volume Message Types.

Next Steps