Chapter 8 · Event Hooks and Custom Statistics
Chapter goals: Master Locust's event system (
events.request/test_start/test_stop, etc.), learn to inject custom metrics, and listen to key lifecycle nodes.
8.1 Event System Overview
Locust's event system lives in the locust.events module. Register callbacks at different test phases:
python
from locust import events
@events.test_start.add_listener
def on_test_start(environment, **kwargs):
print("Load test started!")
@events.test_stop.add_listener
def on_test_stop(environment, **kwargs):
print("Load test ended!")Common events:
| Event | Trigger Moment |
|---|---|
test_start | Entire test begins (once) |
test_stop | Test ends (once) |
request | After every HTTP request completes |
worker_report | Worker reports to Master |
spawning_complete | All virtual users have started |
8.2 Listening to the request Event
Every HTTP request completion triggers the request event — ideal for custom logging, alerts, or statistics:
python
from locust import events
import time
@events.request.add_listener
def on_request(request_type, name, response_time, response_length, exception, context, **kwargs):
if exception:
print(f"❌ {request_type} {name} failed: {exception}")
elif response_time > 2000: # Slow requests over 2 seconds
print(f"⚠️ Slow request {name}: {response_time:.0f}ms")8.3 Custom Metrics Reporting
Use events.request.fire() to纳入 non-HTTP operations into Locust's statistics system:
python
from locust import HttpUser, task, between, events
import time
class CustomMetricsUser(HttpUser):
wait_time = between(1, 2)
@task
def process_data(self):
start = time.time()
# Execute a non-HTTP operation (e.g., database query)
result = self.run_query()
elapsed_ms = (time.time() - start) * 1000
# Report as a custom request, included in Locust's response time charts
events.request.fire(
request_type="DB",
name="SELECT users",
response_time=elapsed_ms,
response_length=len(str(result)),
exception=None,
)8.4 Displaying Custom Data in the Web UI
python
from locust import events
from locust.web import app
from flask import jsonify
@events.test_start.add_listener
def add_custom_endpoint(environment, **kwargs):
@app.route("/api/custom-stats")
def custom_stats():
return jsonify({"slow_requests": 42, "db_queries": 1000})8.5 Chapter Summary
events.requestfires after every HTTP request — log, alert, or customize stats;events.request.fire()extends statistics to non-HTTP operations (DB queries, etc.);test_start/test_stopfor lifecycle hooks;- Custom Flask routes on the Web UI for bespoke dashboards.
🧪 随堂测验
点击你认为正确的选项。答错时会展示正确答案与原因解析。
1. Which event fires after every HTTP request completes?
2. What does events.request.fire() enable?
3. When does the test_stop event fire?
4. How do you add a custom route to the Locust Web UI?
🛠️ Hands-On Exercises
- Register a
requestlistener that prints a warning for any request taking over 1 second. - Use
events.request.fire()to report a simulated database query into the stats; verify it appears in the Web UI. - Add a
test_stoplistener that writes a summary JSON file with total requests, failures, and p95.
Proceed to Chapter 9: Parametrization and Data-Driven Testing.