(重要)BeanShell脚本--编写【请求失败触发报警邮件】功能

原文:http://www.cnblogs.com/kuzaman/p/6424065.html 

 

一、需求背景 

一个内容简单的常规接口请求压力测试,每秒需要10个请求,持续2~3天。因此无人随时监控,需要一个报警邮件机制。 

特别说明:我在网上查找了很久,没有发现Jmeter就有请求失败就报警的功能或者插件,因此自己编写(原创,嘎嘎),如果有谁知道类似的插件,请给我留言,万分感谢。 

二、工具选用 

Jmeter工具本身不带有邮件报警功能,需要自己编写BeanShell脚本在接到响应之后进行处理,BSH断言或者BSH后置处理器都行; 

三、最终结构目录预览 

e 齷 刂 试 计 划 : 务 器 组 ) 
压 呗 刂 线 程 组 
HTTP清求默认值 
HTT 鬥 訁 头 苣 理 器 
用 户 定 义 的 單 
RdEagIeeyeäiPostik 求 
响 应 断 自 
—msg=SUCCESS 
响 应 断 自 
一 code = 200 
SH 断 自 
。 发 法 掘 由 阝 件 舌 条 件 
哀 
粢 台 掘 告 
察 香 结 果 树 
工 作 台

四、设计思路 

1、触发条件设计:由于是大批量,长时间的压测,如果出现错误必然是成批出现,则不可能出现一个请求失败就发送一个报警邮件,因此设计一个触发阈值,每次触发后阈值归零进入下一次统计。 

2、根据响应的结果需要对code和msg进行同时校验。 

3、利用if控制器的判断条件来执行是否发送报警邮件。 

4、报警邮件中包含 时间,请求信息,响应等信息。 

五、脚本编写及变量设置 

1、预设置全局变量6个 

Description 
errcount 
sendemail 
Reqstatus 
respcode 
respmsg 
respdata 
requestok 
am defaultjmeter 
am defaultjmeter 
am defaultjmeter

 

errcount:用于记录请求错误次数,其中:数字“0”为每次压测执行时需要恢复的默认初始值; 

sendemail:是否发送报警邮件的标识,默认初始值是字符串“no”,当值为"yes"时,发送邮件(if逻辑控制器执行); 

Reqstauts:由于利用响应代码和响应信息联合做判断,所以需要此变量标识请求是否成功。默认值“requestok”,如果值为“requestNook”则表示请求失败,errcount+=1。 

respcode:由于邮件中需要引入响应代码,因此设置此参数。 

respmsg:由于邮件中需要引入响应信息,因此设置此参数。 

respdata:由于邮件中需要引入响应数据,因此设置此参数。 

2、采样器BeanShell断言脚本 

RdEagIeeyeäiPostik 求 
响 应 断 自 
—msg=SUCCESS 
响 应 断 自 
—code=200 
固 定 定 时 器 
BSH*fiä—IOOOO 
次 误 则 发 法 掘 由 阝 件

2.1、根据请求的响应结果(返回码+返回消息)判断请求是否成功   

  【响应断言--msg=SUCCESS】页面参数配置:Main Sample only+响应文本+匹配+要测试的模式:"SUCCESS" 

  【响应断言--code=200】页面参数配置:Main Sample only+响应代码+Equals+要测试的模式:"200" 

  if(!(SampleResult.getResponseCode().equals("200") && SampleResult.getResponseDataAsString().equals("SUCCESS"))) 

  { 

    XXXXXXX; 

  }  //在jmeter中做样例时SampleResult要改为prev   =》错误,不需要修改 

2.2、请求失败则获取响应代码,信息,数据并变更对应的全局变量的值 

//获取响应中的响应参数 

String code = SampleResult.getResponseCode(); 

String msg = SampleResult.getResponseMessage(); 

String data = SampleResult.getResponseDataAsString(); 

//调试时的打印信息,正式测试时应该注释掉下面3行log.error(); 

log.error("-----------Returncode is :\"" + code + "\""); 

log.error("-----------ResponseMessage is :\"" + msg + "\""); 

log.error("-----------ResponseData is :\"" + data + "\""); 

//将响应的参数赋值给对应的全局变量,用于后续邮件中使用 

vars.put("respcode",code); 

vars.put("respmsg",msg); 

vars.put("respdata",data); 

vars.put("Reqstatus","requestNook"); 

2.3、设置请求结果标识为失败,请求失败计数器加1  

vars.put("Reqstatus","requestNook"); 

