CEP (Complex Event Processing)
Table of Contents
- Overview
- Screen Layout — EQL Screens in the Automation Group
- Query Screen (
/query/index) - Statement Screen (
/statement/index) - Trigger Screen Reference
- Use Cases
- FAQ
- Related Screens
Overview
CEP (Complex Event Processing) is a rule engine that detects meaningful patterns in real-time event streams and immediately performs actions (store, publish, alarm). In the current left menu it is exposed as EQL Query and Statement under the Automation group.
| Submenu | Internal URL | Purpose |
|---|---|---|
| EQL Query | /query/index | Run ad-hoc EQL (Event Query Language) queries against live streams and see results immediately |
| Statement | /statement/index | Browse per-asset domain rules (state / aggregate / event / command) |
CEP rule results are also wired automatically into the asset triggers (flow_on_asset_event, etc.) of Flow.
Screen Layout — EQL Screens in the Automation Group
| Screen | Primary user | One-line summary |
|---|---|---|
| Query | Operations analyst | Run a single line of EQL instantly and view results from the live stream |
| Statement | Operator | Check the status and execution statistics of domain rules registered on assets |
Query Screen (/query/index)
A screen for writing ad-hoc EQL queries and running them immediately with the ▶ button to view results from the live stream.
Top — Query Save & History
🔍 쿼리 [💾 이 쿼리를 저장] [↩ 마지막 쿼리] [▼ 이력 ▼]
| Button | Action |
|---|---|
| Save this query | saveQueryHistory() — save the current EQL as a favorite |
| Last query | loadLastQuery() — load the most recently executed query |
| History dropdown | loadQueryHistory() — show saved query history in a dropdown (scrolls up to 400px) |
Queries written in the top bar or in the EQL input box of the left menu are automatically passed to this screen for execution.
EQL Input Panel
A large input box with a black border (textarea[name=epl], 8 rows high) plus two icons at the upper right.
| Icon | Action |
|---|---|
| ▶ (play, white) | runQuery() — run the EQL |
| ⚙ (gear, gray) | resultConfig() — result display options dialog (display_count, expire_time, result_format, chart options, etc.) |
Execution Result Panel
The result panel header shows the following.
| Item | Display |
|---|---|
| Left | ⚪ "Query execution results" + [배치시간=..., EQL ID=...] (if it is a saved query) |
| Right | ▶ Start / ⏸ Stop buttons (pause reception of real-time results) |
Result Chart (query_result_chart, 160px)
- Input count (
input_count_cur) and inputs per minute (input_count_min) are shown at the upper right - The chart fills in as result data starts arriving. Real-time line chart format
- Before data arrives: "Waiting for chart data..." (spinner icon)
Result Table (query_result_table)
| Column | Description |
|---|---|
| # | Row number |
| Output time | Time the EQL emitted the result |
| Rows | Number of rows in one emit |
| Data | Result body in JSON or table form |
If you do not stop execution, the result table keeps accumulating. Press Stop or run a new query to halt accumulation.
Trigger Screen Reference
The separate Trigger menu is currently disabled in the unified sidebar. In installations still operating the legacy /trigger/index screen or internal APIs, treat the content below as legacy reference only. For new automation, use the trigger nodes of Flow and the Automation > EQL Query / Statement workflow first.
Manages user-defined triggers that publish EQL match results to external message channels or store them in storage.
Top Toolbar
⚡ 트리거 [➕ 트리거 추가] [↻]
List Table
At the right of the list panel header there are three buttons: Deploy selected triggers / Undeploy / Redeploy all.
| Column | Width | Description |
|---|---|---|
| Select | 50px | Checkbox for bulk deploy/undeploy |
| Status | 80px | Deployed/undeployed badge |
| Trigger ID | 110px | System-assigned ID |
| Trigger name | Description | Auto | Operator-defined metadata |
| MQ streaming | 70px | Whether MQ publishing is used (Y/N) |
| Storage save | 70px | Whether results are loaded into storage (Y/N) |
| Total executions | 70px | Cumulative match count |
| Last execution date | 110px | Most recent match time |
| Errors | 70px | Cumulative error count |
| Registered | 110px | Registration time |
| Last modified | 110px | Last modification time |
| Actions | 80px | Edit / delete buttons |
An information box is displayed at the bottom of the page.
Using user-defined triggers You can add user-defined triggers that perform an action when a specific condition is met. You can additionally stream the result through MQ or save it to storage.
Trigger Add/Edit Form
The Add trigger button at the top navigates to the form screen (/trigger/form).
1) Basic information fieldset
| Input | path | Width | Notes |
|---|---|---|---|
| Trigger ID | trigger_id | 200px | Read-only — assigned automatically by the system |
| Trigger name | trigger_name | 450px | A name that is easy for people to identify |
| Description | trigger_desc | 600 × 100px (textarea) | Purpose of the trigger |
2) EQL fieldset
| Input | path | Description |
|---|---|---|
| EQL | epl | 8-row textarea — write the EQL query (SELECT ... FROM ... WHERE ...) |
| ▶ Test run | (icon) | runQuery() — run the written EQL immediately as a test. Results appear in the Query results table (graph_query_result) below |
Query results table (test run result preview):
| Column | Description |
|---|---|
| Output time | Time the EQL emitted the result |
| Data | Result body |
3) Streaming fieldset
| Input | path | Description |
|---|---|---|
| MQ output | use_mq (checkbox) | Whether to publish result data to an external message channel |
| Protocol | mq_protocol (selector) | MQTT or KAFKA |
| Destination | mq_destination (450px) | Target topic/channel — separators: KAFKA -, MQTT /. e.g. device-machine-topic-1 or device/machine/topic_1 |
4) Storage save fieldset
| Input | path | Description |
|---|---|---|
| Save to storage | use_storage (checkbox) | Whether to load result data into storage |
The storage table name and column definition area is currently disabled because the trigger result storage table is fixed.
Form submission
| Button | Action |
|---|---|
| List (☰) | Return to the trigger list screen |
| Save (blue) | Validate the input and save. Saving alone does not deploy the trigger; you must click Deploy selected triggers on the list screen for it to start running |
Redeploy All
| Button | Location | Action |
|---|---|---|
| Redeploy all | Right of the list panel header (🔁) | Redeploy all registered triggers at once. Use after a rule engine restart or after system inspection |
Operating Procedure
- Add trigger → enter EQL, streaming and storage options → Save
- Check the trigger in the list → click Deploy selected triggers → status changes to "Deployed"
- To pause it during operation, click Undeploy → status changes to "Undeployed"
- After inspection, restart everything at once with Redeploy all
Statement Screen (/statement/index)
A screen for checking the status and execution statistics of domain rules (state / aggregate / event / command) registered per asset.
Top Search & Filter
√ 스테이트먼트 [유형 ▼] [검색 ...] [조회] [↻]
| Control | Options | Description |
|---|---|---|
Type selector (search_type) | (All) · State (CONTEXT) · Aggregate (AGGREGATION) · Event (EVENT) · Command (COMMAND) | Filter by the four rule types |
Search input (txt) | (250px) | placeholder: "Search ..." — rule name / applied asset ID / description keyword |
| Search | (red + 🔍) | search() — refresh the list with the conditions |
| Refresh | (red + ↻) | refresh() — reload the screen |
The Four Rule Types
| Code | Name | Meaning |
|---|---|---|
CONTEXT | State | Defines the asset's current state (running / stopped / faulty) in EQL |
AGGREGATION | Aggregate | Aggregates values such as average or maximum over a given window |
EVENT | Event | Publishes a domain event when a specific pattern (threshold exceeded, etc.) occurs |
COMMAND | Command | Issues a command (flow_on_asset_command) to the asset on a rule match |
List Table
| Column | Width | Description |
|---|---|---|
| Status | 80px | Active/inactive badge |
| Applied asset ID | 150px | Identifier of the asset the rule is assigned to |
| Type | 80px | One of the four types (see table above) |
| Statement name | Auto | Rule name |
| Description | 300px | Rule notes |
| Total executions | 80px | Cumulative number of rule matches |
| Last execution date | 120px | Most recent match time |
| Errors | 60px | Cumulative error count |
| Registered | 120px | Rule registration time |
| Detail | 50px | Opens the rule detail screen (/statement/view) |
Detail View
Clicking the Detail button in the list navigates to a separate screen (/statement/view/{asset_id}/{statement_name}) where you can see the following (see Statement Detail Screen below).
- The rule's EQL body
- Execution result history
- Execution trend / aggregation
- Analysis performance trend
- Status history
Statement Detail Screen
The analysis view reached via the Detail button (statement/view.jsp, 715 lines). It gathers all operational information for a single rule on one screen.
Top — Identification Header
√ 스테이트먼트 | {statement_name} [ {asset_id} ] [← 목록] [↻]
| Button | Action |
|---|---|
| List (←) | Return to /statement/index |
| Refresh | Reload the screen |
Panel 1 — Statement Information (5-column table)
| Column | Width | Description |
|---|---|---|
| Status | 250px | Active/inactive + last execution time |
| Statement name | Auto | Rule name |
| Applied asset | 200px | Asset domain badge — click to go to the asset tree |
| Type | 200px | State (CONTEXT) · Aggregate (AGGREGATION) · Event (EVENT) · Command (COMMAND) |
| Registered | 160px | Rule registration time |
EQL Body fieldset
The rule's EQL query body is shown as-is. You can copy it from the text area and paste it into the Query screen for a test run.
Input/Output fieldset
| Area | Display |
|---|---|
| Input series | List of tags and event types used as rule inputs |
| Output series | Domain event types published by the rule |
| Reset error count | Resets only the cumulative error count to 0 (resetErrorCount(asset_id, statement_name)) |
Panel 2 — Execution Result History (4-column table)
| Column | Width | Description |
|---|---|---|
| Execution time | 160px | Time the rule executed |
| Result | 60px | Success (green) / error (red) |
| Result value / error message | Auto | Result body on success, error message on failure |
| Copy | 50px | 📋 — copy the result value / error message to the clipboard |
Panel 3 — Execution Trend Chart
| Item | Description |
|---|---|
| Header | 📊 "Execution trend" |
| Buttons | Today (switchTrendDay(0)) / Yesterday (switchTrendDay(-1)) toggle |
| Chart | Stacked bars of successes/errors by hour over 24 hours (series: success, error) |
Panel 4 — Execution Aggregation
| Item | Description |
|---|---|
| Header | 📊 "Execution aggregation" |
| Buttons | Today (switchAggDay(0)) / Yesterday (switchAggDay(-1)) toggle |
| fieldset 1 | Per-minute aggregation (counts by hour, average throughput, etc.) |
| fieldset 2 | Priority or result distribution |
Panel 5 — Analysis Performance Trend
| Item | Description |
|---|---|
| Header | 🖥 "Analysis performance trend" |
| Buttons | Today (switchCpuDay(0)) / Yesterday (switchCpuDay(-1)) toggle |
| Chart | Time series of CPU / processing time used for rule processing — identifies heavy rules |
Panel 6 — Status History Table
| Column | Description |
|---|---|
| Change time | Time the rule status changed (activated, undeployed, redeployed, etc.) |
| Status | The new status |
Use this to trace the rule lifecycle (when it was activated, undeployed, or modified).
Usage Patterns
| Analysis flow | Screen flow |
|---|---|
| Diagnosing a failing rule | Execution result history → error message → copy → review EQL body → test run on the Query screen |
| Identifying heavy rules | Analysis performance trend → hours with high CPU usage → simplify the EQL body |
| Analyzing rule match distribution | Execution trend + aggregation → match patterns by hour |
| Maintaining operational rules | Status history → trace activation/deactivation points |
Use Cases
| Scenario | Screen | Procedure |
|---|---|---|
| Instantly check current line operating status | Query | Enter SELECT * FROM AssetData.win:time(1 sec) WHERE asset_id='LINE-A' in the EQL input box → ▶ |
| Test and deploy a new alarm rule | Trigger | Add → write EQL → ▶ test run → check results → Save → Deploy |
| Relay asset events to an external SCADA | Trigger | Publish EQL match messages to the MQTT topic scada/line-a/events |
| Inspect rules per asset | Statement | Type = EVENT + search by asset ID → list of active rules + execution counts |
| Suspected rule flood | Statement | Start with rules having the highest total execution counts → review EQL/inputs in the detail view |
| Receive rule results through automation | Flow | Receive domain rule results directly with the flow_on_asset_event trigger |
FAQ
Q. Is EQL the same as SQL?
A. It uses similar syntax, but EQL is an event processing language that adds the concepts of time windows and streams. For example, Point.win:time(5 sec) processes only the last 5 seconds of data, and Point.win:length(100) processes only the last 100 records.
Q. Are queries executed on the Query screen saved? A. Running ▶ alone is temporary; you must press Save this query to store it in favorites. For one-off analysis you do not need to save it.
Q. I saved a trigger but it does not run. A. Saving only registers the definition. You must check the trigger in the list and click Deploy selected triggers so that it is registered with the rule engine and matching begins.
Q. How should I set the trigger destination? A. The separator differs by protocol.
- KAFKA: hyphen (
-) separated — e.g.device-machine-topic-1 - MQTT: slash (
/) separated — e.g.device/machine/topic_1
Q. Search on the Statement screen returns no results. A. Check whether you selected "Type" (All) in the type selector. Also, entering only part of an asset ID performs a partial-match search.
Q. The total execution count is abnormally high.
A. The rule's input window is most likely too narrow, or the match condition too broad. Review the EQL via the Detail button, or pre-filter messages with the trigger pattern (*_pattern) in Flow.
Q. The trigger's EQL test run returns empty results.
A. There may be no incoming data at the time of the test, or the EQL window may be so long that the first match is delayed. Leave the test running for about a minute and check again, or shorten the window (win:time(1 sec)) for the test.
Q. How do I pause a trigger temporarily? A. Check the trigger in the list and click Undeploy. To run it again, use Deploy selected triggers.
Q. Are rules assigned to assets automatically? A. Depending on the operating environment settings, default domain rules may be assigned automatically when an asset is registered. Check the currently applied rules on the Statement screen; to add or remove rules, work through the system administrator or the per-asset configuration screen.
Q. I want to process EQL results automatically.
A. With the asset triggers (flow_on_asset_event / flow_on_asset_alarm, etc.) in Flow, you can automatically receive domain rule results and chain follow-up actions (issuing work orders, sending email, calling external APIs).
Related Screens
- Data Points — the time series tag data that feeds EQL
- Alarms — operations screen for alarms raised by triggers
- Flow — process rule results automatically with asset triggers
- Factory Management — assign rules in the asset tree
- Status Code Definitions — status codes evaluated by rules (NORMAL/WARN/ERROR)
- Diagnostics — error logs during rule processing