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, optionalcontext,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, optionalcontext,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, plusptype2,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, pluswindow
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, optionalaction2
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,threshfor 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=SubStrand exact string matching when possible for better performance. - Use
threshandwindowto 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.