Event Correlation Types

LogZilla documentation for Event Correlation Types

Event Correlation Rule Types

The following Event Correlation (EC) rule types are used in LogZilla solution examples. Each entry lists purpose, required keys, and a verified example from existing documentation.

Pattern type (ptype)

  • SubStr: substring matching (preferred for performance)
  • RegExp: regular expression matching when substring is not sufficient

Single

Guidance: Single-event conditions should use LogZilla Triggers for performance and simplicity. Use an EC Single rule only when it is a required step inside a larger, stateful correlation chain. See Creating Triggers.

Match a single event that meets the condition.

  • Keys: ptype, pattern, optional context, desc, action

Example (Windows successful login after brute force): (This example requires the following forwarder configuration:)

yaml
# /etc/logzilla/forwarder.d/windows-security.yaml
window_size: 0
type: sec
sec_name: windows-security
match:
  - field: MSWin EventID
    value: ["4624", "4625", "4732", "1102"]
rules:
- rewrite:
    message: >-
      [WINDOWS_AUTH] host=${:host} MSWin_EventID=${:MSWin EventID} SrcIP=${:SrcIP}
      Subject_User_Name=${:Subject User Name} Target_Domain_Name=${:Target Domain Name}
      Target_Group_Name=${:Target Group Name} Target_User_Name=${:Target User Name}
      Username=${:Username} User_Domain_Name=${:User Domain Name} $MESSAGE
conf
# Detect successful login after brute force (correlate on user)
type=Single
ptype=RegExp
pattern=(?s)\[WINDOWS_AUTH\].*?host=([^\s]+).*?MSWin_EventID=4624\b.*?Username=([^\s]+)
context=BRUTE_FORCE_ACTIVE_\L$2\E
desc=Successful login after brute force user=$2 host=$1
action=write /var/log/logzilla/sec/windows-security-messages.log \
         "WINDOWS_COMPROMISE_SUSPECTED %t user=$2 host=$1 (4624 after brute force)"; \
       shellcmd (logger -t SEC-WINDOWS-SECURITY -p local0.crit \
         "WINDOWS_COMPROMISE_SUSPECTED user=\"$2\" host=\"$1\" correlation=\"4624_after_bruteforce\"")

SingleWithThreshold

Count matching events within a time window and fire when the threshold is reached.

  • Keys: ptype, pattern, optional context, desc, action, thresh, window

Example (Windows brute force): (This example requires the forwarder configuration from the previous example.)

conf
# Count failed auth attempts (threshold by user, case-insensitive)
type=SingleWithThreshold
ptype=RegExp
pattern=(?s)\[WINDOWS_AUTH\].*?host=([^\s]+).*?MSWin_EventID=4625\b.*?SrcIP=([^\s]+).*?Username=([^\s]+)
context=\L$3\E
desc=Windows failed logon burst (4625) user=$3 src=$2 host=$1
action=create BRUTE_FORCE_ACTIVE_\L$3\E 1800; \
       write /var/log/logzilla/sec/windows-security-messages.log \
         "BRUTE_FORCE_DETECTED %t user=\L$3\E src=$2 host=$1 attempts=$thresh"; \
       shellcmd (logger -t SEC-WINDOWS-SECURITY -p local0.alert \
         "BRUTE_FORCE_DETECTED user=\"\L$3\E\" src_ip=\"$2\" target=\"$1\" attempts=\"$thresh\"")
thresh=10
window=300

Pair

Detect a two-step sequence: an initial event followed by a second event.

  • Keys: ptype, pattern, context, desc, action, plus ptype2, pattern2, context2, desc2, action2

Example (BGP down then up with outage duration): (This example requires the following forwarder configuration:)

yaml
# /etc/logzilla/forwarder.d/cisco-network-health.yaml
window_size: 0
type: sec
sec_name: cisco-network-health
match:
  - field: cisco_mnemonic
    value: 
      - "BGP-5-ADJCHANGE"
      - "BGP-4-MAXPFX"
      - "BGP-3-NOTIFICATION"
      - "OSPF-5-ADJCHG"
rules:
- rewrite:
    message: >-
      [CISCO_NETWORK_HEALTH]
      cisco_mnemonic="${:cisco_mnemonic}"
      host="${:host}"
      srcip="${:SrcIP}"
      dstip="${:DstIP}"
      srcport="${:SrcPort}"
      dstport="${:DstPort}"
      protocol="${:protocol}"
      $MESSAGE
