User Guide

WHERE Conditions

The following operators are available in the WHERE clause.

  • ‘AND’: Receives an array of operator clauses and returns true if and only if all of them evaluate to true.

  • ‘OR’: Receives an array of operator clauses and returns true if at least one of the operators evaluates to true.

  • ‘NOT’: Receives one operator clause and returns true if the operator clause evaluates to false, while it returns false if the operator clause evaluates to true.

  • ‘contains’: Evaluates whether the first argument contains the second one. It can be applied to strings, arrays, and maps. The operator can also be called with the alias ‘contain’.

  • ‘containsIgnoreCase’: Evaluates whether the first argument contains, in a case-insensitive way, the string passed as second argument. This operator can also be called with the alias ‘containIgnoreCase’.

  • ‘equals’: Compares any two values (including, but not limited to, arrays, maps) and returns whether or not they are equal. An alias for this operator is ‘equal’.

  • ‘equalsIgnoreCase’: Compares two strings and returns whether or not they are equal in a case-insensitive way. The operator can also be called with the alias ‘equalIgnoreCase’.

  • ‘ge’: Compares two values and returns whether the first value is greater than or equal to the second one. If one or both of the values do not exist, it returns false.

  • ‘gt’: Compares two values and returns whether the first value is greater than the second one. If one or both of the values do not exist, it returns false.

  • ‘le’: Compares two values and returns whether the first value is less than or equal to the second one. If one or both of the values do not exist, it returns false.

  • ‘lt’: Compares two values and returns whether the first value is less than the second one. If one or both of the values do not exist, it returns false.

  • ‘ne’: This is the negation of the ‘equals’ operator. Compares two values and returns whether or not they are different. It can also be called with the aliases ‘notEquals’ and ‘notEqual’.

  • ‘regex’: Evaluates whether a field of an event matches a given regular expression.

Note

We use the Rust Regex library (see its github project home page ) to evaluate regular expressions provided by the WITH clause and by the regex operator. Refer to its dedicated documentation for details about its features and limitations. You can also visit this site <https://regex101.com> in order to test your regex input and get interactive feedback on its syntax.

The contains Operator

