展示 HN:Django-xbench – Django 的慢端点聚合
Show HN: Django-xbench – slow endpoint aggregation for Django

原始链接: https://github.com/yeongbin05/django-xbench

## django-xbench:轻量级 Django 请求性能分析 django-xbench 是一个零代理的 Django 中间件,旨在快速识别性能瓶颈,提供 APM 风格的洞察,而无需完整 APM 解决方案的复杂性。它测量并暴露请求时间分解——特别是数据库时间与应用程序/序列化时间——以及执行的数据库查询数量。 主要功能包括:近乎零配置(只需添加中间件),注重隐私的指标(仅暴露时间戳和查询计数,不暴露查询内容),以及通过 Chrome DevTools 中的 Server-Timing header 进行的可视化。可选的日志记录提供每个请求的指标,并且一个实验性的内存慢端点聚合功能提供了一个基本仪表盘,用于识别性能热点。 django-xbench 可以通过 pip 轻松安装,并支持可配置的设置,用于日志记录、慢端点聚合和桶大小调整。它非常适合本地开发和内部调试,提供清晰的视图,了解 Django 请求中时间的消耗情况。 需要 Python 3.9+ 和 Django 3.2+(在 5.2 上测试过)。

Hacker News 新闻 | 过去 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 Show HN: Django-xbench – Django 慢端点聚合 (github.com/yeongbin05) 6 分,yeongbin05 发表于 1 小时前 | 隐藏 | 过去 | 收藏 | 2 条评论 帮助 simonw 发表于 0 分钟前 | 下一个 [–] 在内存中收集统计数据很不错 - 我原本以为这会写入数据库,但事实并非如此:https://github.com/yeongbin05/django-xbench/blob/f63316126b5... 回复 yeongbin05 发表于 1 小时前 | 上一个 [–] 之前它专注于每个请求的计时。这次更新添加了滚动窗口聚合来检测性能趋势。 回复 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请 YC | 联系 搜索:
相关文章

原文

CI PyPI

Lightweight Django middleware for APM-style request profiling
Measure DB vs App time and query count with near-zero configuration.

  • 🔍 DevTools visibility: See DB vs app/serialization time in Chrome DevTools via Server-Timing.
  • 🚀 Zero-agent: No daemon, no SaaS — just one Django middleware.
  • 🧩 Drop-in: Near-zero configuration (add middleware and go).
  • 🔒 Privacy-first: Exposes timing + query counts only (no query contents stored).

Goal: make performance bottlenecks “visible” (DB vs app/serialization) without heavyweight APM.

Here's how django-xbench exposes request timing breakdown using the Server-Timing header:

Server Timing Preview

Slow Endpoints Dashboard

Adds Server-Timing and X-Bench-Queries headers and optionally logs per-request metrics.

  • ✅ Measures total request time and DB time (via connection.execute_wrapper)
  • ✅ Calculates app time (= total - db)
  • ✅ Counts DB queries
  • ✅ Adds response headers:
    • Server-Timing: xbench-total;dur=..., xbench-db;dur=..., xbench-app;dur=...
    • X-Bench-Queries: <int>
  • ✅ Optional logging:
    • [XBENCH] GET /path | xbench_total=...ms xbench_db=...ms xbench_app=...ms q=...
  • ✅ Slow endpoint aggregation (in-memory, per process) + simple dashboard (experimental)
  • ✅ Tested with pytest + pytest-django
pip install django-xbench

For local development (this repository):

  1. Add middleware in your settings.py:
MIDDLEWARE = [
    # Recommended: place near the top to approximate end-to-end server time
    # (includes other middleware overhead).
    "django_xbench.middleware.XBenchMiddleware",

    # ... other middleware ...
]
  1. Run your server and hit any endpoint:

In your project:

python manage.py runserver
curl -I http://127.0.0.1:8000/<your-endpoint>/

In this repo (demo):

