Loading

JMeter使用jsr223 全局后置监听器,来获取错误的请求并打印到本地,使用取样器标识单独命名,并增加日志内容,加入断言结果

再更一版,在原来的基础上新增一个断言的记录,更直观了,性能开销也更大了。
JMeter使用jsr223 全局后置监听器,来获取错误的请求并打印到本地,使用取样器标识单独命名,并增加日志内容,加入断言结果

// 导入所需要的Java类
import org.apache.jmeter.services.FileServer
import java.io.File
import java.io.FileWriter
import java.text.SimpleDateFormat

// 1. 判断上一个取样器(Sampler)是否执行成功
if (!prev.isSuccessful()) {

    // 2. 获取当前请求的名称 (Sample Label)
    def sampleLabel = prev.getSampleLabel()

    // 3. 将请求名称处理成安全的文件名
    def safeFileNameLabel = sampleLabel.replaceAll(/[\\\/:*?"<>|\s]+/, '_')
    
    // 4. 根据处理后的请求名称,动态生成此请求专属的日志文件名
    def logFileName = "${safeFileNameLabel}_error.log"

    // 5. 获取当前JMX脚本的所在目录
    def fs = FileServer.getFileServer()
    if (fs.getScriptName() == null) {
        log.error("【错误日志记录器】: JMX脚本必须先保存才能记录错误日志!")
        return;
    }
    def logDir = fs.getBaseDir()
    
    // 6. 创建指向特定日志文件的File对象
    def logFile = new File(logDir, logFileName)

    // 7. 准备要写入日志的错误信息内容
    def timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date())
    def errorDetails = new StringBuilder()
    
    errorDetails.append("==================== REQUEST FAILED ====================\n")
    errorDetails.append("Timestamp       : " + timestamp + "\n")
    errorDetails.append("Thread Name     : " + ctx.getThread().getThreadName() + "\n")
    errorDetails.append("Sample Label    : " + prev.getSampleLabel() + "\n")
    errorDetails.append("Response Code   : " + prev.getResponseCode() + "\n")
    errorDetails.append("Response Message: " + prev.getResponseMessage() + "\n")
    errorDetails.append("Request URL     : " + prev.getUrlAsString() + "\n\n")
    errorDetails.append("---------- Request Headers ----------\n")
    errorDetails.append(prev.getRequestHeaders() + "\n")
    errorDetails.append("---------- Request Body ----------\n")
    errorDetails.append(prev.getSamplerData() + "\n\n")
    errorDetails.append("---------- Response Body ----------\n")
    errorDetails.append(prev.getResponseDataAsString() + "\n")
    
    // 【新增】获取并记录失败的断言结果
    def assertionResults = prev.getAssertionResults()
    if (assertionResults != null && assertionResults.length > 0) {
        def failureMessages = new StringBuilder()
        for (assertion in assertionResults) {
            // 只记录失败或出错的断言
            if (assertion.isFailure() || assertion.isError()) {
                failureMessages.append("Assertion Name  : " + assertion.getName() + "\n")
                failureMessages.append("Failure Message : " + assertion.getFailureMessage() + "\n\n")
            }
        }
        // 如果确实有断言失败了,才把断言失败信息加入到主日志中
        if (failureMessages.length() > 0) {
            errorDetails.append("\n---------- Assertion Failures ----------\n")
            errorDetails.append(failureMessages.toString())
        }
    }
    
    errorDetails.append("========================================================\n\n")

    // 8. 将错误信息写入对应的日志文件 (线程安全)
    synchronized (this) {
        logFile.append(errorDetails.toString(), "UTF-8")
    }
}
posted @ 2025-07-21 14:46  夷某蓁  阅读(44)  评论(1)    收藏  举报