Skip to content

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:

EventTrigger Moment
test_startEntire test begins (once)
test_stopTest ends (once)
requestAfter every HTTP request completes
worker_reportWorker reports to Master
spawning_completeAll 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.request fires after every HTTP request — log, alert, or customize stats;
  • events.request.fire() extends statistics to non-HTTP operations (DB queries, etc.);
  • test_start / test_stop for 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 ​

  1. Register a request listener that prints a warning for any request taking over 1 second.
  2. Use events.request.fire() to report a simulated database query into the stats; verify it appears in the Web UI.
  3. Add a test_stop listener that writes a summary JSON file with total requests, failures, and p95.

Proceed to Chapter 9: Parametrization and Data-Driven Testing.