scouter.plugin.server.alert.email.EmailPlugin.java Source code

Java tutorial

Introduction

Here is the source code for scouter.plugin.server.alert.email.EmailPlugin.java

Source

/*
 *  Copyright 2016 Scouter Project.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); 
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License. 
 *  
 *  @author Sang-Cheon Park
 */
package scouter.plugin.server.alert.email;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.commons.mail.DefaultAuthenticator;
import org.apache.commons.mail.Email;
import org.apache.commons.mail.SimpleEmail;

import scouter.lang.AlertLevel;
import scouter.lang.TextTypes;
import scouter.lang.TimeTypeEnum;
import scouter.lang.counters.CounterConstants;
import scouter.lang.pack.AlertPack;
import scouter.lang.pack.MapPack;
import scouter.lang.pack.ObjectPack;
import scouter.lang.pack.PerfCounterPack;
import scouter.lang.pack.XLogPack;
import scouter.lang.plugin.PluginConstants;
import scouter.lang.plugin.annotation.ServerPlugin;
import scouter.net.RequestCmd;
import scouter.server.Configure;
import scouter.server.CounterManager;
import scouter.server.Logger;
import scouter.server.core.AgentManager;
import scouter.server.db.TextRD;
import scouter.server.netio.AgentCall;
import scouter.util.DateUtil;
import scouter.util.HashUtil;

import common.Util;

/*  (BuiltInPlugin) */
import scouter.plugin.server.hanium.timecontroller.ObjectContainer;

/**
 * Scouter server plugin to send alert via email
 * Sang-Cheon Park(nices96@gmail.com) on 2016. 3. 28.
 * 
 * ??   ?   
 * @author 2017.05.14. revised by occidere
 */
public class EmailPlugin {

    // Get singleton Configure instance from server
    final Configure conf = Configure.getInstance();

    private static AtomicInteger ai = new AtomicInteger(0);
    private static List<Integer> javaeeObjHashList = new ArrayList<Integer>();

    /*   */
    private static ObjectContainer objectContainer = new ObjectContainer();

