4. SMS 이벤트 설정
이 장에서 하는 일
APM 이벤트를 문자 메시지로 받도록 설정합니다. 화면이나 메신저를 보지 않는 시간대에도 닿아야 하는 심각 이벤트에 씁니다.
다른 채널과 다른 점 — Slack·이메일은 APM 서버가 직접 보내지만, 문자는 별도 프로그램인
khan-event-processor 가 중계합니다. 문자 발송 업체와 연동하는 방식이 회사마다 달라, 그
차이를 이 프로그램이 흡수합니다.
연동 방식은 두 가지입니다. 쓰는 업체가 어느 쪽을 제공하는지 확인하고 하나를 고르십시오.
| 방식 | 어떻게 보내나 | 언제 고르나 |
|---|---|---|
| DBMS | 업체가 지정한 테이블에 발송 건을 넣습니다 | 업체가 데이터베이스 연동을 쓸 때 |
| REST API | 업체 API 로 HTTP 요청을 보냅니다 | 업체가 API 를 제공할 때 |
필요한 것 — 문자 발송 업체 계약과 연동 정보(DB 접속 정보 또는 API 주소·인증 키),
그리고 khan-event-processor 를 설치할 서버입니다.
전체 흐름
| 단계 | 하는 일 |
|---|---|
| 1 | APM 콘솔에서 SMS 이벤트 설정 |
| 2 | khan-event-processor 설치 |
| 3 | 연동 방식(DBMS 또는 REST API)에 맞춰 설정 |
| 4 | 프로그램 시작 후 테스트 발송으로 확인 |
APM 이벤트 설정하기
OPENMARU APM 콘솔에서 설정 > 모니터링 설정 으로 들어가 이벤트 연동 탭을 선택하면
SMS 이벤트 설정을 할 수 있습니다. 모든 채널 설정이 이 한 화면에 모여 있습니다.
SMS 이벤트 설정 항목

| 항목 | 설명 |
|---|---|
| ① 사용여부 | 이벤트를 SMS로 전송할 것인지를 TRUE 또는 FALSE 로 설정합니다. ex) TRUE |
| ② 요약 정보만 전송 여부 | 이벤트를 모아 서 전송 (FALSE: 단건 전송) |
| ③ 사용자 그룹전송 여부 | 사용자별로 그룹하여 전송 (DBMS Insert 방식은 사용 불가) |
| ④ 기본 Info 로그 전송 여부 | 경고정책에 없는 일반 정보 이벤트 발송 여부 |
| ⑤ 기본 Info 로그 받을 사용자 | 경고정책에 없는 일반 정보 이벤트를 받을 사용자 |
| ⑥ 메시지 레벨 | ALL, INFO, WARN, FORECAST, CRITICAL ex) ALL로 선택 후 "Event Processor" application.properties 설정에서 필터링 또는 반대로 적절히 활용 |
각 경고정책에서 "Alerts via"에서 "Event Processor" 추가 선택

