fix(接口自动化): 修复调试执行结果丢包问题,日志排查DEBUG

This commit is contained in:
fit2-zhao 2021-07-23 16:46:43 +08:00 committed by fit2-zhao
parent 12d6b7115b
commit d72fd4f0e3
7 changed files with 74 additions and 38 deletions

View File

@ -70,7 +70,6 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
public void teardownTest(BackendListenerContext context) throws Exception { public void teardownTest(BackendListenerContext context) throws Exception {
TestResult testResult = new TestResult(); TestResult testResult = new TestResult();
testResult.setTestId(testId); testResult.setTestId(testId);
testResult.setConsole(resultService.getJmeterLogger(testId, true));
testResult.setTotal(0); testResult.setTotal(0);
// 一个脚本里可能包含多个场景(ThreadGroup)所以要区分开key: 场景Id // 一个脚本里可能包含多个场景(ThreadGroup)所以要区分开key: 场景Id
final Map<String, ScenarioResult> scenarios = new LinkedHashMap<>(); final Map<String, ScenarioResult> scenarios = new LinkedHashMap<>();
@ -87,6 +86,7 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
super.teardownTest(context); super.teardownTest(context);
testResult.getScenarios().addAll(scenarios.values()); testResult.getScenarios().addAll(scenarios.values());
testResult.getScenarios().sort(Comparator.comparing(ScenarioResult::getId)); testResult.getScenarios().sort(Comparator.comparing(ScenarioResult::getId));
testResult.setConsole(resultService.getJmeterLogger(testId, true));
testResultService.saveResult(testResult, this.runMode, this.debugReportId, this.testId); testResultService.saveResult(testResult, this.runMode, this.debugReportId, this.testId);
} }

View File

