Skip to content

Commit

Permalink
[#8993] Add apdex alarm
Browse files Browse the repository at this point in the history
  • Loading branch information
youngjin.kim2 authored and smilu97 committed Jul 1, 2022
1 parent 8bd106e commit a8c8e20
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@


import com.navercorp.pinpoint.batch.alarm.checker.AlarmChecker;
import com.navercorp.pinpoint.batch.alarm.checker.ApdexScoreChecker;
import com.navercorp.pinpoint.batch.alarm.checker.DataSourceConnectionUsageRateChecker;
import com.navercorp.pinpoint.batch.alarm.checker.DeadlockChecker;
import com.navercorp.pinpoint.batch.alarm.checker.ErrorCountChecker;
Expand Down Expand Up @@ -89,6 +90,13 @@ public AlarmChecker<?> createChecker(DataCollector dataCollector, Rule rule) {
}
});

put(CheckerCategory.APDEX_SCORE, new AlarmCheckerFactory() {
@Override
public AlarmChecker<?> createChecker(DataCollector dataCollector, Rule rule) {
return new ApdexScoreChecker((ResponseTimeDataCollector) dataCollector, rule);
}
});

put(CheckerCategory.SLOW_COUNT_TO_CALLEE, new AlarmCheckerFactory() {
@Override
public AlarmChecker<?> createChecker(DataCollector dataCollector, Rule rule) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright 2022 NAVER Corp.
*
* 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.
*/
package com.navercorp.pinpoint.batch.alarm.checker;

import com.navercorp.pinpoint.batch.alarm.collector.ResponseTimeDataCollector;
import com.navercorp.pinpoint.web.alarm.vo.Rule;
import com.navercorp.pinpoint.web.applicationmap.histogram.ApdexScore;

/**
* @author youngjin.kim2
*/
public class ApdexScoreChecker extends LongValueAlarmChecker {

public ApdexScoreChecker(ResponseTimeDataCollector dataCollector, Rule rule) {
super(rule, "%", dataCollector);
}

@Override
protected Long getDetectedValue() {
final ResponseTimeDataCollector dataCollector = (ResponseTimeDataCollector) this.dataCollector;

final long satisfiedCount = dataCollector.getFastCount();
final long toleratingCount = dataCollector.getNormalCount();
final long totalSamples = dataCollector.getTotalCount();
final double score = (new ApdexScore(satisfiedCount, toleratingCount, totalSamples)).getApdexScore();

return (long) (score * 100.0);
}

@Override
protected boolean decideResult(Long value) {
return value <= rule.getThreshold();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ public class ResponseTimeDataCollector extends DataCollector {
private final long slotInterval;
private final AtomicBoolean init =new AtomicBoolean(false); // need to consider a race condition when checkers start simultaneously.

private long fastCount = 0;
private long normalCount = 0;
private long slowCount = 0;
private long errorCount = 0;
private long totalCount = 0;
Expand Down Expand Up @@ -89,13 +91,23 @@ private long calculatePercent(long value) {

private void sum(Collection<TimeHistogram> timeHistograms) {
for (TimeHistogram timeHistogram : timeHistograms) {
fastCount += timeHistogram.getFastCount();
normalCount += timeHistogram.getNormalCount();
slowCount += timeHistogram.getSlowCount();
slowCount += timeHistogram.getVerySlowCount();
errorCount += timeHistogram.getTotalErrorCount();
totalCount += timeHistogram.getTotalCount();
}
}

public long getFastCount() {
return fastCount;
}

public long getNormalCount() {
return normalCount;
}

public long getSlowCount() {
return slowCount;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* Copyright 2022 NAVER Corp.
*
* 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.
*/
package com.navercorp.pinpoint.batch.alarm.checker;

import com.navercorp.pinpoint.batch.alarm.collector.ResponseTimeDataCollector;
import com.navercorp.pinpoint.common.trace.ServiceType;
import com.navercorp.pinpoint.web.alarm.CheckerCategory;
import com.navercorp.pinpoint.web.alarm.DataCollectorCategory;
import com.navercorp.pinpoint.web.alarm.vo.Rule;
import com.navercorp.pinpoint.web.applicationmap.histogram.TimeHistogram;
import com.navercorp.pinpoint.web.dao.MapResponseDao;
import com.navercorp.pinpoint.web.vo.Application;
import com.navercorp.pinpoint.web.vo.ResponseTime;
import org.junit.BeforeClass;
import org.junit.Test;

import java.util.LinkedList;
import java.util.List;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

/**
* @author youngjin.kim2
*/
public class ApdexScoreCheckerTest {

private static final String SERVICE_NAME = "local_service";
private static final String SERVICE_TYPE = "tomcat";

private static MapResponseDao mockMapResponseDAO;

@BeforeClass
public static void before() {
mockMapResponseDAO = (application, range) -> {
List<ResponseTime> list = new LinkedList<>();
long timeStamp = 1409814914298L;
ResponseTime responseTime = new ResponseTime(SERVICE_NAME, ServiceType.STAND_ALONE, timeStamp);
list.add(responseTime);

for (int i=0 ; i < 5; i++) {
for (int j=0 ; j < 5; j++) {
TimeHistogram histogram = new TimeHistogram(ServiceType.STAND_ALONE, timeStamp);
histogram.addCallCountByElapsedTime(1000, false);
histogram.addCallCountByElapsedTime(1000, false);
histogram.addCallCountByElapsedTime(1000, false);
histogram.addCallCountByElapsedTime(1000, false);
histogram.addCallCountByElapsedTime(6000, false);
responseTime.addResponseTime("agent_" + i + "_" + j, histogram);
}
timeStamp += 1;
}

return list;
};
}

/*
* alert conditions not satisfied
*/
@Test
public void checkTest1() {
Application application = new Application(SERVICE_NAME, ServiceType.STAND_ALONE);
ResponseTimeDataCollector collector = new ResponseTimeDataCollector(DataCollectorCategory.RESPONSE_TIME, application, mockMapResponseDAO, System.currentTimeMillis(), 300000);
Rule rule = new Rule(SERVICE_NAME, SERVICE_TYPE, CheckerCategory.SLOW_COUNT.getName(), 90, "testGroup", false, false, false, "");
ApdexScoreChecker checker = new ApdexScoreChecker(collector, rule);

checker.check();
assertTrue(checker.isDetected());
}

/*
* alert conditions not satisfied
*/
@Test
public void checkTest2() {
Application application = new Application(SERVICE_NAME, ServiceType.STAND_ALONE);
ResponseTimeDataCollector collector = new ResponseTimeDataCollector(DataCollectorCategory.RESPONSE_TIME, application, mockMapResponseDAO, System.currentTimeMillis(), 300000);
Rule rule = new Rule(SERVICE_NAME, SERVICE_TYPE, CheckerCategory.SLOW_COUNT.getName(), 75, "testGroup", false, false, false, "");
ApdexScoreChecker checker = new ApdexScoreChecker(collector, rule);

checker.check();
assertFalse(checker.isDetected());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ public enum CheckerCategory {
ERROR_RATE("ERROR RATE", DataCollectorCategory.RESPONSE_TIME),

TOTAL_COUNT("TOTAL COUNT", DataCollectorCategory.RESPONSE_TIME),

APDEX_SCORE("APDEX SCORE", DataCollectorCategory.RESPONSE_TIME),

SLOW_COUNT_TO_CALLEE("SLOW COUNT TO CALLEE", DataCollectorCategory.CALLER_STAT),

Expand Down

0 comments on commit a8c8e20

Please # to comment.