Skip to content

Event Router

event-router

The event-router plugin is a flexible event stream processing system for RackN DRP that filters, transforms, and routes real-time event streams to multiple output destinations.

Architecture

Event-router is a DRP plugin that subscribes to the event stream and processes each event through a three-stage flow: filter → transform → output.

  • Filters select which events are handled using DRP's type.action.key match syntax.
  • Transforms reshape the event (e.g. select fields) before emission.
  • Outputs deliver to one or more destinations: file (rotating logs), kafka (topics), or drp_audit (DRP audit_entries store).

Multiple rules can run in parallel, enabling fan-out to logging, streaming, and audit systems from a single plugin instance.

Developer

The event-router is configured entirely through DRP parameters, and no plugin source changes or custom code are required to define routing behavior.

Developers compose a JSON document describing which events to match (rules), how to reshape them (transforms), and where to deliver them (destinations), then attach that document to an endpoint or profile via a parameter.

Because configuration lives as data in DRP, routing rules are versionable, portable across environments, and can be iterated on without rebuilding or redeploying the plugin.

Two parameters drive the behavior:

  • event-router/event-fto — JSON with output.destinations and rules (required). This is the full filter/transform/output definition.
  • event-router/name — override the default event stream name (optional). Useful when running multiple router instances or distinguishing event sources downstream.

Filter syntax uses a three-part type.action.key match, optionally extended with And(...), Re(...), and Ne(...) predicates for finer-grained matching on event fields. Each of the three base parts is either a literal value or * to match anything, and the action part additionally accepts a comma-separated list.

  • users.create.* — all user creation events
  • machines.create,update,delete.* — machine create, update, and delete
  • machines.*.abc-123-def — every event for a single machine identified by its key
  • *.*.*.And(event.Principal=Re(^user:),event.Type=Ne(websocket)) — user-originated, non-websocket events

Note: A broad catch-all filter such as *.*.* is generally not recommended on its own. DRP emits a large volume of internal events (websockets, connections, activities, and similar housekeeping traffic) that are not useful for most downstream consumers. Narrow the type to only the objects you care about, or use And(...) / Ne(...) predicates to exclude the noise (as shown in the DRP audit example below).

Transforms reshape the event payload before it reaches any destination. They are configured per-rule under a transform object and support two operations:

  • select_fields — an explicit allow-list of fields to keep. Everything else is dropped. Useful when you want a compact, predictable payload.
  • exclude_fields — a deny-list of fields to drop. Everything else is kept. Useful when you mostly want the full event but need to strip a few noisy or sensitive fields.

Both lists use dot notation to reach into nested objects. For example, Object.Name selects (or excludes) the Name field inside the embedded DRP object, and Object.Meta.color would reach two levels deep. A top-level entry like Time targets a top-level field.

Available top-level fields on every routed event include Time, Type, Action, Key, Principal, and EventSource. For create/delete events the full DRP model is available under Object; for update events the computed change set appears as Operations (RFC 6902 JSON Patch entries) along with Count.

Two behaviors are enforced regardless of what select_fields contains:

  1. EventSource is always preserved so downstream consumers can always tell which DRP endpoint produced the event.
  2. Update metadata is always preserved — for action=update events, the Operations, Count, RawPatch, Data, and Message fields pass through even if they aren't in the select_fields list, so patch information is never lost to an over-aggressive allow-list.

When both operations are specified on the same rule, select_fields runs first and exclude_fields runs on the reduced payload.

Minimal select example — keep only the identifying fields plus the object name:

JSON
{
  "transform": {
    "select_fields": ["Time", "Action", "Key", "Principal", "Object.Name"]
  }
}

Exclude example — keep the full event but drop the Object.Params blob, which can be very large on machine objects:

JSON
{
  "transform": {
    "exclude_fields": ["Object.Params"]
  }
}

Each example below is a complete value for the event-router/event-fto parameter and can be used as-is.

File destination — routes machine create, update, and delete events to a rotating JSON log, using a transform to select only the Time, Action, Key, Principal, and Object.Name fields from each event:

JSON
{
  "output": {
    "destinations": [
      {
        "type": "file",
        "file_path": "/var/log/drp",
        "file_name": "drp-events.log",
        "max_size": 10000000,
        "max_files": 5
      }
    ],
    "format": "json"
  },
  "rules": [
    {
      "name": "machine_events",
      "filter": "machines.*.*",
      "transform": {
        "select_fields": ["Time", "Action", "Key", "Principal", "Object.Name"]
      }
    }
  ]
}

Kafka destination — publishes all events to a Kafka topic with custom headers:

JSON
{
  "output": {
    "destinations": [
      {
        "type": "kafka",
        "topic": "drp-events",
        "brokers": [
          "kafka-1.example.com:9092",
          "kafka-2.example.com:9092"
        ],
        "kafka_headers": {
          "source": "drp",
          "environment": "production"
        }
      }
    ],
    "format": "json"
  },
  "rules": [
    {
      "name": "users_events",
      "filter": "users.*.*"
    }
  ]
}

DRP audit destination — writes user-initiated, non-noise events into the audit_entries store:

JSON
{
  "output": {
    "destinations": [
      {
        "type": "drp_audit"
      }
    ],
    "format": "json"
  },
  "rules": [
    {
      "name": "audit-user-actions",
      "filter": "*.*.*.And(event.Principal=Re(^user:),event.Principal=Ne(user:docker-context),event.Principal=Ne(user:racks),event.Type=Ne(websocket),event.Type=Ne(connections),event.Type=Ne(audit_entries),event.Type=Ne(activities))"
    }
  ]
}

Administrator

Administrators are responsible for installing the event-router plugin content onto the DRP endpoint and verifying that the plugin provider is loaded and running. Once installed, routing is activated by applying the event-router/event-fto parameter either directly on the endpoint object or on a profile that is bound to the endpoint.

File Outputs

When configuring a file destination, ensure the DRP service account has write permission to the configured file_path and that the host has enough disk capacity for the full rotation — roughly max_size × max_files bytes per destination. A typical layout places logs under /var/log/drp:

Bash
sudo mkdir -p /var/log/drp
sudo chown drp-user:drp-user /var/log/drp

Recommendation: the file destination is the preferred way to deliver events into external analytics platforms such as Splunk, Kafka, or Elastic. Rather than pointing the event-router directly at those systems, write events to a local file and let the platform's native forwarding agent pick them up — for example, the Splunk Universal Forwarder, Elastic's Filebeat, a Fluentd or Vector tail input, or a Kafka Connect file-source connector. This approach decouples event production from delivery, survives transient network or broker outages by buffering on disk, and lets the forwarding agent handle retries, backpressure, TLS, authentication, and credential rotation using its standard configuration — concerns the event-router itself intentionally keeps out of scope.

Kafka Outputs

For kafka destinations, confirm that the endpoint has network reachability to every broker listed in the configuration. If the Kafka cluster requires TLS, SASL, or other authentication, those concerns are handled at the broker and network layer — the event-router expects a reachable broker set and will report connection failures in the DRP logs if delivery cannot succeed.

DRP Audit Outputs

The drp_audit destination writes events into the DRP audit_entries store, which is managed by DRP's standard RBAC model. Administrators should grant the appropriate roles read access to audit_entries for any users, service accounts, or integrations (SIEM, dashboards, compliance tools) that need to consume audit data.

Operational Considerations

Parameter changes to event-router/event-fto take effect without restarting DRP, which makes it safe to iterate on routing rules in place. However, because the plugin subscribes to live event streams, misconfigured filters or unreachable destinations can drop events silently from the administrator's point of view — it is worth validating new configurations on a non-production endpoint before rolling them out broadly.

Operator

Operators consume the event streams produced by the event-router and rely on its outputs for day-to-day observability, auditing, and downstream integrations. The location of routed events depends on the destinations configured by the developer or administrator.

Viewing File Output

Events sent to a file destination land in the configured file_path and file_name. For the canonical example configuration, events can be tailed directly from the DRP host:

Bash
tail -f /var/log/drp/drp-events.log

Files rotate automatically once they reach max_size bytes, with up to max_files historical files retained alongside the active file.

Viewing Audit Entries

Events routed to the drp_audit destination appear in the DRP UI under Audit Entries, and are also accessible through the standard DRP API and CLI for users who have RBAC access to the audit_entries object. This is the recommended path for compliance reviews and user-action auditing.

Updating Routing Rules

Because the event-router reads its configuration from DRP parameters, operators can adjust routing behavior on the fly by editing the event-router/event-fto parameter on the endpoint or its bound profile. Changes apply immediately without a DRP restart, making it safe to tune filters or add destinations during live operation.

Troubleshooting

If events stop flowing to an expected destination, start by confirming that the event-router plugin is loaded and running on the endpoint. Next, validate that the event-router/event-fto parameter contains well-formed JSON and that its filter expressions actually match the event types being produced — an overly specific filter is the most common reason for an empty output. For kafka and drp_audit destinations, check the DRP service logs for delivery errors, since those failures are surfaced there rather than at the destination itself.