The contains operator (or it alias contain is used to check whether the first argument contains the second one.

It applies in three different situations:

  • The arguments are both strings: Returns true if the second string is a substring of the first one.

  • The first argument is an array: Returns true if the second argument is contained in the array.

  • The first argument is a map and the second is a string: Returns true if the second argument is an existing key in the map.

In any other case, it will return false.

Rule example:

{
  "description": "",
  "continue": true,
  "active": true,
  "constraint": {
    "WHERE": {
      "type": "contains",
      "first": "${event.payload.hostname}",
      "second": "linux"
    },
    "WITH": {}
  },
  "actions": []
}

An event matches this rule if in its payload appears an entry with key hostname and whose value is a string that contains linux.

A matching Event is:

{
    "type": "trap",
    "created_ms": 1554130814854,
    "payload":{
        "hostname": "linux-server-01"
    }
}

The ‘containsIgnoreCase’ Operator

The containsIgnoreCase operator is used to check whether the first argument contains the string passed as second argument, regardless of their capital and small letters. In other words, the arguments are compared in a case-insensitive way.

It applies in three different situations:

  • The arguments are both strings: Returns true if the second string is a case-insensitive substring of the first one

  • The first argument is an array: Returns true if the array passed as first parameter contains a (string) element which is equal to the string passed as second argument, regardless of uppercase and lowercase letters

  • The first argument is a map: Returns true if the second argument contains, an existing, case-insensitive, key of the map

In any other case, this operator will return false.

Rule example:

{
  "description": "",
  "continue": true,
  "active": true,
  "constraint": {
    "WHERE": {
      "type": "containsIgnoreCase",
      "first": "${event.payload.hostname}",
      "second": "Linux"
    },
    "WITH": {}
  },
  "actions": []
}

An event matches this rule if in its payload it has an entry with key “hostname” and whose value is a string that contains “linux”, ignoring the case of the strings.

A matching Event is:

{
    "type": "trap",
    "created_ms": 1554130814854,
    "payload":{
        "hostname": "LINUX-server-01"
    }
}

Additional values for hostname that match the rule include: linuX-SERVER-02, LInux-Host-12, Old-LiNuX-FileServer, and so on.

The ‘equals’, ‘ge’, ‘gt’, ‘le’, ‘lt’ and ‘ne’ Operators

The equals, ge, gt, le, lt, ne operators are used to compare two values.

All these operators can work with values of type Number, String, Bool, null and Array.

Warning

Please be extremely careful when using these operators with numbers of type float. The representation of floating point numbers is often slightly imprecise and can lead to unexpected results (for example, see https://www.floating-point-gui.de/errors/comparison/ ).

Example:

{
  "description": "",
  "continue": true,
  "active": true,
  "constraint": {
    "WHERE": {
      "type": "OR",
      "operators": [
        {
          "type": "equals",
          "first": "${event.payload.value}",
          "second": 1000
        },
        {
          "type": "AND",
          "operators": [
            {
              "type": "ge",
              "first": "${event.payload.value}",
              "second": 100
            },
            {
              "type": "le",
              "first": "${event.payload.value}",
              "second": 200
            },
            {
              "type": "ne",
              "first": "${event.payload.value}",
              "second": 150
            },
            {
              "type": "notEquals",
              "first": "${event.payload.value}",
              "second": 160
            }
          ]
        },
        {
          "type": "lt",
          "first": "${event.payload.value}",
          "second": 0
        },
        {
          "type": "gt",
          "first": "${event.payload.value}",
          "second": 2000
        }
      ]
    },
    "WITH": {}
  },
  "actions": []
}

An event matches this rule if event.payload.value exists and one or more of the following conditions hold:

  • It is equal to 1000

  • It is between 100 (inclusive) and 200 (inclusive), but not equal to 150 or to 160

  • It is less than 0 (exclusive)

  • It is greater than 2000 (exclusive)

A matching Event is:

{
    "type": "email",
    "created_ms": 1554130814854,
    "payload":{
      "value": 110
    }
}

Here are some examples showing how these operators behave:

  • [{"id":557}, {"one":"two"}] lt 3: false (cannot compare different types, e.g. here the first is an array and the second is a number)

  • {id: "one"} lt {id: "two"}: false (maps cannot be compared)

  • [["id",557], ["one"]] gt [["id",555], ["two"]]: true (elements in the array are compared recursively from left to right: so here “id” is first compared to “id”, then 557 to 555, returning true before attempting to match “one” and “two”)

  • [["id",557]] gt [["id",555], ["two"]]: true (elements are compared even if the length of the arrays is not the same)

  • true gt false: true (the value ‘true’ is evaluated as 1, and the value ‘false’ as 0; consequently, the expression is equivalent to “1 gt 0” which is true)

  • “twelve” gt “two”: false (strings are compared lexically, and ‘e’ comes before ‘o’, not after it)

The ‘equalsIgnoreCase’ Operator

The equalsIgnoreCase operator is used to check whether the strings passed as arguments are equal in a case-insensitive way.

It applies only if both the first and the second arguments are strings. In any other case, the operator will return false.

Rule example:

{
  "description": "",
  "continue": true,
  "active": true,
  "constraint": {
    "WHERE": {
      "type": "equalsIgnoreCase",
      "first": "${event.payload.hostname}",
      "second": "Linux"
    },
    "WITH": {}
  },
  "actions": []
}

An event matches this rule if in its payload it has an entry with key “hostname” and whose value is a string that is equal to “linux”, ignoring the case of the strings.

A matching Event is:

{
    "type": "trap",
    "created_ms": 1554130814854,
    "payload":{
        "hostname": "LINUX"
    }
}

The ‘regex’ Operator

The regex operator is used to check if a string matches a regular expression. The evaluation is performed with the Rust Regex library (see its github project home page )

Rule example:

{
  "description": "",
  "continue": true,
  "active": true,
  "constraint": {
    "WHERE": {
      "type": "regex",
      "regex": "[a-fA-F0-9]",
      "target": "${event.type}"
    },
    "WITH": {}
  },
  "actions": []
}

An event matches this rule if its type matches the regular expression [a-fA-F0-9].

A matching Event is:

{
    "type": "trap0",
    "created_ms": 1554130814854,
    "payload":{}
}

The ‘AND’, ‘OR’, and ‘NOT’ Operators

The and and or operators work on a set of operators, while the not operator works on one single operator. They can be nested recursively to define complex matching rules.

As you would expect:

  • The and operator evaluates to true if all inner operators match

  • The or operator evaluates to true if at least an inner operator matches

  • The not operator evaluates to true if the inner operator does not match, and evaluates to false if the inner operator matches

Example:

{
  "description": "",
  "continue": true,
  "active": true,
  "constraint": {
    "WHERE": {
      "type": "AND",
      "operators": [
        {
          "type": "equals",
          "first": "${event.type}",
          "second": "rsyslog"
        },
        {
          "type": "OR",
          "operators": [
            {
              "type": "equals",
              "first": "${event.payload.body}",
              "second": "something"
            },
            {
              "type": "equals",
              "first": "${event.payload.body}",
              "second": "other"
            }
          ]
        },
        {
          "type": "NOT",
          "operator": {
              "type": "equals",
              "first": "${event.payload.body}",
              "second": "forbidden"
          }
        }
      ]
    },
    "WITH": {}
  },
  "actions": []
}

An event matches this rule if in its payload:

  • The type is “rsyslog”

  • AND an entry with key body whose value is wither “something” OR “other”

  • AND an entry with key body is NOT “forbidden”

A matching Event is:

{
    "type": "rsyslog",
    "created_ms": 1554130814854,
    "payload":{
        "body": "other"
    }
}

A ‘Match all Events’ Rule

If the WHERE clause is not specified, the Rule evaluates to true for each incoming event.

For example, this Rule generates an “archive” Action for each Event:

{
    "description": "",
    "continue": true,
    "active": true,
    "constraint": {
      "WITH": {}
    },
    "actions": [
      {
        "id": "archive",
        "payload": {
          "event": "${event}",
          "archive_type": "one"
        }
      }
    ]
}