提交 dccd5d65 编写于 作者: A ascrutae

完成告警功能

上级 4450b0eb
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;
}
}
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;
}
}
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);
}
}
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.";
}
}
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;
}
}
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;
}
}
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;
}
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);
}
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) {
}
}
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;
}
}
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());
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册