完成告警功能
This commit is contained in:
parent
4450b0eb0b
commit
dccd5d6576
|
|
@ -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<AckSpan> {
|
||||
private List<ISpanChecker> spanCheckers = new ArrayList<ISpanChecker>();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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.";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue