Skip to content

4. SMS Event Configuration

What This Chapter Does

It configures APM events to arrive as text messages. It is used for critical events that have to reach someone even outside the hours when a screen or messenger is being watched.

What is different from other channels -- Slack and email are sent by the APM server directly, but text messages are relayed by a separate program, khan-event-processor. How a text-message provider is integrated differs by company, and this program absorbs that difference.

The APM server puts an event on a RabbitMQ queue; khan-event-processor subscribes to it, converts it into the form the text-message provider accepts, and passes it on; the provider then sends the text to the mobile phone

There are two integration methods. Check which one your provider offers and choose one.

MethodHow it sendsWhen to choose it
DBMSInserts the send record into a table the provider specifiesWhen the provider uses database integration
REST APISends an HTTP request to the provider's APIWhen the provider offers an API

What you need -- a contract with a text-message provider and its integration details (database connection details, or an API address and authentication key), plus a server on which to install khan-event-processor.

Overall Flow

StepWhat you do
1Configure the SMS event settings in the APM console
2Install khan-event-processor
3Configure it for the integration method (DBMS or REST API)
4Start the program and confirm with a test send

Configuring Events in APM

In the OPENMARU APM console, go to Settings > Monitoring Settings and select the Event Channels tab to configure the SMS event settings. Every channel setting is gathered on this one screen.

SMS Event Configuration Items

ItemDescription
① EnabledWhether to send events by SMS, set as TRUE or FALSE. e.g. TRUE
② Send in Summary OnlyGathers events and sends them together (FALSE: sends one at a time)
③ Use Bulk User DeliveryGroups by user before sending (not available with the DBMS insert method)
④ Send Info-Level EventsWhether to send general info events that are not in an alert policy
⑤ Info Event RecipientThe user who receives general info events that are not in an alert policy
⑥ Delivered Message LevelsALL, INFO, WARN, FORECAST, CRITICAL. e.g. select ALL and filter in the "Event Processor" application.properties settings, or the other way round

In each alert policy, add "Event Processor" under "Alerts via".

Installing khan-event-processor

What the Program Does

When an event occurs, the APM server puts it on a message queue (RabbitMQ). khan-event-processor subscribes to that queue and, when a message arrives, converts it into the form the text-message provider accepts and passes it on.

The structure is the diagram at the start of this chapter, What This Chapter Does.

Why it is kept separate -- every text-message provider receives differently. Some ask you to insert a row into a table they specify; others ask you to call an API. This program absorbs that difference so the APM server does not have to know the provider. That is why it is not sent directly by the APM server the way Slack and email are.

Where to install it -- any server that can reach both RabbitMQ and the text-message provider. It can be on the same machine as the APM server or on a separate one.

Delivery method -- choose whichever the provider offers.

MethodHow it sendsWhat you need
DBMSInserts the send record into a table the provider specifiesJDBC connection details, the table schema
REST APISends an HTTP request to the provider's APIThe API address, authentication details

Installation

Unpacking the distribution file (khan-event-processor-<version>-dist.zip) produces this structure.

khan-event-processor/
├── bin/
│ ├── start.sh · kill.sh start · stop
│ ├── status.sh · tail.sh check status · view logs
├── config/
│ └── application.properties ← the file to edit
├── lib/ executables (do not touch)
└── logs/

The only file to edit is config/application.properties. The next section explains its items.

A Java runtime is required

This program runs on Java. The server it is installed on needs JRE 8 or later; check first with java -version.

Configuring khan-event-processor

There are two files to edit.

FileWhat it decides
config/application.propertiesQueue and database connection details, and the send conditions
config/spring-context.xmlWhich method to send with (DBMS / REST API)

1) application.properties -- Connection Details and Send Conditions

RabbitMQ connection -- the queue the APM server puts events on. If the values are wrong the program stays up but receives nothing at all.