khan-event-processor 설치
무엇을 하는 프로그램인가
APM 서버는 이벤트가 생기면 메시지 큐(RabbitMQ) 에 올립니다. khan-event-processor 는 그
큐를 구독하다가 메시지가 오면 문자 발송 업체가 받을 수 있는 형태로 바꿔 전달합니다.
구조는 이 장 앞의 문자 발송 경로 그림과 같습니다.
왜 따로 두는가 — 문자 발송 업체마다 받는 방식이 다릅니다. 어떤 곳은 지정한 테이블에 행을 넣으라 하고, 어떤 곳은 API 를 호출하라 합니다. 그 차이를 이 프로그램이 흡수해, APM 서버는 업체를 몰라도 됩니다. Slack·이메일처럼 APM 서버가 직접 보내지 않는 이유입니다.
어디에 설치하나 — RabbitMQ 와 문자 발송 업체 양쪽에 접속할 수 있는 서버면 됩니다. APM 서버와 같은 장비에 두어도 되고 따로 두어도 됩니다.
전달 방식 — 업체가 제공하는 쪽을 고릅니다.
| 방식 | 어떻게 보내나 | 준비물 |
|---|---|---|
| DBMS | 업체가 지정한 테이블에 발송 건을 넣습니다 | JDBC 접속 정보, 테이블 스키마 |
| REST API | 업체 API 로 HTTP 요청을 보냅니다 | API 주소, 인증 정보 |
설치
배포 파일(khan-event-processor-<버전>-dist.zip)의 압축을 풀면 아래 구조가 생깁니다.
khan-event-processor/
├── bin/
│ ├── start.sh · kill.sh 기동 · 종료
│ ├── status.sh · tail.sh 상태 확인 · 로그 보기
├── config/
│ └── application.properties ← 고칠 파일
├── lib/ 실행 파일 (건드리지 않음)
└── logs/
고칠 파일은 config/application.properties 하나입니다. 다음 절에서 항목을 설명합니다.
이 프로그램은 Java 로 동작합니다. 설치할 서버에 JRE 8 이상이 있어야 하며, java -version 으로
먼저 확인하십시오.
khan-event-processor 설정
고칠 파일은 두 개입니다.
| 파일 | 무엇을 정하나 |
|---|---|
config/application.properties | 큐·데이터베이스 접속 정보와 발송 조건 |
config/spring-context.xml | 어느 방식으로 보낼지 (DBMS / REST API) |
1) application.properties — 접속 정보와 발송 조건
RabbitMQ 접속 — APM 서버가 이벤트를 올리는 큐입니다. 값이 틀리면 프로그램은 떠 있지만 메시지를 하나도 받지 못합니다.
rabbitmq.host=localhost
rabbitmq.port=5672
rabbitmq.username=khan
rabbitmq.password=<비밀번호>
데이터베이스 접속 — DBMS 방식을 쓸 때만 필요합니다. REST API 방식이면 건너뜁니다.
jdbc.driverClass=org.mariadb.jdbc.Driver
jdbc.url=jdbc:mariadb://localhost:3306/sms
jdbc.user.name=sms
jdbc.user.password=<비밀번호>
Oracle 을 쓴다면 아래로 바꿉니다.
jdbc.driverClass=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@<주소>:1521:<SID>
발송 조건
| 항목 | 기본값 | 설명 |
|---|---|---|
sms.sendLevels | CRITICAL | 어느 등급을 문자로 보낼지. 쉼표로 여러 개 — ALL · INFO · WARN · FORECAST · CRITICAL |
sms.ignoreMinutes | 5 | 이 시간(분)보다 오래된 이벤트는 버립니다 |
sms.message.length | 200 | 문자 본문의 최대 길이. 넘으면 잘립니다 |
sendLevels 를 넓히면 문자가 쏟아집니다문자는 건당 비용이 들고 되돌릴 수 없습니다. CRITICAL 로 시작해 실제 발생량을 본 뒤
넓히십시오. ALL 은 시험 목적으로만 쓰십시오.
ignoreMinutes 는 프로그램이 잠시 멈췄다 다시 떴을 때 쌓여 있던 옛 이벤트가 한꺼번에
나가는 것을 막습니다.
2) spring-context.xml — 보내는 방식 고르기
smsEventToDatabase 경로에서 쓸 것만 남기고 나머지는 주석 처리합니다. 기본은 Oracle 이
열려 있습니다.
<doTry>
{/* Oracle 을 쓸 때 */}
<to uri="mybatis:SmsOracleDB.insert?statementType=Insert"/>
{/* MariaDB 를 쓸 때 */}
{/*<to uri="mybatis:SmsMariaDB.insert?statementType=Insert"/>*/}
{/* REST API 로 보낼 때 */}
{/*<to uri="direct:sendSMSHttp"/>*/}
REST API 방식이면 smsEventToHttp 경로의 주소도 업체가 알려 준 값으로 바꿉니다.
<to uri="http://localhost/send"/> {/* ← 업체 API 주소로 */}
DBMS Query 작성
DBMS 종류에 따라 파일 선택
config/mappers/SMS-MariaDB.xml
config/mappers/SMS-OracleDB.xml
아래 DBMS Table은 예제이며 고객사 상황에 맞게 아래 변수를 활용하여 작성합니다.
<insert id="insert" parameterType="com.opennaru.khan.monitoring.app.event.SmsEvent">
<![CDATA[
INSERT INTO
SMS_SKTELINK
(
CMP_MSG_ID,
CMP_USR_ID,
ODR_FG,
SMS_GB,
USED_CD,
MSG_GB,
WRT_DTTM,
SND_DTTM,
SND_PHN_ID,
RCV_PHN_ID,
CALLBACK,
SND_MSG,
CMP_SND_DTTM,
CMP_RCV_DTTM,
REG_SND_DTTM,
REG_RCV_DTTM,
EXPIRE_VAL,
SMS_ST,
RSLT_VAL,
RSRVD_ID,
RSRVD_WD
)
VALUES(
#{msgId},
'00000',
'1',
'1',
'00',
'A',
TO_CHAR(SYSDATE, 'YYYYMMDDHH24MISS'),
TO_CHAR(SYSDATE, 'YYYYMMDDHH24MISS'),
'02-1234-1234',
#{phoneNumber},
'02-1234-1234',
#{message},
NULL,
NULL,
NULL,
NULL,
0,
'0',
'99',
NULL,
NULL
)
]]>
</insert>
DBMS 방식 활용 가능 변수
| 구분 | 설명 |
|---|---|
#{msgId} | yyyyMMddHHmmss + “9” + 00001(순번) (20 자리) |
#{phoneNumber} | 받는 사람 번호 |
#{email} | 이메일 주소 |
#{subject} | 메시지 제목 |
#{message} | 메시지 내용(TEXT) |
#{htmlMessage} | 메시지 내용(HTML) |
REST API Data 설정(JSON)
{
"subject" : "${sms.subject}",
"contents" : "${sms.message}",
"html" : "${sms.htmlMessage}",
"phoneNumber" : "${sms.phoneNumber}",
"email" : "${sms.email}",
"sender" :
{
"emailAddress" : "knoxportal@samsung.com"
},
"smsRecipients" :
[
#foreach( $phone in $sms.phoneNumbers )
{
"address" : "${phone}"
}#if( $foreach.hasNext ), #end
#end
],
"mailRecipients" :
[
#foreach( $email in $sms.emails )
{
"address" : "${email}"
}#if( $foreach.hasNext ), #end
#end
]
}
REST API 방식 활용 가능 변수
| 구분 | 설명 |
|---|---|
${sms.msgId} | yyyyMMddHHmmss + “9” + 00001(순번) (20 자리) |
${sms.phoneNumber} | 받는 사람 번호 |
${sms.phoneNumbers} | 받는 사람 번호 목록, 그룹 전송 여부(Gather users) true : 사용자 배열 형태로 전달 (phoneNumber=null) false : 사용자 단위로 전달 |
${sms.subject} | 메시지 제목 |
${sms.message} | 메시지 내용(TEXT) |
${sms.htmlMessage} | 메시지 내용(HTML) |
${sms.eventKey.year} | 연도 yyyy (4자리) |
${sms.eventKey.month} | 월 MM (2자리) |
${sms.eventKey.date} | 일 dd (2자리) |
${sms.eventKey.hour} | 시간 HH (2자리) |
${sms.eventKey.minute} | 분 mm (2자리) |
${sms.eventKey.second} | 초 ss (2자리) |
${sms.eventKey.count} | 순번 (5자리) |
${sms.eventData.created} | 발생 시간 (TimeMillis) |
${sms.eventData.level} | 이벤트 레벨 |
${sms.eventData.agentType} | 에이전트 종류 |
${sms.eventData.hostname} | 호스트 이름 |
${sms.eventData.ipAddress} | 아이피 |
${sms.eventData.instanceId} | 인스턴스 이름 |
${sms.eventData.readableMessage} | 메시지 내용 (시간 및 에이전트 정보 제외) |
${sms.eventData.readableWhere} | 에이전트 정보 |
시작 및 중지
./start.sh
./tail.sh
테스트 방법
이벤트 > 이벤트 목록 으로 들어간 뒤 목록 오른쪽 위의 더보기(⋮) 단추를 누르고
심각 이벤트 발생테스트 를 선택하면 테스트용 심각 이벤트가 한 건 발송됩니다.

테스트 이벤트는 경고 정책 설정과 관계없이 admin 계정으로만 발송됩니다.