본문으로 건너뛰기

4. SMS 이벤트 설정

이 장에서 하는 일

APM 이벤트를 문자 메시지로 받도록 설정합니다. 화면이나 메신저를 보지 않는 시간대에도 닿아야 하는 심각 이벤트에 씁니다.

다른 채널과 다른 점 — Slack·이메일은 APM 서버가 직접 보내지만, 문자는 별도 프로그램인 khan-event-processor 가 중계합니다. 문자 발송 업체와 연동하는 방식이 회사마다 달라, 그 차이를 이 프로그램이 흡수합니다.

APM 서버가 이벤트를 RabbitMQ 큐에 올리면 khan-event-processor 가 구독해 문자 발송 업체가 받는 형태로 바꿔 전달하고, 업체가 휴대전화로 문자를 보낸다

연동 방식은 두 가지입니다. 쓰는 업체가 어느 쪽을 제공하는지 확인하고 하나를 고르십시오.

방식어떻게 보내나언제 고르나
DBMS업체가 지정한 테이블에 발송 건을 넣습니다업체가 데이터베이스 연동을 쓸 때
REST API업체 API 로 HTTP 요청을 보냅니다업체가 API 를 제공할 때

필요한 것 — 문자 발송 업체 계약과 연동 정보(DB 접속 정보 또는 API 주소·인증 키), 그리고 khan-event-processor 를 설치할 서버입니다.

전체 흐름

단계하는 일
1APM 콘솔에서 SMS 이벤트 설정
2khan-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 실행 환경이 필요합니다

이 프로그램은 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.sendLevelsCRITICAL어느 등급을 문자로 보낼지. 쉼표로 여러 개 — ALL · INFO · WARN · FORECAST · CRITICAL
sms.ignoreMinutes5이 시간(분)보다 오래된 이벤트는 버립니다
sms.message.length200문자 본문의 최대 길이. 넘으면 잘립니다
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 계정으로만 발송됩니다.