conf
# BGP adjacency outage tracker (host + neighbor)

type=Pair

# ---- START (neighbor Down) ----
ptype=RegExp
pattern=\[CISCO_NETWORK_HEALTH\]\s+cisco_mnemonic="BGP-5-ADJCHANGE"\s+host="([^"]+)"\s+srcip="[^"]*"\s+dstip="[^"]*"\s+srcport="[^"]*"\s+dstport="[^"]*"\s+protocol="[^"]*"\s+.*\bneighbor\s+([0-9A-Fa-f:.]+)\s+Down\b
context=BGP_ADJ_$1_$2
desc=BGP Neighbor $2 Down on $1
action=eval %router_host ( "$1" ); \
       eval %neighbor_ip ( "$2" ); \
       eval %down_time ( time() ); \
       shellcmd (/usr/bin/host %neighbor_ip > /tmp/bgp-lookup-%neighbor_ip 2>/dev/null); \
       eval %hostname ( readfile("/tmp/bgp-lookup-%neighbor_ip") ); \
       write /var/log/logzilla/sec/network-health.log \
         "BGP_ADJ_DOWN %t router=%router_host neighbor=%neighbor_ip hostname=%hostname"; \
       shellcmd (logger -t SEC-NETWORK-HEALTH \
         "BGP_ADJ_DOWN router=\"%router_host\" neighbor=\"%neighbor_ip\" hostname=\"%hostname\"")

# ---- END (same host + neighbor, Up) ----
ptype2=RegExp
pattern2=\[CISCO_NETWORK_HEALTH\]\s+cisco_mnemonic="BGP-5-ADJCHANGE"\s+host="([^"]+)"\s+srcip="[^"]*"\s+dstip="[^"]*"\s+srcport="[^"]*"\s+dstport="[^"]*"\s+protocol="[^"]*"\s+.*\bneighbor\s+([0-9A-Fa-f:.]+)\s+Up\b
context2=BGP_ADJ_$1_$2
desc2=BGP Neighbor $2 Up on $1
action2=eval %up_time ( time() ); \
        eval %outage_duration ( %up_time - %down_time ); \
        write /var/log/logzilla/sec/network-health.log \
          "BGP_ADJ_UP %t router=%router_host neighbor=%neighbor_ip downtime=%outage_duration hostname=%hostname"; \
        shellcmd (logger -t SEC-NETWORK-HEALTH \
          "BGP_OUTAGE_RESOLVED router=\"%router_host\" neighbor=\"%neighbor_ip\" downtime=\"%outage_duration\" hostname=\"%hostname\""); \
        delete /tmp/bgp-lookup-%neighbor_ip

# Pairing window (how long to wait for the Up after Down)
window=86400

PairWithWindow

Like Pair, but requires the second event to arrive within a specified window.

  • Keys: same as Pair, plus window

Example (BGP adjacency down/up within 4 hours): (This rule requires the forwarder configuration from the previous example.)

conf
# BGP adjacency flapping detector (down/up within 4 hours)

type=PairWithWindow

# ---- START (neighbor Down) ----
ptype=RegExp
pattern=\[CISCO_NETWORK_HEALTH\]\s+cisco_mnemonic="BGP-5-ADJCHANGE"\s+host="([^"]+)"\s+srcip="([^"]+)"\s+dstip="[^"]*"\s+srcport="[^"]*"\s+dstport="[^"]*"\s+protocol="[^"]*"\s+.*\bneighbor\s+\S+\s+Down\b
context=BGP_FLAP_$1_$2
desc=BGP neighbor outage detected on $1
action=eval %router_host ( "$1" ); \
       eval %neighbor_ip ( "$2" ); \
       eval %outage_start ( time() )

# ---- END (same host + neighbor, Up within 4 hours) ----
ptype2=RegExp
pattern2=\[CISCO_NETWORK_HEALTH\]\s+cisco_mnemonic="BGP-5-ADJCHANGE"\s+host="([^"]+)"\s+srcip="([^"]+)"\s+dstip="[^"]*"\s+srcport="[^"]*"\s+dstport="[^"]*"\s+protocol="[^"]*"\s+.*\bneighbor\s+\S+\s+Up\b
context2=BGP_FLAP_$1_$2
desc2=BGP neighbor %neighbor_ip flapped on %router_host
action2=eval %outage_duration ( time() - %outage_start ); \
        write /var/log/logzilla/sec/network-health.log \
          "BGP_FLAP_4H %t router=%router_host neighbor=%neighbor_ip duration=%outage_duration window=14400s"; \
        shellcmd (logger -t SEC-NETWORK-HEALTH -p local0.warning \
          "BGP_FLAP_4H host=\"%router_host\" neighbor=\"%neighbor_ip\" duration=\"%outage_duration\"")

# Pairing window (4 hours = 14400 seconds)
window=14400

SingleWithScript

Run an external script to decide or compute a condition.

  • Keys: ptype, pattern, script, desc, action, optional action2

Example (Memory trend analysis): (This example requires the following forwarder configuration):

yaml
# /etc/logzilla/forwarder.d/cisco-device-health.yaml
window_size: 0
type: sec
sec_name: cisco-device-health
match:
  - field: cisco_mnemonic
    value: ["SYS-1-CPURISINGTHRESHOLD", "SYS-4-FREEMEMLOW", "LINK-3-UPDOWN"]
rules:
- rewrite:
    message: >-
      [CISCO_DEVICE_HEALTH]
      cisco_mnemonic="${:cisco_mnemonic}"
      host="${:host}"
      $MESSAGE

SEC Rule:

conf
# Analyze memory trend in external script
# Cisco memory threshold tracking

type=SingleWithScript

ptype=RegExp
pattern=\[CISCO_DEVICE_HEALTH\]\s+cisco_mnemonic="SYS-4-FREEMEMLOW"\s+host="([^"]+)"\s+