@ -17,15 +17,17 @@ public class JmeterLoggerAppender extends UnsynchronizedAppenderBase<ILoggingEve
if (logger == null) { if (logger == null) {
logger = new LinkedHashMap<>(); logger = new LinkedHashMap<>();
} }
StringBuffer message = new StringBuffer(); if (!event.getLevel().levelStr.equals(LogUtil.DEBUG)) {
message.append(DateUtils.getTimeStr(event.getTimeStamp())).append(" ") StringBuffer message = new StringBuffer();
.append(event.getLevel()).append(" ") message.append(DateUtils.getTimeStr(event.getTimeStamp())).append(" ")
.append(event.getThreadName()).append(" ") .append(event.getLevel()).append(" ")
.append(event.getFormattedMessage()).append("\n"); .append(event.getThreadName()).append(" ")
if (logger.containsKey(event.getTimeStamp())) { .append(event.getFormattedMessage()).append("\n");
logger.get(event.getTimeStamp()).append(message); if (logger.containsKey(event.getTimeStamp())) {
} else { logger.get(event.getTimeStamp()).append(message);
logger.put(event.getTimeStamp(), message); } else {
logger.put(event.getTimeStamp(), message);
}
} }
} catch (Exception e) { } catch (Exception e) {
LogUtil.error(e); LogUtil.error(e);

View File

@ -13,15 +13,14 @@ import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import sun.security.util.Cache; import sun.security.util.Cache;
import java.util.Comparator; import java.util.*;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Service @Service
public class MsResultService { public class MsResultService {
// 零时存放实时结果 // 零时存放实时结果
private Cache cache = Cache.newHardMemoryCache(0, 3600 * 2); private Cache cache = Cache.newHardMemoryCache(0, 3600 * 2);
private Map<String, List<SampleResult>> processCache = new HashMap<>();
private final static String THREAD_SPLIT = " "; private final static String THREAD_SPLIT = " ";
@ -34,29 +33,59 @@ public class MsResultService {
return null; return null;
} }
public List<SampleResult> procResult(String key) {
if (this.processCache.get(key) != null) {
return this.processCache.get(key);
}
return new LinkedList<>();
}
public void setCache(String key, SampleResult result) { public void setCache(String key, SampleResult result) {
if (key.startsWith("[") && key.endsWith("]")) { if (key.startsWith("[") && key.endsWith("]")) {
key = JSON.parseArray(key).get(0).toString(); key = JSON.parseArray(key).get(0).toString();
} }
TestResult testResult = this.getResult(key); List<SampleResult> testResult = this.procResult(key);
testResult.add(result);
this.processCache.put(key, testResult);
}
public TestResult sysnSampleResult(String key) {
if (key.startsWith("[") && key.endsWith("]")) {
key = JSON.parseArray(key).get(0).toString();
}
String logs = getJmeterLogger(key, false);
List<SampleResult> results = this.processCache.get(key);
boolean isRemove = false;
TestResult testResult = (TestResult) cache.get(key);
if (testResult == null) { if (testResult == null) {
testResult = new TestResult(); testResult = new TestResult();
} }
if (result.getResponseCode().equals(MsResultCollector.TEST_END)) { if (CollectionUtils.isNotEmpty(results)) {
testResult.setEnd(true); final Map<String, ScenarioResult> scenarios = new LinkedHashMap<>();
for (SampleResult result : results) {
if (result.getResponseCode().equals(MsResultCollector.TEST_END)) {
testResult.setEnd(true);
this.cache.put(key, testResult);
isRemove = true;
break;
}
testResult.setTestId(key);
if (StringUtils.isNotEmpty(logs)) {
testResult.setConsole(logs);
}
testResult.setTotal(0);
this.formatTestResult(testResult, scenarios, result);
}
testResult.getScenarios().clear();
testResult.getScenarios().addAll(scenarios.values());
testResult.getScenarios().sort(Comparator.comparing(ScenarioResult::getId));
this.cache.put(key, testResult); this.cache.put(key, testResult);
return;
if (isRemove) {
this.processCache.remove(key);
}
} }
testResult.setTestId(key); return (TestResult) cache.get(key);
testResult.setConsole(getJmeterLogger(key, false));
testResult.setTotal(0);
final Map<String, ScenarioResult> scenarios = new LinkedHashMap<>();
this.formatTestResult(testResult, scenarios, result);
testResult.getScenarios().addAll(scenarios.values());
testResult.getScenarios().sort(Comparator.comparing(ScenarioResult::getId));
this.cache.put(key, testResult);
} }
public void delete(String testId) { public void delete(String testId) {
@ -88,7 +117,6 @@ public class MsResultService {
scenarioResult.addError(result.getErrorCount()); scenarioResult.addError(result.getErrorCount());
testResult.addError(result.getErrorCount()); testResult.addError(result.getErrorCount());
} }
RequestResult requestResult = this.getRequestResult(result); RequestResult requestResult = this.getRequestResult(result);
scenarioResult.getRequestResults().add(requestResult); scenarioResult.getRequestResults().add(requestResult);
scenarioResult.addResponseTime(result.getTime()); scenarioResult.addResponseTime(result.getTime());
@ -114,6 +142,12 @@ public class MsResultService {
.filter(map -> map.getKey() > finalStartTime && map.getKey() < endTime) .filter(map -> map.getKey() > finalStartTime && map.getKey() < endTime)
.map(map -> map.getValue()).collect(Collectors.joining()); .map(map -> map.getValue()).collect(Collectors.joining());
if (removed) { if (removed) {
if (processCache.get(testId) != null) {
try {
Thread.sleep(2000);
} catch (Exception e) {
}
}
FixedTask.tasks.remove(testId); FixedTask.tasks.remove(testId);
} }
if (FixedTask.tasks.isEmpty()) { if (FixedTask.tasks.isEmpty()) {

View File

@ -88,7 +88,7 @@ public class ScenarioReportWebSocket {
@Override @Override
public void run() { public void run() {
try { try {
TestResult report = resultService.getResult(reportId); TestResult report = resultService.sysnSampleResult(reportId);
if (!session.isOpen()) { if (!session.isOpen()) {
return; return;
} }

View File

@ -31,7 +31,7 @@ public class TaskCenterWebSocket {
public void onOpen(@PathParam("projectId") String projectId, Session session) { public void onOpen(@PathParam("projectId") String projectId, Session session) {
Timer timer = new Timer(true); Timer timer = new Timer(true);
TaskCenterWebSocket.TaskCenter task = new TaskCenterWebSocket.TaskCenter(session, projectId); TaskCenterWebSocket.TaskCenter task = new TaskCenterWebSocket.TaskCenter(session, projectId);
timer.schedule(task, 0, 6 * 1000); timer.schedule(task, 0, 10 * 1000);
refreshTasks.putIfAbsent(session, timer); refreshTasks.putIfAbsent(session, timer);
} }

View File

@ -1131,12 +1131,12 @@ export default {
} }
this.loading = false; this.loading = false;
this.sort(); this.sort();
// resourceId
if (this.scenarioDefinition) {
this.resetResourceId(this.scenarioDefinition);
}
}) })
} }
// resourceId
if (this.scenarioDefinition) {
this.resetResourceId(this.scenarioDefinition);
}
}, },
setParameter() { setParameter() {
this.currentScenario.stepTotal = this.scenarioDefinition.length; this.currentScenario.stepTotal = this.scenarioDefinition.length;

View File

@ -13,7 +13,7 @@
<template v-slot:headerLeft> <template v-slot:headerLeft>
<el-input draggable size="mini" v-model="controller.variable" style="width: 15%" :placeholder="$t('api_test.request.condition_variable')"/> <el-input draggable size="mini" v-model="controller.variable" style="width: 12%" :placeholder="$t('api_test.request.condition_variable')"/>
<el-select v-model="controller.operator" :placeholder="$t('commons.please_select')" size="mini" <el-select v-model="controller.operator" :placeholder="$t('commons.please_select')" size="mini"
@change="change" class="ms-select"> @change="change" class="ms-select">
@ -27,7 +27,7 @@
</template> </template>
<template v-slot:debugStepCode> <template v-slot:debugStepCode>
<span class="ms-step-debug-code" :class="node.data.code ==='error'?'ms-req-error':'ms-req-success'" v-if="!loading && node.data.debug"> <span class="ms-step-debug-code" :class="node.data.code ==='error'?'ms-req-error':'ms-req-success'" v-if="!loading && node.data.debug && node.data.code">
{{ getCode() }} {{ getCode() }}
</span> </span>
</template> </template>
@ -141,7 +141,7 @@
<style scoped> <style scoped>
.ms-btn { .ms-btn {
width: 20%; width: 15%;
margin-left: 5px; margin-left: 5px;
} }
@ -165,6 +165,6 @@
text-overflow: ellipsis; text-overflow: ellipsis;
vertical-align: middle; vertical-align: middle;
white-space: nowrap; white-space: nowrap;
width: 100px; width: 80px;
} }
</style> </style>