Hi SecOps Community,
One of the biggest operational risks in any SOC is silent telemetry loss—critical infrastructure servers that suddenly stop forwarding logs without raising an immediate alert. Whether due to an agent crash, network misconfiguration, or deliberate adversary tampering, missing logs create massive blind spots during incident response.
To solve this, I designed a YARA-L 2.0 detection rule called Silent Log Detection. It tracks monitored servers across a sliding window, evaluates their activity, and triggers an alert if an active host stops forwarding events for more than 2 hours.
How the Rule Works
- Log Source Filtering: Scopes down high-value operating system, system, and EDR feeds (winevtlog, windows_ad, syslog, linux, edr).
- Entity Normalization: Strips domain/FQDN suffixes and normalizes hostnames to lowercase to ensure clean aggregation.
- Naming Taxonomy Scope: Uses regex patterns to identify server assets (srv, dc, db, app, etc.) while explicitly excluding end-user workstations (desk, lap, ws, etc.) to prevent false positives from expected sleep/shutdown behavior.
- Time Delta Evaluation: Aggregates by $server across a 6-hour window and calculates the delta between the current timestamp and the most recent event timestamp (diff_seconds > 7200).
- Noise Gate: Requires #e >= 5 events within the window to prevent single-event transient noise from generating alerts.
rule silent_log_hosts {
meta:
author = "Diogo Caldas"
description = "Detects monitored servers that stopped sending telemetry for more than 2 hours within a 6-hour evaluation window."
severity = "High"
priority = "High"events:
// 1. Filter by common OS, system, and EDR log types
re.regex($e.metadata.log_type, "(?i)(winevtlog|windows_ad|syslog|linux|edr)")// 2. Extract hostname (stripping domain/FQDN and converting to lowercase)
$server = strings.to_lower(re.capture($e.principal.hostname, "^([^.]+)"))// 3. Match server naming conventions (Customize with your organization's naming taxonomy)
re.regex($server, "(?i)(srv|dc|db|sql|app|web|prd|vm)")// 4. Exclude workstation patterns to reduce false positives
not re.regex($server, "(?i)(desk|wk|ws|note|nb|lap|pc)")match:
$server over 6houtcome:
$server_name = array_distinct($server)
$log_types = array_distinct($e.metadata.log_type)
$events_count = count($e.metadata.id)
$last_event_sec = max($e.metadata.event_timestamp.seconds)
$diff_seconds = timestamp.current_seconds() - max($e.metadata.event_timestamp.seconds)
$diff_minutes = (timestamp.current_seconds() - max($e.metadata.event_timestamp.seconds)) / 60condition:
#e >= 5 and $diff_seconds > 7200
}
Implementation Tips & Best Practices
- Tuning Asset Tags: Be sure to adjust the server patterns in step 3 and workstation exclusions in step 4 to match your organization’s internal naming conventions, or swap them for entity context tags if you maintain an enriched CMDB/Asset table in SecOps.
- Tuning Inactivity Thresholds: You can adjust $diff_seconds > 7200 (2 hours) and the match window (over 6h) based on your ingestion latency and SLA tolerance.
- Context in Alert: The rule populates $diff_minutes and $log_types in the outcome section, giving analysts immediate context on how long the asset has been dark and what feeds were affected.