rabbitmq.host=localhost
rabbitmq.port=5672
rabbitmq.username=khan
rabbitmq.password=<password>

Database connection -- required only for the DBMS method. Skip it for the REST API method.

jdbc.driverClass=org.mariadb.jdbc.Driver
jdbc.url=jdbc:mariadb://localhost:3306/sms
jdbc.user.name=sms
jdbc.user.password=<password>

For Oracle, change it to the following.

jdbc.driverClass=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@<address>:1521:<SID>

Send conditions

ItemDefaultDescription
sms.sendLevelsCRITICALWhich levels to send by text. Several can be given, comma-separated -- ALL, INFO, WARN, FORECAST, CRITICAL
sms.ignoreMinutes5Events older than this many minutes are discarded
sms.message.length200The maximum length of the text body. Anything beyond it is cut
Widening sendLevels makes text messages pour in

Text messages cost money per message and cannot be taken back. Start with CRITICAL, look at the actual volume, then widen. Use ALL for testing only.

ignoreMinutes prevents old events that piled up while the program was briefly down from going out all at once when it comes back.

2) spring-context.xml -- Choosing the Send Method

In the smsEventToDatabase route, leave only what you use and comment out the rest. Oracle is open by default.

<doTry>
{/* When using Oracle */}
<to uri="mybatis:SmsOracleDB.insert?statementType=Insert"/>
{/* When using MariaDB */}
{/*<to uri="mybatis:SmsMariaDB.insert?statementType=Insert"/>*/}
{/* When sending through a REST API */}
{/*<to uri="direct:sendSMSHttp"/>*/}

For the REST API method, also change the address in the smsEventToHttp route to the value the provider gave you.

<to uri="http://localhost/send"/> {/* ← to the provider's API address */}

Writing the DBMS Query

Choose the file according to the type of DBMS.

config/mappers/SMS-MariaDB.xml
config/mappers/SMS-OracleDB.xml

The DBMS table below is an example; write it to suit the customer's situation using the variables listed afterwards.

<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>

Variables Available with the DBMS Method

NameDescription
#{msgId}yyyyMMddHHmmss + "9" + 00001 (sequence) (20 characters)
#{phoneNumber}The recipient's number
#{email}The email address
#{subject}The message subject
#{message}The message body (TEXT)
#{htmlMessage}The message body (HTML)

REST API Data Configuration (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
]
}

Variables Available with the REST API Method

NameDescription
${sms.msgId}yyyyMMddHHmmss + "9" + 00001 (sequence) (20 characters)
${sms.phoneNumber}The recipient's number
${sms.phoneNumbers}The list of recipient numbers. With bulk user delivery (Gather users) true: passed as an array of users (phoneNumber=null); false: passed per user
${sms.subject}The message subject
${sms.message}The message body (TEXT)
${sms.htmlMessage}The message body (HTML)
${sms.eventKey.year}The year, yyyy (4 digits)
${sms.eventKey.month}The month, MM (2 digits)
${sms.eventKey.date}The day, dd (2 digits)
${sms.eventKey.hour}The hour, HH (2 digits)
${sms.eventKey.minute}The minute, mm (2 digits)
${sms.eventKey.second}The second, ss (2 digits)
${sms.eventKey.count}The sequence (5 digits)
${sms.eventData.created}The time it occurred (TimeMillis)
${sms.eventData.level}The event level
${sms.eventData.agentType}The agent type
${sms.eventData.hostname}The host name
${sms.eventData.ipAddress}The IP address
${sms.eventData.instanceId}The instance name
${sms.eventData.readableMessage}The message body (excluding the time and agent information)
${sms.eventData.readableWhere}The agent information

Starting and Stopping

./start.sh
./tail.sh

How to Test

Go to Event > Event List, press the more (⋮) button at the top right of the list, and select Test Sample Critical Event. One test critical event is sent.

Who receives it

The test event is sent only to the admin account, regardless of the alert policy settings.