count =count + 1; 

vars.put("errcount",count.toString()); 

log.error("----False------count="+count); 

2.4、根据阈值是否触发报警邮件  

if((count % 3) == 0){ 

//sendemail=yes则if逻辑控制器会触发发送报警邮件 

vars.put("sendemail","yes"); 

log.error("--------It is sendemail ? :"+vars.get("sendemail")); 

}else{ 

vars.put("sendemail","no"); 

} 

//设置当前请求采样器Sampler为失败状态(查看结果树里红色高亮显示) 

SampleResult.setSuccessful(false); 

3、IF控制器及邮件发送采样器 

   

BeanShell Sampler 
SMTP sampler

3.1、IF控制器 

由于需要根据条件来判断是否需要发送邮件,因此选择了IF控制器 

"${sendemail}"=="yes" 是否发送邮件的标识变量sendemail等于yes时,发送邮件。 

标识变更在断言【BSH断言--10000次错误则发送报警邮件】中进行设置 

   

如 果 (If) 控 制 器 
名 称 : 掘 由 阝 件 紺 凵 空 制 器 
: 如 果 用 户 自 定 义 單 ndem 的 值 裰 设 定 为 享 符 畢 . yes , 那 么 发 法 一 掘 由 阝 件 
[ 囗 Interpret Condition as Variable Expression? 《 囗 Evaluate forall Children?

3.2、SMTP邮件采样器配置 

   

SMTP Sampler 
SMTP sampler 
Server settings 
Server: smtpsinacom 
Mail settings 
Address From: 
Address To: 
Address To CC: 
Address To acc: 
Add ress Reply-To: 
Auth settings 
@ Use Auth 
Security settings 
@ Use no security features 
Timeouts (milliseconds) 
Connection timeout: 10000 
Read timeout: 
(Defaults: SMTP:25, SSL•Å65, startTLS:587) 
@sinacom 
Username: 
Password: • 
0 Use SSL 
O Use startTLS

  

    

Security settings 
@ Use no security features 
Trust all certificates 
Local truststore: 
Message settings 
O Use SSL 
Use local truststore 
Subject: 
Message: 
C] Include timestamp in subject 
Add Header 
eagleeyeik*knt! 
Returncode is S{respcode} 
ResponseMessage is S{respmsg} 
ResponseOata is S{respdata} 
O Use startTLS 
Enforce StartTLS 
CO Suppress Subject Header 
Send plain body (i.e. not multipart/mixed) 
Attach file(s): 
Send .eml: 
Additional Settings 
Calculate message size 
From iapppaybjqa@sinacom 
hi-fiiä] 
@ Enable debug logging?

  

  

  邮件标题:【eagleeye接口请求失败${__time(YMD)}--${__time(HMS)}】其中后半部分“${__time(YMD)}--${__time(HMS)}”是Jmeter内置变量,在请求成功发送出去后,结果会显示成类似“20170221--135323”形式 

  邮件内容: 

    Returncode is :${respcode} <-----响应代码 

    ResponseMessage is :${respmsg} <----响应信息 

    ResponseData is :${respdata} <----响应数据 

  说明一下:最后是使用sina邮箱成功发送邮件。因为126邮箱尽管设置了【客户端授权密码】,使用Firefox发送邮件,但Jmeter的邮件代理发送仍然失败。有热心朋友提醒说【没有开126的SMTP代理设置】,我在网上找了很多stmp设置的文章,说的都是下图的内容。 

