如何为无头模式Locust会话的输出添加自定义指标列?
为无头模式Locust添加自定义指标列的实现方法
完全可行,虽然官方文档没有直接给出修改输出的指引,但可以通过扩展Locust的统计类和重写输出格式化逻辑来实现。以下是具体步骤:
1. 扩展统计类,添加自定义指标字段
首先需要继承Locust的RequestStats类,新增自定义指标的统计逻辑,比如记录平均值、计数等:
from locust.stats import RequestStats class CustomRequestStats(RequestStats): def __init__(self): super().__init__() self.custom_total = 0 self.custom_count = 0 def add_custom_value(self, value): self.custom_total += value self.custom_count += 1 @property def custom_avg(self): return self.custom_total / self.custom_count if self.custom_count > 0 else 0
2. 替换全局统计实例
通过Locust的init事件,将默认的统计实例替换为我们自定义的类:
from locust import events events.init.add_listener(lambda environment: setattr(environment.stats, "total", CustomRequestStats()))
3. 重写控制台输出函数
找到Locust负责无头模式输出的print_stats函数,重写它来加入自定义指标列:
import locust.stats from locust.stats import print_stats as original_print_stats def custom_print_stats(environment): stats = environment.stats # 自定义表头,加入新的自定义指标列 header = "Type Name # reqs # fails | Avg Min Max Med | req/s failures/s | Custom Avg" print(header) print("--------|----------------------------------------------------------------------------|-------|-------------|-------|-------|-------|-------|--------|-----------|-----------") # 遍历每个请求的统计数据,格式化输出 for name, stats_entry in sorted(stats.entries.items()): method, path = name.split(" ", 1) if " " in name else ("", name) reqs = stats_entry.num_requests fails = f"{stats_entry.num_failures}({stats_entry.failure_ratio:.2%})" avg = stats_entry.avg_response_time min_val = stats_entry.min_response_time or 0 max_val = stats_entry.max_response_time or 0 med = stats_entry.median_response_time req_per_sec = stats_entry.total_rps fails_per_sec = stats_entry.failures_per_sec # 获取自定义指标平均值 custom_avg = stats_entry.custom_avg if hasattr(stats_entry, "custom_avg") else 0 line = f"{method:<6} {path:<63} | {reqs:>6} | {fails:>11} | {avg:>6.0f} {min_val:>6.0f} {max_val:>6.0f} {med:>6.0f} | {req_per_sec:>6.2f} {fails_per_sec:>11.2f} | {custom_avg:>10.2f}" print(line) # 输出汇总行 print("--------|----------------------------------------------------------------------------|-------|-------------|-------|-------|-------|-------|--------|-----------|-----------") total_reqs = stats.total.num_requests total_fails = f"{stats.total.num_failures}({stats.total.failure_ratio:.2%})" total_avg = stats.total.avg_response_time total_min = stats.total.min_response_time or 0 total_max = stats.total.max_response_time or 0 total_med = stats.total.median_response_time total_req_per_sec = stats.total.total_rps total_fails_per_sec = stats.total.failures_per_sec total_custom_avg = stats.total.custom_avg total_line = f" Aggregated {total_reqs:>6} | {total_fails:>11} | {total_avg:>6.0f} {total_min:>6.0f} {total_max:>6.0f} {total_med:>6.0f} | {total_req_per_sec:>6.2f} {total_fails_per_sec:>11.2f} | {total_custom_avg:>10.2f}" print(total_line) print() # 替换默认的输出函数 locust.stats.print_stats = custom_print_stats
4. 在任务中收集自定义指标
在你的用户任务函数里,完成请求后收集自定义指标的值,比如从响应中提取业务数据:
from locust import HttpUser, task class MyUser(HttpUser): @task def version(self): response = self.client.get("/version") # 这里替换为实际的自定义指标值,比如从响应JSON中提取 custom_value = 42 # 更新当前请求的统计 self.environment.stats.entries["GET /version"].add_custom_value(custom_value) # 更新全局汇总统计 self.environment.stats.total.add_custom_value(custom_value)
注意事项
- 不同版本的Locust,
RequestStats类的结构可能略有差异,需要根据你使用的版本调整代码 - 自定义指标的统计逻辑可以根据需求修改,比如计数、求和、百分位数等
- 重写输出函数时要注意格式对齐,避免输出混乱
内容的提问来源于stack exchange,提问作者David Ross
相关产品推荐
相关产品推荐

