From dccd5d65761702a56f08fea097d5cc56d11b5bbf Mon Sep 17 00:00:00 2001 From: ascrutae Date: Thu, 8 Dec 2016 13:57:26 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=91=8A=E8=AD=A6=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storage/alarm/SpanAlarmHandler.java | 36 ++++++++++ .../storage/alarm/checker/CheckResult.java | 32 +++++++++ .../alarm/checker/ExceptionChecker.java | 22 ++++++ .../alarm/checker/ExecuteTimeChecker.java | 29 ++++++++ .../ExecuteTimePossibleErrorChecker.java | 17 +++++ .../ExecuteTimePossibleWarningChecker.java | 17 +++++ .../storage/alarm/checker/FatalReason.java | 8 +++ .../storage/alarm/checker/ISpanChecker.java | 10 +++ .../alarm/sender/AlarmMessageSender.java | 13 ++++ .../sender/AlarmMessageSenderFactory.java | 13 ++++ .../storage/alarm/SpanAlarmHandlerTest.java | 72 +++++++++++++++++++ 11 files changed, 269 insertions(+) create mode 100644 skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/SpanAlarmHandler.java create mode 100644 skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/checker/CheckResult.java create mode 100644 skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/checker/ExceptionChecker.java create mode 100644 skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/checker/ExecuteTimeChecker.java create mode 100644 skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/checker/ExecuteTimePossibleErrorChecker.java create mode 100644 skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/checker/ExecuteTimePossibleWarningChecker.java create mode 100644 skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/checker/FatalReason.java create mode 100644 skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/checker/ISpanChecker.java create mode 100644 skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/sender/AlarmMessageSender.java create mode 100644 skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/sender/AlarmMessageSenderFactory.java create mode 100644 skywalking-storage-center/skywalking-storage/src/test/java/com/a/eye/skywalking/storage/alarm/SpanAlarmHandlerTest.java diff --git a/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/SpanAlarmHandler.java b/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/SpanAlarmHandler.java new file mode 100644 index 0000000000..5b4c688efa --- /dev/null +++ b/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/SpanAlarmHandler.java @@ -0,0 +1,36 @@ +package com.a.eye.skywalking.storage.alarm; + +import com.a.eye.skywalking.network.grpc.AckSpan; +import com.a.eye.skywalking.storage.alarm.checker.*; +import com.a.eye.skywalking.storage.alarm.sender.AlarmMessageSenderFactory; +import com.lmax.disruptor.EventHandler; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by xin on 2016/12/8. + */ +public class SpanAlarmHandler implements EventHandler { + private List spanCheckers = new ArrayList(); + + public SpanAlarmHandler() { + spanCheckers.add(new ExceptionChecker()); + spanCheckers.add(new ExecuteTimePossibleWarningChecker()); + spanCheckers.add(new ExecuteTimePossibleErrorChecker()); + } + + @Override + public void onEvent(AckSpan span, long sequence, boolean endOfBatch) throws Exception { + for (ISpanChecker spanChecker : spanCheckers) { + CheckResult result = spanChecker.check(span); + if (!result.isPassed()) { + AlarmMessageSenderFactory.getSender().send(generateAlarmMessageKey(span, result.getFatalReason()), result.getMessage()); + } + } + } + + private String generateAlarmMessageKey(AckSpan span, FatalReason reason) { + return span.getUsername() + "-" + span.getApplicationCode() + "-" + (System.currentTimeMillis() / (10000 * 6)) + "-" + reason; + } +} diff --git a/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/checker/CheckResult.java b/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/checker/CheckResult.java new file mode 100644 index 0000000000..cf1329f27c --- /dev/null +++ b/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/checker/CheckResult.java @@ -0,0 +1,32 @@ +package com.a.eye.skywalking.storage.alarm.checker; + +/** + * Created by xin on 2016/12/8. + */ +public class CheckResult { + private boolean passed; + private FatalReason fatalReason; + private String message; + + public CheckResult() { + this.passed = true; + } + + public CheckResult(FatalReason level, String alarmMessage) { + this.passed = false; + this.fatalReason = level; + this.message = alarmMessage; + } + + public boolean isPassed() { + return passed; + } + + public FatalReason getFatalReason() { + return fatalReason; + } + + public String getMessage() { + return message; + } +} diff --git a/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/checker/ExceptionChecker.java b/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/checker/ExceptionChecker.java new file mode 100644 index 0000000000..c7e0dbc922 --- /dev/null +++ b/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/checker/ExceptionChecker.java @@ -0,0 +1,22 @@ +package com.a.eye.skywalking.storage.alarm.checker; + +import com.a.eye.skywalking.network.grpc.AckSpan; +import com.a.eye.skywalking.storage.config.Config; + +public class ExceptionChecker implements ISpanChecker { + + @Override + public CheckResult check(AckSpan span) { + if (span.getStatusCode() != 1) + return new CheckResult(); + String exceptionStack = span.getExceptionStack(); + if (exceptionStack == null) { + exceptionStack = ""; + } else if (exceptionStack.length() > Config.Alarm.ALARM_EXCEPTION_STACK_LENGTH) { + exceptionStack = exceptionStack.substring(0, Config.Alarm.ALARM_EXCEPTION_STACK_LENGTH); + } + + return new CheckResult(FatalReason.EXCEPTION_ERROR, exceptionStack); + } + +} diff --git a/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/checker/ExecuteTimeChecker.java b/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/checker/ExecuteTimeChecker.java new file mode 100644 index 0000000000..b6b43ceb60 --- /dev/null +++ b/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/checker/ExecuteTimeChecker.java @@ -0,0 +1,29 @@ +package com.a.eye.skywalking.storage.alarm.checker; + +import com.a.eye.skywalking.network.grpc.AckSpan; + +/** + * Created by xin on 2016/12/8. + */ +public abstract class ExecuteTimeChecker implements ISpanChecker { + + @Override + public CheckResult check(AckSpan span) { + long cost = span.getCost(); + if (isOverThreshold(cost)) { + return new CheckResult(getFatalLevel(), generateAlarmMessage(span)); + } + + return new CheckResult(); + } + + protected abstract boolean isOverThreshold(long cost); + + protected abstract FatalReason getFatalLevel(); + + protected String generateAlarmMessage(AckSpan span) { + return span.getViewpointId() + " cost " + span.getCost() + " ms."; + } + + +} diff --git a/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/checker/ExecuteTimePossibleErrorChecker.java b/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/checker/ExecuteTimePossibleErrorChecker.java new file mode 100644 index 0000000000..ba7c6510ef --- /dev/null +++ b/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/checker/ExecuteTimePossibleErrorChecker.java @@ -0,0 +1,17 @@ +package com.a.eye.skywalking.storage.alarm.checker; + +/** + * Created by xin on 2016/12/8. + */ +public class ExecuteTimePossibleErrorChecker extends ExecuteTimeChecker { + + @Override + protected boolean isOverThreshold(long cost) { + return cost >= 3000; + } + + @Override + protected FatalReason getFatalLevel() { + return FatalReason.EXECUTE_TIME_ERROR; + } +} diff --git a/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/checker/ExecuteTimePossibleWarningChecker.java b/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/checker/ExecuteTimePossibleWarningChecker.java new file mode 100644 index 0000000000..336c065351 --- /dev/null +++ b/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/checker/ExecuteTimePossibleWarningChecker.java @@ -0,0 +1,17 @@ +package com.a.eye.skywalking.storage.alarm.checker; + +/** + * Created by xin on 2016/12/8. + */ +public class ExecuteTimePossibleWarningChecker extends ExecuteTimeChecker { + @Override + protected boolean isOverThreshold(long cost) { + return cost > 500 && cost < 3000; + } + + @Override + protected FatalReason getFatalLevel() { + return FatalReason.EXECUTE_TIME_WARNING; + } + +} diff --git a/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/checker/FatalReason.java b/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/checker/FatalReason.java new file mode 100644 index 0000000000..75cc1b4f44 --- /dev/null +++ b/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/checker/FatalReason.java @@ -0,0 +1,8 @@ +package com.a.eye.skywalking.storage.alarm.checker; + +/** + * Created by xin on 2016/12/8. + */ +public enum FatalReason { + EXCEPTION_ERROR, EXECUTE_TIME_ERROR, EXECUTE_TIME_WARNING; +} diff --git a/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/checker/ISpanChecker.java b/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/checker/ISpanChecker.java new file mode 100644 index 0000000000..ef364efa0d --- /dev/null +++ b/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/checker/ISpanChecker.java @@ -0,0 +1,10 @@ +package com.a.eye.skywalking.storage.alarm.checker; + +import com.a.eye.skywalking.network.grpc.AckSpan; + +/** + * Created by xin on 2016/12/8. + */ +public interface ISpanChecker { + CheckResult check(AckSpan span); +} diff --git a/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/sender/AlarmMessageSender.java b/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/sender/AlarmMessageSender.java new file mode 100644 index 0000000000..67740817c4 --- /dev/null +++ b/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/sender/AlarmMessageSender.java @@ -0,0 +1,13 @@ +package com.a.eye.skywalking.storage.alarm.sender; + +/** + * Created by xin on 2016/12/8. + */ +public class AlarmMessageSender { + + + + public void send(String alarmKey, String message) { + + } +} diff --git a/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/sender/AlarmMessageSenderFactory.java b/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/sender/AlarmMessageSenderFactory.java new file mode 100644 index 0000000000..ce447c3975 --- /dev/null +++ b/skywalking-storage-center/skywalking-storage/src/main/java/com/a/eye/skywalking/storage/alarm/sender/AlarmMessageSenderFactory.java @@ -0,0 +1,13 @@ +package com.a.eye.skywalking.storage.alarm.sender; + +/** + * Created by xin on 2016/12/8. + */ +public class AlarmMessageSenderFactory { + + private static AlarmMessageSender sender = new AlarmMessageSender(); + + public static AlarmMessageSender getSender() { + return sender; + } +} diff --git a/skywalking-storage-center/skywalking-storage/src/test/java/com/a/eye/skywalking/storage/alarm/SpanAlarmHandlerTest.java b/skywalking-storage-center/skywalking-storage/src/test/java/com/a/eye/skywalking/storage/alarm/SpanAlarmHandlerTest.java new file mode 100644 index 0000000000..25a658734e --- /dev/null +++ b/skywalking-storage-center/skywalking-storage/src/test/java/com/a/eye/skywalking/storage/alarm/SpanAlarmHandlerTest.java @@ -0,0 +1,72 @@ +package com.a.eye.skywalking.storage.alarm; + +import com.a.eye.skywalking.network.grpc.AckSpan; +import com.a.eye.skywalking.network.grpc.TraceId; +import com.a.eye.skywalking.storage.alarm.sender.AlarmMessageSender; +import com.a.eye.skywalking.storage.alarm.sender.AlarmMessageSenderFactory; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.*; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(AlarmMessageSenderFactory.class) +public class SpanAlarmHandlerTest { + + @Mock + private AlarmMessageSender messageHandler; + @InjectMocks + private SpanAlarmHandler handler; + private AckSpan normalAckSpan; + private AckSpan costMuchSpan; + private AckSpan costTooMuchSpan; + private AckSpan exceptionSpan; + + @Before + public void setUp() { + PowerMockito.mockStatic(AlarmMessageSenderFactory.class); + when(AlarmMessageSenderFactory.getSender()).thenReturn(messageHandler); + long startTime = System.currentTimeMillis(); + AckSpan.Builder builder = AckSpan.newBuilder().setApplicationCode("test").setUsername("test").setCost(20) + .setStatusCode(0).setLevelId(0).setParentLevel("0.0").setTraceId(TraceId.newBuilder() + .addSegments(2016).addSegments(startTime).addSegments(2).addSegments(100).addSegments(30) + .addSegments(1).build()); + + normalAckSpan = builder.build(); + costMuchSpan = builder.setCost(600).build(); + costTooMuchSpan = builder.setCost(4000).build(); + exceptionSpan = builder.setCost(20).setStatusCode(1).setExceptionStack("occur exception").build(); + } + + @Test + public void testNormalSpan() throws Exception { + handler.onEvent(normalAckSpan, 1, false); + verify(messageHandler, never()).send(any(), anyString()); + } + + @Test + public void testCostMuchSpan() throws Exception { + handler.onEvent(costMuchSpan, 1, false); + verify(messageHandler, times(1)).send(any(), anyString()); + } + + @Test + public void testExceptionSpan() throws Exception { + handler.onEvent(exceptionSpan, 1, false); + verify(messageHandler, times(1)).send(any(), anyString()); + } + + @Test + public void testCostTooMuchSpan() throws Exception { + handler.onEvent(costTooMuchSpan,1, false); + verify(messageHandler, times(1)).send(any(), anyString()); + } +} + -- GitLab