Commit 1781d700 authored by 吴晟's avatar 吴晟
Browse files

* 增加 #43 描述的时间超时告警能力

* 针对 #26 增加“运行时间缓慢告警”的服务端处理能力,需要alarm程序配合实现
parent 2a49c593
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -83,6 +83,12 @@ public class Config {
        public static int REDIS_MAX_TOTAL = 20;

        public static boolean ALARM_OFF_FLAG = false;
        
        public static class Checker {
        	public static boolean TURN_ON_EXCEPTION_CHECKER = true;
        	
        	public static boolean TURN_ON_EXECUTE_TIME_CHECKER = true;
        }
    }

    public static class MailSenderInfo {
+5 −0
Original line number Diff line number Diff line
@@ -60,6 +60,11 @@ alarm.redis_max_total=50
#是否关闭告警发送
alarm.alarm_off_flag=false

#告警检查器:异常告警检查
alarm.checker.turn_on_exception_checker=true
#告警检查器:执行时间超时告警检查
alarm.checker.turn_on_execute_time_checker=true

#邮件发送配置id
mailsenderinfo.configid=1000
#邮件模板配置id
+6 −0
Original line number Diff line number Diff line
@@ -103,6 +103,12 @@ public class Config {
        public static boolean ALARM_OFF_FLAG = false;
        
        public static long ALARM_REDIS_INSPECTOR_INTERVAL = 5 * 1000L;
        
        public static class Checker {
        	public static boolean TURN_ON_EXCEPTION_CHECKER = true;
        	
        	public static boolean TURN_ON_EXECUTE_TIME_CHECKER = true;
        }
    }
    
    public static class HealthCollector {
+27 −25
Original line number Diff line number Diff line
@@ -21,15 +21,12 @@ public class AlarmRedisConnector {
	private static JedisPool jedisPool;

	static {
		new RedisInspector().start();
		new RedisInspector().connect().start();
	}

	public static Jedis getJedis() {
		if (Config.Alarm.ALARM_OFF_FLAG) {
			return null;
		} else if (jedisPool == null || jedisPool.isClosed()) {
			reportJedisFailure();
			return null;
		} else {
			return jedisPool.getResource();
		}
@@ -62,21 +59,14 @@ public class AlarmRedisConnector {
			}
		}

		@Override
		public void run() {
			if (Config.Alarm.ALARM_OFF_FLAG)
				return;

			while (true) {
				try {
					if (needConnectInit) {
		private RedisInspector connect() {
			if (jedisPool != null && !jedisPool.isClosed()) {
				jedisPool.close();
			}

			GenericObjectPoolConfig genericObjectPoolConfig = buildGenericObjectPoolConfig();
						jedisPool = new JedisPool(genericObjectPoolConfig,
								config[0], Integer.valueOf(config[1]));
			jedisPool = new JedisPool(genericObjectPoolConfig, config[0],
					Integer.valueOf(config[1]));
			// Test connect redis.
			Jedis jedis = null;
			try {
@@ -91,6 +81,18 @@ public class AlarmRedisConnector {
					jedis.close();
				}
			}
			return this;
		}

		@Override
		public void run() {
			if (Config.Alarm.ALARM_OFF_FLAG)
				return;

			while (true) {
				try {
					if (needConnectInit) {
						connect();
					}

					if (needConnectInit) {
+30 −51
Original line number Diff line number Diff line
package com.ai.cloud.skywalking.reciever.storage.chain;

import static com.ai.cloud.skywalking.reciever.conf.Config.Alarm.ALARM_EXCEPTION_STACK_LENGTH;
import static com.ai.cloud.skywalking.reciever.conf.Config.Alarm.ALARM_EXPIRE_SECONDS;

import java.util.ArrayList;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import redis.clients.jedis.Jedis;

import com.ai.cloud.skywalking.protocol.Span;
import com.ai.cloud.skywalking.reciever.conf.Config;
import com.ai.cloud.skywalking.reciever.storage.AlarmRedisConnector;
import com.ai.cloud.skywalking.reciever.storage.Chain;
import com.ai.cloud.skywalking.reciever.storage.IStorageChain;
import com.ai.cloud.skywalking.reciever.storage.chain.alarm.ExceptionChecker;
import com.ai.cloud.skywalking.reciever.storage.chain.alarm.ExecuteTimeChecker;
import com.ai.cloud.skywalking.reciever.storage.chain.alarm.ISpanChecker;

import static com.ai.cloud.skywalking.reciever.conf.Config.Alarm.Checker.*;

public class AlarmChain implements IStorageChain {
	private static Logger logger = LogManager.getLogger(AlarmChain.class);

    @Override
    public void doChain(List<Span> spans, Chain chain) {
        for (Span span : spans) {
            if (span.getStatusCode() != 1)
                continue;
            String exceptionStack = span.getExceptionStack();
            if (exceptionStack == null) {
                exceptionStack = "";
            } else if (exceptionStack.length() > ALARM_EXCEPTION_STACK_LENGTH) {
                exceptionStack = exceptionStack.substring(0, ALARM_EXCEPTION_STACK_LENGTH);
            }
            saveAlarmMessage(generateAlarmKey(span), span.getTraceId(), exceptionStack);
        }
        chain.doChain(spans);
    }
	private List<ISpanChecker> checkList = new ArrayList<ISpanChecker>();

    private String generateAlarmKey(Span span) {
        return span.getUserId() + "-" + span.getApplicationId() + "-"
                + (System.currentTimeMillis() / (10000 * 6));
	public AlarmChain() {
		if (TURN_ON_EXCEPTION_CHECKER)
			checkList.add(new ExceptionChecker());
		if (TURN_ON_EXECUTE_TIME_CHECKER)
			checkList.add(new ExecuteTimeChecker());
	}

    private void saveAlarmMessage(String key, String traceId, String exceptionMsgOutline) {
	@Override
	public void doChain(List<Span> spans, Chain chain) {
		if (Config.Alarm.ALARM_OFF_FLAG) {
			return;
		}

        Jedis jedis = null;
        try {
            jedis = AlarmRedisConnector.getJedis();
            if(jedis == null){
            	logger.error("Failed to set data. can't get jedis.");
            	return;
            }
            jedis.hsetnx(key, traceId, exceptionMsgOutline);
            jedis.expire(key, ALARM_EXPIRE_SECONDS);
        } catch (Exception e) {
        	AlarmRedisConnector.reportJedisFailure();
            logger.error("Failed to set data.", e);
        } finally {
            if (jedis != null) {
                jedis.close();
		for (Span span : spans) {
			for (ISpanChecker checker : checkList) {
				checker.check(span);
			}
		}
		chain.doChain(spans);
	}

}
Loading