Operation
CEP is one of the cep services of pd — the API, console, and engine reside in the same process.
| Item | Value |
|---|---|
| Port | 7400 (HTTP) · 7401 (TLS) |
pd Service | cep — MASTER only |
| Configuration | plantpulse-cep.properties (rendered) |
| Rules · Event Types | PostgreSQL datalake DB |
| Input · Output | Valkey |
docker exec plantpulse-datalake pd status cep
docker exec plantpulse-datalake pd restart cep
docker exec plantpulse-datalake pd logs --lines 200 cep
Which backend started — a single log line is the answer
CEP input path: aster.
ingest.rate_1m is not evidenceInflow increases regardless of which engine started. "It is running" and "What is running" are different questions.
The method for selecting a backend and the transition sequence are located in Backends.
Reading registration results
Statements are registered, and registration produces a result.
curl -fsS -H "X-API-Key: ${PP_CEP_API_KEY}" http://127.0.0.1:7400/api/v1/eql/registration
| Result | Meaning |
|---|---|
| ACTIVE | Received by the booted backend and is running |
| REJECTED | Saved but not running. A token is provided indicating which configuration caused the rejection |
REJECTED is a list, not a «defect»It is not normal for this number to be 0. A rejected statement is input for what to do next — rewrite it without the configuration, change the backend, or request that feature.
The important thing is that it is not silent. Rejections are saved, named, and queryable.
Portability is queried separately.
curl -fsS -H "X-API-Key: ${PP_CEP_API_KEY}" http://127.0.0.1:7400/api/v1/eql/portability
Primary APIs
| Path | Function |
|---|---|
POST /api/v1/eql/deploy | Register statement |
POST /api/v1/eql/validate | Evaluation only |
DELETE /api/v1/eql/undeploy/{id} | Unregister |
GET /api/v1/eql/registration | Registration result table (ACTIVE / REJECTED) |
GET /api/v1/eql/portability | Portability |
GET /api/v1/eql/metrics/snapshot · /metrics/engine | Match rate · Output rate per statement, engine metrics |
GET·POST·PUT·DELETE /api/v1/event-types | Register event type |
GET·POST·DELETE /api/v1/keys | API Key |
GET /api/health | Anonymous readiness — engine · cache · schema |
The server counts matches and outputs for each statement, and the two endpoints above provide them. This is consistent regardless of which backend is booted.
CPU · wall-clock time per statement is not provided — providing 0 for a value that cannot be measured would be misinterpreted as «fast».
The Authority of Rules — Intent in DB, Fact in Engine
| Question | Authority |
|---|---|
| «Which rules should exist» | cep_statement (datalake DB) |
| «Which rules are running» | The booted engine itself |
CREATE TABLE IF NOT EXISTS cep_statement (
statement_name VARCHAR(200) NOT NULL,
eql TEXT NOT NULL,
updated_at_ms BIGINT NOT NULL DEFAULT 0,
updated_by VARCHAR(64) NOT NULL DEFAULT '',
CONSTRAINT cep_statement_pkey PRIMARY KEY (statement_name)
);
One statement is one row, and registration writes while unregistration erases.
CEP is a rule engine, not asset management. Therefore, it records «what should run» in its own table.
enabled column is intentionalThe only signal to stop is the absence of a row, which is the state created by unregistration. A column that must always be true would be read like a non-existent switch.
The same applies to statement_name being the primary key — situations where the same name has two bodies are rejected rather than resolved.
updated_at_ms · updated_by are not read by code — they are for the person sitting in front of psql during a failure.
The three tables (cep_statement · cep_event_type · cep_api_key) are created by CEP itself upon startup. They are all in a «leave as is if present» format, so they apply directly even to installations with existing values.
Input — Valkey Stream
| Setting | Default |
|---|---|
| Stream Prefix | PP:CEP-IN-STREAM |
| Shard Count | 16 (cep.stream.shard_count) |
| Batch Read Count | 1000 |
| TLS | Off — values come from cache.ssl.enabled |
tls being «Off» is based on measured resultsThe platform Valkey configuration lacks a TLS port declaration and serves in plaintext.
🔴 If this value is incorrect, it will not fail loudly. Connecting to a plaintext server via TLS will result in a handshake timeout, which is read as a network failure rather than a configuration issue.
Failed or stalled events are preserved in a dead-letter queue — do not revert to silent disposal.
Output — One Topic Per Statement
Results are sent to a Valkey topic that is unique to each statement name.
- If there are 0 subscribers, only logs are left. Since publishing succeeds even without subscribers, this is where results silently disappear.
- When redeploying, stop the consumer first, then clear the registry. If the order is reversed, dead-letters will accumulate with every redeployment.
Time Zone
| Layer | Value | Determined By |
|---|---|---|
| Wire | epoch ms | No time zone. Same value in any PP_TZ |
| Window Boundary | Statement > PP_TZ > Rejection | WINDOW TUMBLING … AT TIME ZONE |
The registration response includes the actual time zone used and its source — this is to ensure that «which midnight it was» can be questioned later.
Do not guess and select. A silently selected time zone creates different answers for each deployment host.
Configuration Values
| Key | Default | Description |
|---|---|---|
cep.backend | aster | Backend — aster · flink. Defaults to aster if not set. Booting stops with the name for other values (including old values like esper · siddhi) |
cep.mode | native | If portable, also queries the reference backend (Aster CEP) |
cep.stream.shard_count | 16 | Input Shard |
cep.consumer.thread_count | 16 | Consumer Thread |
cep.api.max_eql_text_length | 100000 | Maximum statement length |
cep.storage.ttl_seconds | 864000 (10 days) | Operational metrics retention |
cep.api.key | X-API-Key of management API | |
cep.web.user · cep.web.password | Console login — if empty, only the console is closed |
The procedure for changing values is How to change configuration, and key rotation is Changing passwords · API keys.
The authority is the template rendered by the deployment.