Observability middleware у Bun.js: logs, request id, tracing і latency budgets
Практичний deep dive по observability middleware у Bun.js: request id, structured logs, traceparent, OpenTelemetry, latency budgets, timing headers, error correlation, redaction, sampling і погані практики логування.

Bun.js Middleware Production Guide 2026
Серія про production middleware у Bun.js: огляд, безпека, performance, observability, rate limiting, body parsing, WebSocket/SSE і тестування request pipeline.
Усі статті в цьому гайді
01
Bun.js middleware у 2026: overview, best practices і анти-патерни
Базова ментальна модель middleware у native Bun, Hono та Elysia, з прикладами, оптимізацією і roadmap наступних deep dive статей.
02
Auth middleware у Bun.js: JWT, sessions, API keys і multi-tenant контекст
Як правильно будувати auth middleware у Bun: порядок перевірок, cache, token rotation, tenant context, помилки 401/403 і тестування.
03
Rate limiting у Bun.js: in-memory, Redis, sliding window і edge cases
Детальний розбір rate limiting для Bun API: алгоритми, Redis, distributed limits, abuse protection і graceful degradation.
04
Observability middleware у Bun.js: logs, request id, tracing і latency budgets
Як додати request id, structured logs, timing headers, OpenTelemetry-подібний flow і не перетворити логування на bottleneck.
05
Body parsing і validation у Bun.js: JSON, uploads, streams і payload limits
Як безпечно читати body у Bun, де ставити limits, як не зламати streams, uploads, idempotency і schema validation.
Логи без request id, traces без sampling policy, errors без tenant/user context, metrics без route group і debug body у production не є observability. Це просто шум, який іноді випадково допомагає.
Observability middleware має давати відповідь на практичні питання: який request, який route, який tenant, який user/API key, скільки часу зайняв auth, rate limit, handler, database, downstream, який error class і де це знайти у logs.
У Bun це краще проектувати як тонкий request-scoped layer, а не як довільні console.log у handlers.
Це четвертий chapter серії про Bun middleware. Після auth і rate limiting треба зробити так, щоб production поведінка була видима, а не тільки “ніби швидка локально”.
console.log(req), body logs, різні request id у різних шарах, tracing без context propagation.Observability не варто зводити до “додали логер”. Logs, metrics і traces мають різні ролі, і middleware має зібрати мінімальний контекст для всіх трьох.
| Сигнал | Що відповідає | Що писати | Ризик |
|---|---|---|---|
| Logs | Що сталося з конкретним request або error | requestId, traceId, route, status, duration, error class, tenant/user ids | Шум, PII, секрети, body dumps, expensive serialization |
| Metrics | Що відбувається в системі агреговано | latency percentiles, error rate, request count, limiter decisions | Надто висока cardinality через userId/path params |
| Traces | Де request витратив час у distributed flow | spans, parent/child relationship, downstream calls, timings | Немає користі без propagation і sampling policy |
Logs, metrics і traces не дублюють одне одного. Вони дають різні кути огляду на той самий request flow.
Скріншот секції observability-modelВисновок
Для Bun middleware найкращий baseline: request id у logs, latency у metrics, trace context у downstream calls.
Request id має бути створений на вході або прийнятий від trusted edge/proxy. Далі він має пройти через logs, response headers, error reports і downstream calls. Якщо різні middleware генерують різні ids, correlation втрачається.
Мінімальний native Bun патерн:
type Context = { requestId: string; startedAt: number };
type Handler = (req: Request, ctx: Context) => Promise<Response> | Response;
type Middleware = (next: Handler) => Handler;
const withRequestId: Middleware = (next) => async (req, ctx) => {
const incoming = req.headers.get("x-request-id");
const requestId = incoming && incoming.length <= 128 ? incoming : crypto.randomUUID();
const res = await next(req, { ...ctx, requestId });
res.headers.set("x-request-id", requestId);
return res;
};
Bun.serve({
fetch: withRequestId(async (_req, ctx) => {
return Response.json({ ok: true, requestId: ctx.requestId });
}),
});У production варто чітко визначити trust boundary. Якщо x-request-id приходить від публічного клієнта, його треба валідувати або замінити. Якщо він приходить від вашого gateway, його можна прийняти як upstream correlation id.
Request id має бути один на весь request flow: response, logs, errors і downstream calls мають посилатися на той самий ідентифікатор.
Скріншот секції request-idПрактичне правило
Генеруйте request id один раз на edge або на вході в Bun API, а потім тільки передавайте його далі.
Structured logging означає, що log entry є JSON-like подією з полями, які можна фільтрувати: requestId, traceId, route, method, status, durationMs, tenantId, subjectId, errorClass. Рядок user failed не масштабується, коли інцидент має 200 тисяч events.
Pino популярний у Node ecosystem саме як швидкий JSON logger і має redaction механізм для приховування sensitive fields. Навіть якщо ви не використовуєте Pino у Bun напряму, принципи ті самі: structured fields, low overhead, redaction, sampling, жодних secrets у payload. [4]
Типовий shape log entry для Bun API:
logger.info({
event: "request.completed",
requestId: ctx.requestId,
traceId: ctx.traceId,
method: req.method,
route: ctx.routePattern,
status,
durationMs,
tenantId: ctx.auth?.tenantId,
subjectId: ctx.auth?.subjectId,
});Що не логувати
Не логайте Authorization headers, cookies, refresh tokens, full API keys, raw request body, passwords, payment data або великі payload-и без явного security review.
W3C Trace Context стандартизує headers traceparent і tracestate, щоб різні системи могли передавати trace identity між services. OpenTelemetry використовує context propagation, щоб spans були частиною одного distributed trace. [2][3]
У Bun API це означає: якщо request прийшов із traceparent, ви маєте або прийняти його від trusted upstream, або створити новий trace. Якщо ваш handler викликає інший service, queue, worker або AI gateway, trace context має піти далі.
Не плутайте request id і trace id. Request id зручний для support/debug response. Trace id потрібен для distributed path. Вони можуть бути різними, але мають бути разом у logs.
Trace context потрібен, коли request проходить через кілька services. Без propagation trace розпадається на непов'язані фрагменти.
Скріншот секції trace-contextВисновок
Request id допомагає знайти один request. Trace context показує весь шлях request через систему.
Якщо ви бачите тільки total duration, ви знаєте, що API повільний, але не знаєте чому. Observability middleware має розбити request на важливі етапи.
Скільки коштує credential verification
JWT verify, session lookup, API key lookup, tenant resolution і permissions cache мають окремий timing. Інакше auth непомітно стає bottleneck.
Скільки коштує limiter storage
Redis latency або local limiter overhead має бути видимим. Якщо limiter додає 15ms до кожного request, це вже product decision.
Скільки часу займає business logic
Handler timing треба відділяти від middleware timing, щоб не оптимізувати не той шар.
Скільки часу йде на DB, APIs, queues
DB і external services мають окремі spans або timing events. Інакше slow query виглядає як slow Bun server.
Висновок
Latency без breakdown перетворюється на здогадки. Breakdown без budget перетворюється на нескінченний шум.
У high-traffic Bun API повне логування кожного request може бути дорожчим за сам handler. Sampling має бути частиною дизайну, а не аварійним вимикачем.
Добре: повні logs для errors і slow requests
Errors, 5xx, 429 spikes, auth failures і slow requests варто логувати детальніше, але все одно без секретів.
Обережно: debug logs для всього traffic
У production це створює storage bill, latency, noise і security exposure. Debug sampling має бути вузьким і тимчасовим.
Добре: route-aware sampling
Critical flows, checkout, login, exports і webhooks можуть мати іншу sampling policy, ніж cheap public GET routes.
Обережно: sampling без інцидентного override
Під час інциденту команда має мати контрольований спосіб тимчасово підняти деталізацію для route, tenant або request class.
Observability легко перетворити на проблему: повільні logs, витоки секретів, шум і trace data, яку ніхто не може зв'язати.
console.log(req) або логування raw request object.
Логування Authorization, cookies, refresh tokens, full API keys або request body.
Генерація нового request id у кожному middleware.
Trace id є, але він не пишеться в logs.
Downstream calls не отримують trace context.
Metrics мають high cardinality через raw URL з ids або userId labels.
Error logs не містять route, status, requestId або error class.
Debug logging увімкнений глобально в production.
Observability middleware стоїть після handler і не бачить early rejects.
Немає sampling policy і storage budget.
Рев'ю правило
Observability має відповідати на питання інциденту швидше, ніж вона створює нові ризики для performance і security.
Цей checklist варто пройти перед запуском Bun API у staging або production, особливо якщо API має auth, rate limiting і downstream calls.
Request id один на весь flow
Приймається від trusted upstream або генерується на вході, додається в response і всі logs.
Trace context propagates
traceparent і tracestate приймаються/створюються за policy і передаються у downstream calls.
Structured logs мають стабільний schema
event, requestId, traceId, route, method, status, durationMs, tenant/subject ids, error class.
Secrets redacted
Authorization, cookies, API keys, tokens, passwords, PII і raw body не потрапляють у logs.
Latency breakdown є
Auth, rate limit, handler, DB/downstream мають окремі timings або spans.
Sampling policy визначена
Errors і slow requests логуються детальніше; high-volume success logs мають sampling або aggregation.
Route labels нормалізовані
Metrics використовують route pattern, наприклад /users/:id, а не raw /users/123.
Incident override контрольований
Є тимчасовий спосіб підняти деталізацію для route/tenant/request class без глобального debug хаосу.
Bun API може відповідати швидко, але без observability команда все одно програє час на інцидентах. Request id, structured logs, trace context і latency breakdown дають можливість швидко зрозуміти, що сталося, де сталося і кого зачепило.
Головний компроміс: observability не має стати новим bottleneck або новим каналом витоку даних. Тому middleware має бути тонким, redaction має бути default, sampling має бути свідомим, а timings мають вимірювати саме ті шари, які можуть боліти.
У production корисний не той лог, який містить усе. Корисний той, який містить правильний мінімум і стабільно пов'язується з request, trace, route, tenant і error.
Ні для production. `console.log` може допомогти локально, але production API потребує structured logs з requestId, route, status, duration, error class і redaction. Інакше logs важко шукати, агрегувати й безпечно зберігати.
Ні. Request id зазвичай використовується для support/debug correlation одного HTTP request. Trace id показує distributed path через кілька services. У logs краще мати обидва.
Authorization headers, cookies, refresh tokens, full API keys, passwords, PII, payment data і raw request body без explicit security review. Redaction має бути default.
Не завжди з першого дня. Для малого API достатньо request id, structured logs і latency breakdown. Коли з'являються downstream services, queues або distributed flow, trace context і OpenTelemetry стають значно кориснішими.
Тримайте middleware тонким, не серіалізуйте великі об'єкти, не логайте body, використовуйте sampling для high-volume success traffic, вимірюйте overhead логера і пишіть route labels без high-cardinality values.
На самому початку, щоб бачити early rejects від auth/rate limit/body validation. Але redaction і context enrichment мають бути акуратними, щоб не читати body або secrets без потреби.
Джерела підтверджують стандарти trace context, OpenTelemetry propagation підхід, Bun server model і практики structured logging/redaction.
PAS7 Studio може допомогти спроєктувати observability middleware для Bun, Hono або Elysia: request id, structured logs, trace context, latency budgets, redaction, sampling і dashboards для production API.
Це особливо корисно для SaaS, internal platforms, integration APIs і high-traffic продуктів, де інциденти треба пояснювати швидко, а не читати тисячі випадкових log lines.
Observability middleware у Bun.js: logs, request id, tracing і latency budgets
Пов'язані статті
Скільки коштує розробка AI асистента у 2026: RAG чатбот, база знань, CRM, Telegram та підтримка
Практичний гід для бізнесу: від чого залежить ціна розробки AI асистента у 2026 році, що входить у RAG чатбот, інтеграції з CRM, Telegram, guardrails, оцінювання, моніторинг і супровід.
AI для розробки лендінгів: де він реально прискорює запуск, а де псує конверсію
Дослідження про використання AI у розробці лендінгів: v0, Webflow AI, Builder.io, Framer-подібні AI builders, генерація UX, copy, SEO, персоналізація, A/B тести, ризики шаблонності, безпеки, доступності та технічного боргу.
AI SEO / GEO у 2026: ваші наступні клієнти — не люди, а агенти
Пошук зміщується від кліків до відповідей. Боти та AI-агенти сканують, цитують, рекомендують і дедалі частіше купують. Дізнайтесь, що таке AI SEO / GEO, чому класичного SEO вже недостатньо, і як PAS7 Studio допомагає брендам перемагати у «агентному» вебі.
Найпотужніший чіп від Apple? M5 Pro і M5 Max б'ють рекорди
Аналітичний розбір Apple M5 Pro і M5 Max станом на березень 2026 року. Пояснюємо, чому ці чіпи можна вважати найпотужнішими професійними ноутбучними SoC від Apple, як вони виглядають на тлі M4 Pro, M4 Max, M1 Pro, M1 Max і що показують у порівнянні з актуальними Intel та AMD.
Професійна розробка для вашого бізнесу
Створюємо сучасні веб-рішення та боти для бізнесу. Дізнайтеся, як ми можемо допомогти вам досягти цілей.