Loading

JMeter 响应时间监控与日志记录方案

JMeter 响应时间监控与日志记录方案

需求描述

当JMeter测试中遇到响应时间超过200ms的请求时,需要记录以下信息到本地日志文件:

  • CnsmrSrlNo(消费者流水号)
  • GlblSrlNo(全局流水号)
  • 响应时间(毫秒)

日志要求:

  1. 文件不存在时自动创建
  2. 以追加方式写入新记录
  3. 使用可读的格式

解决方案

JSR223 PostProcessor + Groovy 脚本实现

import groovy.json.JsonSlurper
import java.nio.file.*

// 1. 检查响应时间是否超过阈值(200ms)
if (prev.getTime() > 200) {
    
    // 2. 解析JSON响应
    def response = prev.getResponseDataAsString()
    def json = new JsonSlurper().parseText(response)
    
    // 3. 提取关键字段
    def cnsmrSrlNo = json.Head.CnsmrSrlNo
    def glblSrlNo = json.Head.GlblSrlNo
    def responseTime = prev.getTime()
    
    // 4. 构造记录内容(带时间戳)
    def timestamp = new Date().format("yyyy-MM-dd HH:mm:ss")
    def record = "[${timestamp}] CnsmrSrlNo:${cnsmrSrlNo}, GlblSrlNo:${glblSrlNo}, ResponseTime:${responseTime}ms\n"
    
    // 5. 定义文件路径(推荐使用绝对路径)
    def filePath = "D:/JMeter_Logs/slow_responses.log"
    
    // 6. 确保目录存在
    def logFile = new File(filePath)
    if (!logFile.parentFile.exists()) {
        logFile.parentFile.mkdirs()
    }
    
    // 7. 追加写入文件
    logFile << record
    
    // 8. 在JMeter日志中输出提示(可选)
    log.info("记录慢响应: " + record.trim())
}

配置步骤

  1. 添加JSR223 PostProcessor

    • 位置:目标HTTP请求 → 右键添加 → 后置处理器 → JSR223 PostProcessor
  2. 配置脚本参数

    • 语言:选择 groovy
    • 将上述脚本复制到脚本区域
    • 修改 filePath 变量为实际路径
  3. 文件路径配置建议

    // Windows 示例
    def filePath = "C:/Performance_Logs/slow_responses.log"
    
    // Linux/Mac 示例
    def filePath = "/var/log/jmeter/slow_responses.log"
    
    // 使用相对路径(不推荐)
    def filePath = "results/slow_responses.log"
    

日志输出示例

[2025-06-23 15:35:04] CnsmrSrlNo:2025062315350408301578310408, GlblSrlNo:2025062315350408301894748811, ResponseTime:350ms
[2025-06-23 15:36:12] CnsmrSrlNo:2025062315361208301578310409, GlblSrlNo:2025062315361208301894748812, ResponseTime:420ms
[2025-06-23 15:37:45] CnsmrSrlNo:2025062315374508301578310410, GlblSrlNo:2025062315374508301894748813, ResponseTime:315ms

性能优化建议

缓冲写入方案(高并发场景)

import groovy.json.JsonSlurper
import java.util.concurrent.ConcurrentLinkedQueue

// 创建线程安全的缓冲队列
static ConcurrentLinkedQueue<String> buffer = new ConcurrentLinkedQueue<>()
def filePath = "D:/JMeter_Logs/slow_responses.log"

if (prev.getTime() > 200) {
    def response = prev.getResponseDataAsString()
    def json = new JsonSlurper().parseText(response)
    
    def record = "[${new Date().format('yyyy-MM-dd HH:mm:ss')}] " +
                 "CnsmrSrlNo:${json.Head.CnsmrSrlNo}, " +
                 "GlblSrlNo:${json.Head.GlblSrlNo}, " +
                 "ResponseTime:${prev.getTime()}ms\n"
    
    // 添加到缓冲队列
    buffer.add(record)
    
    // 每积累50条或每10秒写入一次
    if (buffer.size() >= 50) {
        flushBuffer(filePath)
    }
}

// 定时刷新缓冲的方法
static void flushBuffer(String path) {
    def logFile = new File(path)
    if (!logFile.parentFile.exists()) logFile.parentFile.mkdirs()
    
    try {
        def writer = new FileWriter(logFile, true)
        while (!buffer.isEmpty()) {
            writer.write(buffer.poll())
        }
        writer.close()
    } catch (Exception e) {
        log.error("缓冲写入失败", e)
    }
}

// 添加定时刷新线程(每10秒)
if (!org.apache.jmeter.threads.JMeterContextService.getTestStartTime()) {
    Thread.start {
        while (true) {
            sleep(10000) // 10秒
            if (!buffer.isEmpty()) {
                flushBuffer(filePath)
            }
        }
    }
}

注意事项

  1. 文件权限问题

    • 确保JMeter进程有目标目录的写入权限
    • Linux系统可能需要配置目录权限:chmod -R 755 /var/log/jmeter
  2. 日志轮转

    • 添加日期后缀实现自动轮转:
      def dateSuffix = new Date().format("yyyyMMdd")
      def filePath = "D:/JMeter_Logs/slow_responses_${dateSuffix}.log"
      
  3. 错误处理增强

    • 添加JSON解析异常处理:
      try {
          def json = new JsonSlurper().parseText(response)
          // 提取字段...
      } catch (Exception e) {
          log.error("JSON解析失败: " + e.getMessage())
      }
      
  4. JMeter最佳实践

    • 在测试计划中添加以下配置:
      # jmeter.properties 配置
      jsr223.groovy.engine.cache.size=100  # 缓存编译脚本
      
  5. 监控与告警

    • 可结合以下工具实时监控日志:
      # Linux 监控命令
      tail -f /var/log/jmeter/slow_responses.log | grep --color=auto 'ResponseTime:[3-9][0-9][0-9]ms'
      

替代方案比较

方案 优点 缺点 适用场景
JSR223 + Groovy 高性能,功能强大,线程安全 需要Groovy基础 推荐方案,适合所有场景
BeanShell JMeter内置,无需额外依赖 性能较差,功能有限 旧版本JMeter兼容
响应文件写入监听器 无需编程 灵活性差,不能条件过滤 简单场景
JSR223采样器+队列 最高性能 实现复杂 超高并发(>1000 TPS)

扩展应用

集成到JMeter Dashboard

  1. 在测试计划中添加 Backend Listener
  2. 配置InfluxDB/Grafana收集响应时间数据
  3. 创建Dashboard监控慢请求比例

邮件报警扩展

// 在原始脚本中添加(当响应时间>1000ms时发送邮件)
if (prev.getTime() > 1000) {
    def mailBody = "严重慢响应检测!\n" + record
    def command = "mailx -s 'JMeter告警' admin@example.com <<< '${mailBody}'"
    def proc = ["sh", "-c", command].execute()
}

最佳实践提示:对于生产环境监控,建议结合ELK(Elasticsearch, Logstash, Kibana)堆栈实现日志的集中管理和可视化分析。

posted @ 2025-06-23 16:17  夷某蓁  阅读(57)  评论(0)    收藏  举报