script=/usr/local/bin/cisco-memory-threshold-tracking.sh $1
desc=Memory alert counter for $1
action=eval %hostname ( "$1" ); \
       write /var/log/logzilla/sec/device-health.log \
         "MEMORY_ALERT %t host=%hostname count=$2"


EventGroup3

Correlate three related conditions (with thresholds) to indicate a larger issue.

  • Keys: ptype, pattern, context, thresh for each group segment

Example (Network device health): (This example requires the forwarder configuration from the previous example.)

conf
# Cisco Device Health (CPU≥80%, Mem low, Iface down)

type=EventGroup3
# Group by device host (keep $1 as host in all patterns)
context=HOST_$1
window=300

# -------- CPU HIGH (>=80%) --------
# Matches %SYS-1-CPURISINGTHRESHOLD lines that mention 80–100%
ptype=RegExp
pattern=\[CISCO_DEVICE_HEALTH\]\s+cisco_mnemonic="SYS-1-CPURISINGTHRESHOLD"\s+host="([^"]+)"\b.*\b(8\d|9\d|100)%\b
thresh=3

# -------- MEMORY LOW (≈ high usage) --------
# Matches Cisco low-watermark memory events (no % necessarily present)
ptype2=RegExp
pattern2=\[CISCO_DEVICE_HEALTH\]\s+cisco_mnemonic="SYS-4-FREEMEMLOW"\s+host="([^"]+)"\b.*
thresh2=2

# -------- INTERFACE DOWN --------
# Matches interface down events; capture interface name if present (not used in final group alert)
ptype3=RegExp
pattern3=\[CISCO_DEVICE_HEALTH\]\s+cisco_mnemonic="(?:LINK-3-UPDOWN|LINEPROTO-5-UPDOWN)"\s+host="([^"]+)"\b.*?\bInterface\s+([^,]+),\s+changed state to down\b
thresh3=1

desc=Device health degradation on host=$1 (CPU>=80% x3, Mem low x2, IfDown x1 within 5m)
action=write /var/log/logzilla/sec/network-health.log \
         "DEVICE_HEALTH_ALERT %t host=$1 symptoms=cpu_ge80x3,mem_lowx2,ifdownx1"; \
       shellcmd (logger -t SEC-CRITICAL -p local0.crit \
         "DEVICE_HEALTH_ALERT host=\"$1\" correlation=\"cpu>=80x3,mem_lowx2,ifdownx1\"")

Notes

  • Prefer ptype=SubStr and exact string matching when possible for better performance.
  • Use thresh and window to control noise and define meaningful time bounds for correlation.
  • When calling external scripts from EC rules (shellcmd), pass values as positional arguments and read them as $1, $2, etc., in the script.
  • Prefer LogZilla Triggers for single-event logic whenever possible; reserve EC for multi-event/stateful correlation.
Event Correlation Types | LogZilla Documentation