> For the complete documentation index, see [llms.txt](https://kopens.gitbook.io/plantpulse-platform/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kopens.gitbook.io/plantpulse-platform/admin/modules/cep.md).

# cep (복합 이벤트)

## 역할

**Complex Event Processing** 엔진. 여러 센서 이벤트의 시간적 / 논리적 패턴을 실시간으로 감지하여 알람 / Flow 트리거 / 자동화를 수행합니다.

| 항목    | 값                                                 |
| ----- | ------------------------------------------------- |
| 모듈명   | `plantpulse-cep`                                  |
| 설치 경로 | `/opt/kopens/plantpulse-platform/plantpulse-cep/` |
| 포트    | **7400** (HTTP), 7401 (TLS)                       |
| 엔진    | Esper CEP                                         |
| 처리량   | 초당 500,000 이벤트                                    |

## 사용 예시

> "온도가 80°C 를 5초 이상 초과하고 동시에 압력이 평균보다 15% 이상 상승하면 위험 알람 발생"

이런 복합 조건을 EQL (Event Query Language) 스크립트로 정의하면 CEP 엔진이 실시간으로 매칭하여 결과를 발행합니다.

## 구성

```mermaid
graph LR
  K_IN[Kafka<br/>pp-tag-point] --> CEP[CEP Engine<br/>:7400]
  CONSOLE[Server 콘솔<br/>EQL 에디터] --> CEP
  CEP --> K_OUT[Kafka<br/>pp-cep-output]
  CEP --> ALARM[알람 발행]
  CEP --> FLOW[Flow 트리거]
  CEP --> STOMP[STOMP 푸시]
```

## 디렉토리 구조

```
plantpulse-cep/
├── app/
│   └── plantpulse-cep-web/           # CEP 관리 웹 앱
├── bin/start.sh stop.sh log-viewer.sh
├── logs/system.log
└── server/                            # 내장 Tomcat
    ├── conf/server.xml
    └── webapps/
```

## 주요 설정

### `app/plantpulse-cep-web/WEB-INF/classes/cep.properties`

```properties
cep.kafka.bootstrap=${PP_KAFKA_HOST}:${PP_KAFKA_PORT}
cep.kafka.input.topic=${PP_TOPIC_PREFIX}-tag-point
cep.kafka.output.topic=${PP_TOPIC_PREFIX}-cep-output
cep.kafka.group=cep-engine

cep.api.key=${PP_CEP_API_KEY}
cep.threads=16
cep.engine.partition.count=8

cep.script.dir=/opt/kopens/plantpulse-platform/plantpulse-cep/scripts
cep.window.max.duration.seconds=3600
```

### 인증

CEP 는 X-API-Key 헤더로 인증합니다. 서버 콘솔의 `PP_CEP_API_KEY` 와 일치해야 합니다.

```bash
curl -H "X-API-Key: ${PP_CEP_API_KEY}" \
  http://127.0.0.1:7400/api/v1/status
```

## EQL 예제

콘솔의 **AUTOMATION > CEP** 메뉴에서 EQL 스크립트를 등록 / 배포합니다.

```sql
-- 5초 윈도우에서 평균 온도가 80도 초과
@Name('high-temp')
SELECT tagId, avg(value) AS avg_temp
FROM TagPoint(tagId = 'TEMP_REACTOR_01').win:time(5 sec)
GROUP BY tagId
HAVING avg(value) > 80
OUTPUT EVERY 1 sec;

-- 두 태그의 시간 정렬 패턴
@Name('temp-pressure-correlation')
SELECT a.tagId AS temp_id, b.tagId AS pressure_id
FROM pattern [
  every a = TagPoint(tagId = 'TEMP_01' AND value > 80)
  -> b = TagPoint(tagId = 'PRESS_01' AND value > 100) WHERE timer:within(10 sec)
];
```

자세한 EQL 문법은 [사용자 가이드 - EQL 도움말](/plantpulse-platform/user/eql.md) 페이지를 참고해 주세요.

## 운영 명령

```bash
cd /opt/kopens/plantpulse-platform/plantpulse-startup

./restart-cep.sh           # CEP 모듈 재시작
./status.sh                # 7400 RUNNING 확인
```

## 자주 발생하는 문제

| 증상           | 원인          | 조치                                   |
| ------------ | ----------- | ------------------------------------ |
| 룰이 동작하지 않음   | 배포 안 됨      | 콘솔에서 "배포" 클릭                         |
| 처리 지연        | 윈도우 메모리 부족  | `cep.window.max.duration` 단축 또는 힙 상향 |
| Kafka lag 증가 | 처리 스레드 부족   | `cep.threads` 상향                     |
| API 인증 실패    | API key 불일치 | `PP_CEP_API_KEY` 통일                  |

## 관련 문서

* [모듈 인덱스](/plantpulse-platform/admin/modules.md)
* [EQL 도움말](/plantpulse-platform/user/eql.md)
* [CEP (사용자)](/plantpulse-platform/user/cep.md)
* [개발자: 플로우 엔진](/plantpulse-platform/developer/flow.md)