    public EmailPlugin() {
        if (ai.incrementAndGet() == 1) {
            ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);

            //thread count check
            executor.scheduleAtFixedRate(new Runnable() {
                @Override
                public void run() {
                    for (int objHash : javaeeObjHashList) {
                        try {
                            if (AgentManager.isActive(objHash)) {
                                ObjectPack objectPack = AgentManager.getAgent(objHash);
                                MapPack mapPack = new MapPack();
                                mapPack.put("objHash", objHash);
                                mapPack = AgentCall.call(objectPack, RequestCmd.OBJECT_THREAD_LIST, mapPack);

                                final int LIMIT = 30; //?  . ? 20 ?    30 ? ?

                                //  .   ?  thread exceed threshold  ?? .
                                int threadCountThreshold = conf.getInt("ext_plugin_thread_count_threshold", LIMIT);
                                int threadCount = mapPack.getList("name").size();

                                /*   ? */
                                if (threadCountThreshold != 0 && threadCount > threadCountThreshold) {
                                    AlertPack ap = new AlertPack();

                                    //  ? 2  FATAL, ? WARN
                                    if (threadCount > threadCountThreshold * 2)
                                        ap.level = AlertLevel.FATAL;
                                    else
                                        ap.level = AlertLevel.WARN;

                                    ap.objHash = objHash;
                                    ap.title = "  !";
                                    ap.message = objectPack.objName + "?   " + threadCount
                                            + ", (" + LIMIT + ") !";
                                    ap.time = System.currentTimeMillis();
                                    ap.objType = objectPack.objType;

                                    long limitTime = conf.getLong("ext_plugin_thread_limit_time", 120000); //2
                                    long safeTime = conf.getLong("ext_plugin_thread_safe_time", 180000); //3

                                    //? ? objectPack.objName ? 
                                    if (objectContainer.sendAlert(ap, objectPack.objName, limitTime, safeTime))
                                        alert(ap);
                                }
                            }
                        } catch (Exception e) {
                            // ignore
                        }
                    }
                }
            }, 0, 5, TimeUnit.SECONDS); //5 
        }
    }

    /**
     * ? ? ??  <br>
     *   ? ?? ?? <br>
     * @param pack ?? ?   pack
     */
    @ServerPlugin(PluginConstants.PLUGIN_SERVER_ALERT)
    public void alert(final AlertPack pack) {
        /* Email    */
        if (conf.getBoolean("ext_plugin_email_send_alert", true)) {

            /* 
             * Get log level (0 : INFO, 1 : WARN, 2 : ERROR, 3 : FATAL)
             * 0   ??  ??  ?.
             */
            int level = conf.getInt("ext_plugin_email_level", 0);

            /* ?  level   ? ? ?  */
            if (level <= pack.level) {
                new Thread() {
                    public void run() {
                        try {

                            // Get server configurations for email
                            String hostname = conf.getValue("ext_plugin_email_smtp_hostname", "smtp.gmail.com"); // smtp 
                            int port = conf.getInt("ext_plugin_email_smtp_port", 587); // smtp ?

                            String username = conf.getValue("ext_plugin_email_username", "haniumscouter@gmail.com"); // ? ?? 
                            String password = conf.getValue("ext_plugin_email_password", "dkqorhvk!@#$"); // ? ?? 

                            boolean tlsEnabled = conf.getBoolean("ext_plugin_email_tls_enabled", true); // tls (gamil? true)

                            String from = conf.getValue("ext_plugin_email_from_address", "haniumscouter@gmail.com"); // ?? ? ?? 
                            String to = conf.getValue("ext_plugin_email_to_address", "occidere@naver.com"); // ? ??(? , )
                            String cc = conf.getValue("ext_plugin_email_cc_address"); // cc ??

                            assert hostname != null;
                            assert port > 0;
                            assert username != null;
                            assert password != null;
                            assert from != null;
                            assert to != null;

                            // Get agent Name.  ??.
                            String name = AgentManager.getAgentName(pack.objHash) == null ? "N/A"
                                    : AgentManager.getAgentName(pack.objHash);

                            if (name.equals("N/A") && pack.message.endsWith("connected.")) {
                                int idx = pack.message.indexOf("connected");
                                if (pack.message.indexOf("reconnected") > -1)
                                    name = pack.message.substring(0, idx - 6);
                                else
                                    name = pack.message.substring(0, idx - 4);
                            }

                            // Make email subject
                            String subject = "[" + AlertLevel.getName(pack.level) + "] "
                                    + pack.objType.toUpperCase() + "(" + name + ") : " + pack.title;

                            String title = pack.title;
                            String msg = pack.message;

                            /* 
                             * Agent ? (inactivate) ? ? .
                             * ?  ,  ? ? Agent  ?  ?
                             * Agent ?  title? ?    .
                             */
                            if (title.equals("INACTIVE_OBJECT")) {
                                title = name + "  (Inactivated) ?!";
                                msg = pack.message.substring(0, pack.message.indexOf("OBJECT") - 1);
                            }

                            //? ? ? ?  ?
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy MM dd? HH mm ss");

                            // Make email message
                            String message = "[??   ?   ver.20170815]"
                                    + Util.NEW_LINE + "[ ] : " + title + Util.NEW_LINE + "[ ] : "
                                    + sdf.format(new Date(pack.time)) + Util.NEW_LINE + "[ ] : "
                                    + pack.objType.toUpperCase() + Util.NEW_LINE + "[? ] : " + name
                                    + Util.NEW_LINE + "[ ] : " + AlertLevel.getName(pack.level)
                                    + Util.NEW_LINE + "[ ] : " + msg + Util.NEW_LINE;

                            // Create an Email instance
                            Email email = new SimpleEmail();

                            email.setHostName(hostname);
                            email.setSmtpPort(port);
                            email.setAuthenticator(new DefaultAuthenticator(username, password));
                            email.setStartTLSEnabled(tlsEnabled);
                            email.setFrom(from);
                            email.setSubject(subject);
                            email.setMsg(message);

                            //? ,   
                            for (String addr : to.split(",")) {
                                email.addTo(addr);
                            }

                            //cc  ,   
                            if (cc != null) {
                                for (String addr : cc.split(","))
                                    email.addCc(addr);
                            }

                            // Send the email
                            email.send();

                            println("Email about " + name + " sent to [" + to + "] successfully.");
                            Logger.println("Email about " + name + " sent to [" + to + "] successfully.");
                        } catch (Exception e) {
                            println("[? ] : " + e.getMessage());
                            Logger.printStackTrace(e);

                            if (conf._trace) {
                                e.printStackTrace();
                            }
                        }
                    }
                }.start();
            }
        }
    }

    //Agent (activate)? ?? .
    @ServerPlugin(PluginConstants.PLUGIN_SERVER_OBJECT)
    public void object(ObjectPack pack) {
        if (pack.version != null && pack.version.length() > 0) {
            AlertPack ap = null;
            ObjectPack op = AgentManager.getAgent(pack.objHash);

            if (op == null && pack.wakeup == 0L) {
                // in case of new agent connected
                ap = new AlertPack();
                ap.level = AlertLevel.INFO;
                ap.objHash = pack.objHash;
                ap.title = "Object  ?!";
                ap.message = pack.objName + " ?.";
                ap.time = System.currentTimeMillis();

                if (AgentManager.getAgent(pack.objHash) != null) {
                    ap.objType = AgentManager.getAgent(pack.objHash).objType;
                } else {
                    ap.objType = "scouter";
                }

                alert(ap);

            } else if (op.alive == false) {
                // in case of agent reconnected
                ap = new AlertPack();
                ap.level = AlertLevel.INFO;
                ap.objHash = pack.objHash;
                ap.title = "Object ?.";
                ap.message = pack.objName + " ?.";
                ap.time = System.currentTimeMillis();
                ap.objType = AgentManager.getAgent(pack.objHash).objType;

                alert(ap);
            }
            // inactive state can be handled in alert() method.
            // Agent? (inactivate) ??  ? alert()  ? ? ? ?.
        }
    }

    //?   ?? .
    @ServerPlugin(PluginConstants.PLUGIN_SERVER_XLOG)
    public void xlog(XLogPack pack) {
        try {
            final int LIMIT = 2000; // ?  . ?  4 ?.

            //  ?   (ms)  ?? .
            int elapsedThreshold = conf.getInt("ext_plugin_elapsed_time_threshold", LIMIT);

            if (elapsedThreshold != 0 && pack.elapsed > elapsedThreshold) {
                String serviceName = TextRD.getString(DateUtil.yyyymmdd(pack.endTime), TextTypes.SERVICE,
                        pack.service); // ? URL? ?   

                AlertPack ap = new AlertPack();

                ap.level = AlertLevel.WARN;
                ap.objHash = pack.objHash;
                ap.title = " ??  ?!";
                ap.message = "[" + AgentManager.getAgentName(pack.objHash) + "] " + pack.service + "(" + serviceName
                        + ") " + "?   ?? " + pack.elapsed + "ms, (" + LIMIT
                        + "ms) .";
                ap.time = System.currentTimeMillis();
                ap.objType = AgentManager.getAgent(pack.objHash).objType;

                long limitTime = conf.getLong("ext_plugin_elapsed_limit_time", 60000); //1
                long safeTime = conf.getLong("ext_plugin_elapsed_safe_time", 120000); //2
                if (objectContainer.sendAlert(ap, serviceName, limitTime, safeTime))
                    alert(ap);

            }

        } catch (Exception e) {
            Logger.printStackTrace(e);
        }
    }

    //   ?   ?? .
    @ServerPlugin(PluginConstants.PLUGIN_SERVER_COUNTER)
    public void counter(PerfCounterPack pack) {
        String objName = pack.objName;
        int objHash = HashUtil.hash(objName);
        String objType = null;
        String objFamily = null;

        if (AgentManager.getAgent(objHash) != null) {
            objType = AgentManager.getAgent(objHash).objType;
        }

        if (objType != null) {
            objFamily = CounterManager.getInstance().getCounterEngine().getObjectType(objType).getFamily()
                    .getName();
        }

        try {
            // in case of objFamily is javaee
            if (CounterConstants.FAMILY_JAVAEE.equals(objFamily)) {
                // save javaee type's objHash
                if (!javaeeObjHashList.contains(objHash)) {
                    javaeeObjHashList.add(objHash);
                }

                if (pack.timetype == TimeTypeEnum.REALTIME) {

                    final int LIMIT = 100; //?  . GC Time?  100ms ?.

                    //gc time?   (ms)  ?? .
                    long gcTimeThreshold = conf.getLong("ext_plugin_gc_time_threshold", LIMIT);
                    long gcTime = pack.data.getLong(CounterConstants.JAVA_GC_TIME);

                    if (gcTimeThreshold != 0 && gcTime > gcTimeThreshold) {
                        AlertPack ap = new AlertPack();

                        ap.level = AlertLevel.WARN;
                        ap.objHash = objHash;
                        ap.title = " ?  ? ? !";
                        ap.message = objName + "? GC time? " + gcTime + "ms, (" + LIMIT
                                + "ms) .";
                        ap.time = System.currentTimeMillis();
                        ap.objType = objType;

                        long limitTime = conf.getLong("ext_plugin_gc_time_limit_time", 100);
                        long safeTime = conf.getLong("ext_plugin_gc_time_safe_time", 200);
                        if (objectContainer.sendAlert(ap, objName, limitTime, safeTime))
                            alert(ap); //?? ? objName ?
                    }
                }
            }
        } catch (Exception e) {
            Logger.printStackTrace(e);
        }
    }

    private void println(Object o) {
        if (conf.getBoolean("ext_plugin_email_debug", false)) {
            Logger.println(o);
        }
    }
}