AgentStack
SKILL verified MIT Self-run

Request Correlation

skill-robhowley-py-pit-skills-request-correlation · by robhowley

Enforce end-to-end request correlation across HTTP handlers,

No reviews yet
0 installs
6 views
0.0% view→install

Install

$ agentstack add skill-robhowley-py-pit-skills-request-correlation

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Request Correlation? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Skill: request-correlation

Core stance

Every request or job must produce a traceable log story.

A single correlation ID must propagate through:

  • HTTP handlers
  • service functions
  • outbound HTTP calls
  • background jobs and async tasks

The correlation ID must appear automatically in logs.

Infrastructure vs. convention: Some rules are wired once at app startup (middleware, logging config, HTTP client factory). Others are conventions followed everywhere (raise don't log in services, never pass correlation as a function argument). Keep them separate in your mental model -- the infrastructure makes the conventions effortless.

Canonical locations

Correlation infrastructure must live in predictable modules.

Use:

{pkgname}/observability/correlation.py\ {pkgname}/observability/logging.py

Do not duplicate correlation logic elsewhere.

Rules

1. Wire correlation at entrypoints

Entrypoints include HTTP requests, background job workers, CLI tasks, and async task roots.

For HTTP requests, use a functional middleware to read x-request-id if present, otherwise generate one, then set it into context:

``` python import uuid from fastapi import Request from {pkgname}.observability.correlation import correlationid

@app.middleware("http") async def correlationmiddleware(request: Request, callnext): cid = request.headers.get("x-request-id") or str(uuid.uuid4()) correlationid.set(cid) response = await callnext(request) response.headers["x-request-id"] = cid return response


Prefer `@app.middleware("http")` over `BaseHTTPMiddleware` — the class-based
approach can swallow exceptions and interfere with streaming responses.

For job workers and CLI entrypoints, set `correlation_id` before executing
the task -- either from a passed value or a freshly generated one.

**2. Store correlation in `contextvars`**

Correlation must live in a `contextvars.ContextVar`.

Never store it on request objects or pass it through every function
argument.

Example:

``` python
from contextvars import ContextVar

correlation_id: ContextVar[str | None] = ContextVar("correlation_id", default=None)

3. Inject correlation into all log records

Logging configuration must automatically attach the correlation ID.

Example:

``` python class CorrelationFilter(logging.Filter): def filter(self, record): record.correlationid = correlationid.get() return True


Log format must include it (use structured/JSON output if the project
already does):

    %(levelname)s [cid=%(correlation_id)s] %(message)s

**4. Log exceptions only at boundaries**

Exceptions are logged exactly once at system boundaries:

-   HTTP exception handlers
-   job worker wrapper
-   CLI entrypoint

Service functions should raise errors but **not log them**. Log calls
inside service internals to "track" correlation add noise without value --
the boundary log with the shared correlation ID tells the whole story.

**5. Propagate correlation to outbound HTTP calls**

All outbound HTTP clients must include the correlation ID.

Example:

``` python
headers={"x-request-id": correlation_id.get()}

Centralize HTTP client creation so headers are applied automatically. See the http-client-integration skill for the full outbound client pattern.

6. Propagate correlation to background jobs

If a request schedules a queue-based job, pass the correlation ID explicitly.

Example:

``` python queue.enqueue(task, correlationid=correlationid.get())


The worker must restore it before executing the task.

**7. Be explicit about context propagation for spawned async tasks**

Do not assume task boundaries preserve correlation in every execution
model. Use `copy_context()` as the safe pattern:

``` python
import contextvars
import asyncio

ctx = contextvars.copy_context()
loop.run_in_executor(None, ctx.run, task)
# or for coroutines:
asyncio.get_running_loop().call_soon(ctx.run, task)

This applies the same principle as Rule 6 -- correlation must be deliberately carried across any execution boundary, not assumed to be inherited.

8. Never log secrets

Never log:

  • authorization headers
  • tokens
  • passwords
  • cookies
  • session IDs

Success signal

A request should produce logs that share one correlation ID:

INFO request.start cid=abc123 path=/orders INFO http.outbound cid=abc123 service=payments ERROR request.failed cid=abc123 error=PaymentError

One request → one correlation ID → one coherent trace.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.