# macOS / Linux
export DJANGO_SECRET_KEY="dev"
python -m examples.manage runserver --noreload
curl -I http://127.0.0.1:8000/db-heavy/
# Windows PowerShell
$env:DJANGO_SECRET_KEY="dev"
python -m examples.manage runserver --noreload
curl -I http://127.0.0.1:8000/db-heavy/

You should see headers similar to:

Server-Timing: xbench-total;dur=12.345, xbench-db;dur=1.234, xbench-app;dur=11.111
X-Bench-Queries: 3

Example:

Server-Timing: xbench-total;dur=52.300, xbench-db;dur=14.100, xbench-app;dur=38.200
  • xbench-total: whole request duration
  • xbench-db: total DB time measured by wrapper
  • xbench-app: max(0, total - db) (serialization/template/python time etc.)

You can inspect this in Chrome DevTools → Network → Timing
(or any browser that supports the Server-Timing spec).

django-xbench supports two configuration styles.

Use a single XBENCH dictionary to keep settings compact and grouped:

XBENCH = {
    "ENABLED": True,       # default: True
    "LOG": False,          # default: False
    "LOG_LEVEL": "info",   # "info" or "debug"
    "SLOW_AGG": False,     # default: False
}

Older flat settings are still supported:

XBENCH_ENABLED = True
XBENCH_LOG_ENABLED = True
XBENCH_LOG_LEVEL = "debug"
XBENCH_SLOW_AGG_ENABLED = True

Slow endpoint dashboard (experimental)

This feature keeps an in-memory rolling window of endpoint timings (per process) and shows the slowest endpoints by "damage" (total accumulated latency).

XBENCH = {"SLOW_AGG": True}

Expose developer endpoints (do not expose publicly)

In your project's urls.py:

from django.urls import include, path

urlpatterns = [
    # ... your urls ...
    path("__xbench__/", include("django_xbench.slowagg.urls")),
]
  • JSON snapshot: GET /__xbench__/slow/?n=20
  • HTML dashboard: GET /__xbench__/slow/ui/?n=20
  • Aggregation is in-memory per process. If you run multiple workers/processes, each one has its own rolling window.
  • Intended for debugging / internal visibility, not as a full distributed APM.
  • DB%: db_total / total
  • Avg Q: average DB queries per request
  • Damage: total accumulated latency in the window (sum of durations)

The dashboard only shows data after requests occur.

If you see "No data yet":

  1. Make sure SLOW_AGG is enabled
  2. Hit some endpoints (e.g. /db-heavy/)
  3. Refresh the dashboard

If using Django runserver with auto-reload, aggregation resets on reload.

Advanced tuning (optional)

XBENCH = {
    "SLOW_AGG": True,
    "SLOW_BUCKET_SECONDS": 10,   # bucket size in seconds
    "SLOW_BUCKET_COUNT": 60,     # number of buckets (window = bucket_seconds * bucket_count)
    "SLOW_ENDPOINT_CAP": 200,    # max unique endpoints per bucket (overflow goes to "__other__")
}

Note: this repo includes a bundled examples/ Django project used by pytest-django. In CI, we set PYTHONPATH=examples to ensure examples.config.settings can be imported reliably.

If you want to see logs while testing:

This repository includes an examples/ Django project for manual testing.

Run it from the repository root:

# macOS / Linux
export DJANGO_SECRET_KEY="dev"
python -m examples.manage runserver --noreload
# Windows PowerShell
$env:DJANGO_SECRET_KEY="dev"
python -m examples.manage runserver --noreload

Try a few endpoints:

curl -I http://127.0.0.1:8000/db-heavy/
curl -I http://127.0.0.1:8000/app-heavy/
curl -I http://127.0.0.1:8000/admin/login/
  • Python: 3.9+
  • Django: 3.2+ (tested on 5.2)

Issues and PRs are welcome.
If you propose new metrics, please include:

  • minimal reproducible example
  • tests
  • documentation update

MIT

联系我们 contact @ memedata.com