-
Notifications
You must be signed in to change notification settings - Fork 0
Architecture
Technical deep-dive into the WinEventEngine architecture.
- Overview
- System Architecture
- Component Details
- Data Flow
- Event Sources
- Rule Engine
- Action System
- Lua Scripting Integration
- GUI Architecture
- Metrics & Monitoring
- Security Model
- Performance Considerations
WinEventEngine is built with a modular, event-driven architecture using Rust's async ecosystem (Tokio). The system decouples event generation from processing through an internal event bus, enabling high throughput and reliability.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Windows Event Automation Engine β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Event Sources (Plugins) β
β ββ File Watcher ββββ β
β ββ Window Watcher ββΌβββ β
β ββ Process MonitorββΌβββΌβββ β
β ββ Registry Monitorβ΄βββΌβββ β
β β β
β Event Bus (Tokio mpsc channels) β
β β β
β Rule Engine β β
β ββ Pattern Matcher β β
β ββ Lua Evaluator ββββββ β
β β β
β Action Executor β β
β ββ ExecuteCommand β β
β ββ PowerShell β β
β ββ HTTP Request β β
β ββ Log β β
β ββ Lua Script ββββββββββ β
β β
β Supporting Systems β
β ββ Configuration (TOML) + Hot Reload β
β ββ Metrics Collector (1h sliding window) β
β ββ Windows Service Integration β
β ββ Native GUI (Iced) β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Event sources are implemented as plugins implementing the EventSourcePlugin trait:
#[async_trait]
pub trait EventSourcePlugin: Send + Sync {
fn name(&self) -> &str;
async fn start(&mut self, emitter: EventEmitter) -> Result<(), PluginError>;
async fn stop(&mut self) -> Result<(), PluginError>;
}Current Implementations:
-
File Watcher (
notifycrate)- OS-specific file system notifications
- Pattern matching with glob syntax
- Recursive directory watching
- Debouncing to handle rapid successive events
-
Window Watcher (Win32 API)
- Windows event hooks (WH_SHELL, WH_CBT)
- Tracks window creation, destruction, focus changes
- Gets window title, class, executable path, PID
-
Process Monitor (ETW - Event Tracing for Windows)
- Kernel-level process events
- Real-time process start/stop notifications
- Captures command line, parent PID, session ID
- Requires Administrator privileges
-
Registry Monitor (ETW)
- Kernel-level registry access monitoring
- Tracks key/value creation, modification, deletion
- Process context for each operation
- Requires Administrator privileges
The event bus uses Tokio's multi-producer, single-consumer (mpsc) channels:
pub type EventEmitter = mpsc::Sender<Event>;
pub type EventReceiver = mpsc::Receiver<Event>;Design Decisions:
- Backpressure handling: Bounded channels with configurable buffer size
- Event dropping: Old events dropped if buffer full (logged)
- Clone-on-send: Events are cloned for each rule evaluation
Buffer Configuration:
[engine]
event_buffer_size = 1000 # Default: 1000 eventsThe rule engine evaluates events against configured rules:
Matching Process:
- Event arrives from bus
- Each rule's trigger is evaluated
- If trigger matches, associated actions execute
- Actions execute sequentially (order matters)
Trigger Types:
- Pattern matching (glob syntax)
- Process name matching
- Window title substring matching
- Composite AND/OR logic
Example Flow:
Event: FileCreated { path: "C:/Data/input.csv" }
β
Rule: "process_csv"
Trigger: file_created + pattern "*.csv"
β MATCH
β
Action: Execute "python process.py {{EVENT_PATH}}"
Actions implement the Action trait:
pub trait Action: Send + Sync {
fn execute(&self, event: &Event) -> Result<ActionResult, ActionError>;
fn description(&self) -> String;
fn clone_box(&self) -> Box<dyn Action>;
}Action Types:
-
Execute - Run external commands
- Working directory support
- Argument passing
- Environment variable injection
-
PowerShell - Execute PowerShell scripts
- Script content or file path
- Variable injection via environment
- Error stream capture
-
HTTP Request - Webhook integration
- GET/POST/PUT/DELETE/PATCH
- Custom headers
- Body templating with event data
- Security: Must be enabled in settings (disabled by default)
-
Variables: Response available via
HTTP_STATUS_CODE,HTTP_RESPONSE_BODY,HTTP_SUCCESS
-
Log - Structured logging
- Debug/Info/Warn/Error levels
- Message templating
- Contextual event data
-
Script (Lua) - Custom scripting
- Sandboxed execution environment
- Rich API (logging, HTTP, JSON, filesystem)
- 30-second timeout (configurable)
- Error handling strategies
ββββββββββββββββ
β OS Event β (File created, Process started, etc.)
ββββββββ¬ββββββββ
β
ββββββββΌββββββββ
β Event Source β (Translate OS event to Event struct)
β Plugin β
ββββββββ¬ββββββββ
β mpsc::send()
ββββββββΌββββββββ
β Event Bus β (Channel buffer)
ββββββββ¬ββββββββ
β mpsc::recv()
ββββββββΌββββββββ
β Rule Engine β (Evaluate triggers)
ββββββββ¬ββββββββ
β
ββββββββΌββββββββ
β Action β (Execute matched actions)
β Executor β
ββββββββ¬ββββββββ
β
ββββββββΌββββββββ
β Result β (Log success/failure)
ββββββββββββββββ
Latency Breakdown:
- OS event to plugin: <1ms (kernel notification)
- Plugin to bus: <1ms (async send)
- Rule evaluation: 1-10ms (depends on complexity)
- Action execution: 10ms-30s (depends on action)
- Total typical: 10-100ms
βββββββββββββββββββββββββββββββββββββββββββ
β ScriptAction β
β (Rust - implements Action trait) β
ββββββββββββββββ¬βββββββββββββββββββββββββββ
β Creates fresh Lua state
ββββββββββββββββΌβββββββββββββββββββββββββββ
β Lua VM (mlua) β
β - Sandboxed environment β
β - Script loaded & executed β
β - API bindings (log, http, etc.) β
ββββββββββββββββ¬βββββββββββββββββββββββββββ
β Calls user function
ββββββββββββββββΌβββββββββββββββββββββββββββ
β User Script β
β function on_event(event) β
β -- Custom logic β
β return {success = true} β
β end β
βββββββββββββββββββββββββββββββββββββββββββ
Sandbox Restrictions:
- β No
dofile,loadfile,require(can't load external code) - β No
iolibrary (direct file access) - β No
oslibrary (except safe functions) - β No
debuglibrary - β No loading of C modules
- β File operations via restricted API
- β HTTP only (no raw sockets)
- β 30-second execution timeout
- β Fresh Lua state per execution
API Safety:
- File operations restricted to safe directories
- HTTP requests limited to standard methods
- Command execution via controlled API
- All I/O goes through Rust-implemented APIs
The native GUI is built with Iced, a cross-platform GUI library for Rust.
βββββββββββββββββββββββββββββββββββββββββββ
β WinEventApp β
β (Main Application State) β
ββββββββββββββββ¬βββββββββββββββββββββββββββ
β
βββββββββ΄ββββββββ
β β
ββββββββΌβββββββ ββββββββΌβββββββ
β Views β β State β
β β β β
β - Dashboard β β - Engine β
β - Rules β β - Events β
β - Sources β β - Metrics β
β - Tester β β - Config β
β - Settings β β - Theme β
βββββββββββββββ βββββββββββββββ
GUI Features:
- Dashboard: Real-time event stream, metrics cards, status indicators
- Rules: Create, edit, delete, enable/disable automation rules
- Sources: Configure and manage event source plugins
- Event Tester: Test rules against sample events with JSON input
- Settings: Theme selection, service management, HTTP security toggle
Event Broadcasting:
// Engine broadcasts events to GUI
tokio::sync::broadcast::channel(100)
// GUI subscribes and updates in real-timeUpdate Flow:
- Engine processes event
- Event broadcast to all subscribers
- GUI receives event via broadcast channel
- UI updates immediately (no polling)
pub struct MetricsCollector {
counters: DashMap<String, AtomicU64>,
gauges: DashMap<String, AtomicU64>,
histograms: DashMap<String, Vec<(DateTime<Utc>, u64)>>,
// ... sliding window cleanup
}Collected Metrics:
-
events_total- Events by source and type -
events_dropped_total- Dropped due to full buffer -
events_processing_duration_seconds- Processing latency -
rules_evaluated_total- Rule evaluations -
rules_matched_total- Successful matches -
actions_executed_total- Actions by result -
plugins_events_generated_total- Events per plugin -
engine_uptime_seconds- Engine uptime
Retention:
- Regular metrics: 1 hour (sliding window)
- Error metrics: 24 hours
- Cleanup runs every 5 minutes
GUI Dashboard:
- Real-time metrics display
- Event counter cards
- Last update timestamp
- Auto-refresh every 2 seconds
- Lua scripts: Run in isolated Lua state, fresh per execution
- Command execution: Spawns separate process
- File access: Restricted API only, path validation
- Network: HTTP/HTTPS only via controlled API
Disabled by Default:
[engine]
http_requests_enabled = false # Security: must explicitly enableWhy Disabled by Default:
- Prevents malicious rules from calling external APIs
- Protects against data exfiltration
- User must consciously enable
Enabling HTTP:
- Via GUI: Settings β Security β "Allow HTTP Request Actions"
- Via Config: Set
http_requests_enabled = true - Requires rule rebuild to take effect
| Component | Normal User | Administrator |
|---|---|---|
| File Watcher | β | β |
| Window Watcher | β | β |
| Process Monitor | β | β |
| Registry Monitor | β | β |
| Windows Service | β | β |
| HTTP Requests (toggle) | β | β |
- Config file: User's responsibility to secure
- Logs: May contain sensitive paths (configure log rotation)
- HTTP responses: Stored in environment variables (session only)
Tested Capacity:
- File events: 1000+ events/second
- Process events: 500+ events/second
- Rule evaluations: 10,000+ evaluations/second
- Action execution: Depends on action type
Bottlenecks:
- File I/O: Script actions with file operations
- Network latency: HTTP request actions
- Process spawn: Execute actions
- Lua overhead: Script compilation (mitigated by caching)
Typical (idle):
- Engine: 20-30MB
- GUI: 50-80MB
- Lua runtime (per script): ~1MB
- Metrics: ~5MB (1h retention)
- Total: ~100MB
Under load:
- Event buffer: Configurable (default 1000 events)
- Per-event overhead: ~500 bytes
- Lua scripts: Freed after execution
- GUI event history: Last 50 events
-
Use specific patterns instead of
*:- Good:
*.txt - Bad:
*(monitors everything)
- Good:
-
Batch actions with composite rules:
- Better than multiple single-action rules
-
Set appropriate timeouts:
- Don't use default 30s for quick scripts
- Increase for long-running operations
-
Filter early:
- Use source filters before rule evaluation
- Pattern match in trigger, not in Lua
-
Monitor metrics:
- Watch
events_dropped_total - Increase buffer size if dropping
- Watch
- Language: Rust (2024 edition)
- Async Runtime: Tokio
- GUI Framework: Iced
- Lua: mlua (Lua 5.4)
- Serialization: serde + toml
- Logging: tracing
- Windows API: windows-rs
- Build Tools: cargo, winres (Windows resources)