6 “ 邮 
首 页 
总 规 
笞 名 / 老 子 名 片 
宗 信 分 
冂 李 机 号 码 0 箱 
帐 号 与 苤 箱 中 心 
箱 全 过 岩 
箱 季 相 务 
0 过 吸 / 黑 苎 名 苤 
2093 SMTP MAP 
客 户 端 权 码 
通 讯 一 
0126.com 丷 i 
应 甲 中 心 
擾 叹 码 
0 易 信 0 羊 机 皈 I 级 v № i 服 务 v 
收 件 箱 
j 设 首 ^ I 帮 助 丷 i 退 出 
网 易 严 选 
授 叹 码 是 甲 于 登 录 三 方 鏘 件 客 户 端 的 亏 甲 巒 码 . 
适 甲 于 登 录 以 下 服 : POP3/IMAP/SMTP/Exchange/CardDAV/CalDAVAH%. 
C) ( 默 认 〕 
您 已 0 权 码 0 哇 衤 权 码 登 三 方 # 客 产 
过 河 
停 时 河 
2017 . 02 一 05 15 应 g : 21 停 用 
启 0 权 码 , 避 免 码 泄 过 箱 安 全 地 里 哇 衤 # 客 产 0 更 安 心 。 了 解 更 多 >

 

六、BeanShell断言的全部代码 

名称:BSH断言--10000次错误则发送报警邮件 

备注:根据请求失败次数,按照一定比例配置(如:失败10000次发一封邮件),触发邮件发送条件 

log.error(vars.get("Reqstatus")); 
int count = Integer.parseInt(vars.get("errcount").trim()); 
 
if(!(SampleResult.getResponseCode().equals("200") && SampleResult.getResponseDataAsString().equals("SUCCESS"))){ 
//获取响应中的响应参数 
String code = SampleResult.getResponseCode(); 
String msg = SampleResult.getResponseMessage(); 
String data = SampleResult.getResponseDataAsString(); 
//调试时的打印信息,正式测试时应该注释掉下面4行log.error(); 
// log.error("-----------Request FALSE-----------Returncode or ResponseData is ERROR"); 
log.error("-----------Returncode is :\"" + code + "\""); 
log.error("-----------ResponseMessage is :\"" + msg + "\""); 
log.error("-----------ResponseData is :\"" + data + "\""); 
//将响应的参数赋值给对应的全局变量,用于后续邮件中使用 
vars.put("respcode",code); 
vars.put("respmsg",msg); 
vars.put("respdata",data); 
 
vars.put("Reqstatus","requestNook"); 
count =count + 1; 
vars.put("errcount",count.toString()); 
log.error("----False------count="+count); 
if((count % 10000) == 0){ 
//sendemail=yes则if逻辑控制器会触发发送报警邮件 
  vars.put("sendemail","yes");  
  log.error("--------It is sendemail ? :"+vars.get("sendemail")); 
}else{ 
  vars.put("sendemail","no"); 
} 
//设置当前请求采样器Sampler为失败状态(查看结果树里红色高亮显示) 
SampleResult.setSuccessful(false); 
}else{ 
log.error("-----------Returncode is :\""+ SampleResult.getResponseCode()+"\""); 
// log.error("-----------ResponseMessage is :\""+ SampleResult.getResponseMessage()+"\""); 
// log.error("-----------ResponseData is :\""+ SampleResult.getResponseDataAsString()+"\""); 
SampleResult.setSuccessful(true); 
} 

七、邮件发送执行效果: 

1、收到邮件  

eagleeyefåQiß*kÄ20170221- 
iapppaybjqa 
bukaiwen 
-140814 
iapppaybjqa < iapppaybjqa@sina.com> 
14:09 
4 KB 
Returncode is :404 
ResponseMessage is :Not Found 
ResponseData is : 
-From : iapppaybjqa@sina.com 
: 20170221140814

2、Jmeter脚本在测试调试状态下的截图 

 为了测试BSH脚本以及邮箱采样器是否正常工作 ,因此设置请求错误数量达到 3次 就发送报警邮件,在Jmeter的查看结果树组件结果如下: 

 下图中结果树的绿色文字: 

 BeanShell Sampler里面只是打印日志的 语句,绿色表示执行成功; 

 SMTP Sampler表示邮件发送成功,因此是绿色; 

Search: 
Text 
dEagleeyeäiPostik* 
BeanShell Sampler 
SMTP sampler 
BeanShell Sampler 
SMTP sampler 
Thread Name: 1-1 
sample stat 2017-02-21 1408 14 CST 
Load time: 50 
Connect Time: 44 
Latency: 50 
Size in ones: 14g 
Headers size in bytes: 149 
Body size in ones: O 
Sample Count 1 
Error Count 1 
Data type text 
Response code: 404 
Response message: Not Found 
Response headers: 
1 404 Found 
Server: Apache-coyote/l 1 
Content-Type: 
Content-Lengttm O 
Date: Tue, 21 Feb 2017 0608 14 GMT

  

结束语:以上就是Jmeter测试过程中遇到请求失败次数达到一定数量时,进行报警邮件发送的完整内容。 

请求帮助:本人BeanShell用的不多,写起来很啰嗦,用了很多Jmeter全局变量,但目前也没想到更简便的方法,如果有谁能帮我优化一下代码或者结构,请联系我。 

 

posted @ 2017-11-28 11:43  春田花花同学会  阅读(407)  评论(0编辑  收藏  举报