시나리오 예외 규칙 생성
지정한 탐지 시나리오에 새로운 예외 규칙을 등록합니다. 조건 트리(exprs)와 일치하는 이벤트는 유효 기간(valid_from-valid_until) 동안 탐지에서 제외됩니다.
필요 권한
관리자 이상의 계정으로 이용할 수 있습니다.
HTTP 요청
POST /api/sonar/exception-rules
cURL 예시
curl -H "Authorization: Bearer <API_KEY>" \
-d type="stream" \
-d scenario_guid="a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
-d description="사내 관리자 IP 제외" \
-d 'exprs={"field":"src_ip","type":"IP","operator":"EQ","value":"203.0.113.10"}' \
--data-urlencode 'valid_from=2026-06-01 00:00:00+0900' \
--data-urlencode 'valid_until=2026-12-31 23:59:59+0900' \
-X POST \
https://HOSTNAME/api/sonar/exception-rules
요청 매개변수
| 키 | 필수 | 타입 | 설명 | 비고 |
|---|---|---|---|---|
| type | O | 문자열 | 시나리오 유형 | stream(실시간) 또는 batch(배치) 중 하나. 대소문자 구분 없음 |
| scenario_guid | O | 문자열 | 시나리오 GUID | 36자 |
| description | X | 문자열 | 메모 | 최대 2,000자 |
| exprs | O | 문자열 키/값 | 조건 트리 | JSON 객체. 구조는 아래 참고 |
| valid_from | O | 날짜 | 유효 시작 일자 | 형식: yyyy-MM-dd HH:mm:ssZ |
| valid_until | O | 날짜 | 유효 종료 일자 | 형식: yyyy-MM-dd HH:mm:ssZ. valid_from보다 늦어야 함 |
exprs 객체 속성
exprs는 리프 노드(단일 조건) 또는 그룹 노드(조건 그룹) 중 하나의 형태를 가지는 JSON 객체입니다.
리프 노드(단일 조건)의 속성:
- field (문자열): 필드 이름. 영문자, 숫자,
_,.,-만 사용 가능, 최대 128자 - type (문자열): 값 타입.
STRING,NUMBER,BOOLEAN,IP중 하나 - operator (문자열): 비교 연산자. type에 따라 사용 가능한 값이 다름(하단 표 참고)
- value: 비교 대상 값. operator가
IS_NULL,IS_NOT_NULL이면 생략, 그 외에는 필수(STRING은 문자열, NUMBER는 숫자, BOOLEAN은 불리언, IP는 IP 주소 문자열)
| type 값 | 사용 가능한 operator |
|---|---|
STRING | EQ, NEQ, STARTS_WITH, ENDS_WITH, CONTAINS, IS_NULL, IS_NOT_NULL |
NUMBER | EQ, NEQ, GT, GTE, LT, LTE, IS_NULL, IS_NOT_NULL |
BOOLEAN | EQ, NEQ, IS_NULL, IS_NOT_NULL |
IP | EQ, NEQ, IS_NULL, IS_NOT_NULL |
그룹 노드(조건 그룹)의 속성:
- operator (문자열): 그룹 연산자.
AND,OR,NOT,SRC_IP,DST_IP,SRC_IP_DST_IP중 하나 - operands (객체 배열): 하위 조건 목록(리프 노드 또는 그룹 노드).
NOT은 1개,SRC_IP·DST_IP는 1개(field가 각각src_ip,dst_ip이고 type이IP, operator가EQ또는NEQ인 리프 노드),SRC_IP_DST_IP는 2개(첫 번째 field는src_ip, 두 번째는dst_ip, 둘 다 typeIP·operatorEQ또는NEQ)여야 함
Note
조건 트리에는 다음 제약이 있습니다: 리프 노드(조건) 최대 50개, 중첩 깊이 최대 3단계, 그룹 노드 최대 10개.
정상 응답
{
"guid": "b2c3d4e5-f6a7-8901-bcde-f12345678901"
}
- guid (문자열): 생성된 예외 규칙 GUID
오류 응답
필수 매개변수가 누락된 경우
HTTP 상태 코드 400 응답
{
"error_code": "null-argument",
"error_msg": "scenario_guid should be not null"
}
type 값이 stream, batch가 아닌 경우
HTTP 상태 코드 400 응답
{
"error_code": "invalid-argument",
"error_msg": "No enum constant com.logpresso.sonar.api.exceptionrule.ExceptionRuleType.FOO"
}
Note
type=global처럼 열거형 이름 자체는 유효하지만 stream, batch가 아닌 값을 지정하면 위와 다른 메시지("unsupported exception rule type: GLOBAL")로 같은 400 오류가 반환됩니다. 이 동작은 시나리오 예외 규칙 일괄 삭제 API에도 동일하게 적용됩니다. 다만 만료된 예외 규칙 삭제 API는 이 경로에 도달하기 전에 시나리오를 찾지 못해 scenario-not-found 오류를 반환합니다.
description 값의 길이가 잘못된 경우
HTTP 상태 코드 400 응답
{
"error_code": "invalid-argument",
"error_msg": "'description' must be shorter than or equal to 2000 characters."
}
valid_from이 valid_until보다 늦은 경우
HTTP 상태 코드 400 응답
{
"error_code": "invalid-argument",
"error_msg": "valid_from should be earlier than valid_until"
}
조건 트리가 제약을 초과한 경우
HTTP 상태 코드 400 응답
{
"error_code": "invalid-argument",
"error_msg": "too many conditions: 51"
}
exprs의 field 형식이 올바르지 않은 경우
HTTP 상태 코드 400 응답
{
"error_code": "invalid-argument",
"error_msg": "invalid field format: src ip"
}
시나리오가 존재하지 않는 경우
HTTP 상태 코드 500 응답
{
"error_code": "illegal-state",
"error_msg": "scenario not found: a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
권한이 없는 경우
HTTP 상태 코드 500 응답
{
"error_code": "illegal-state",
"error_msg": "no-permission"
}