microsoft / microsoft/SimpleL7Proxy
Request per-request GUID correlation ID forwarded to backend (replace or supplement sequential x-S7P-ID)
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 21
- Forks
- 11
- Avg merge
- 7h 36m
- Merged PRs (30d)
- 2
Description
Summary
We need a globally unique, per-request correlation identifier generated by SimpleL7Proxy and forwarded to backend services for end-to-end tracing. The current x-S7P-ID format is useful for operational debugging but is not suitable as a durable correlation ID in multi-replica deployments (e.g. ECS).
Current behavior
On each inbound request, the proxy assigns:
| Identifier | Format | Forwarded to backend? |
|---|---|---|
MID → x-S7P-ID |
{RequestIDPrefix}-{replicaId}-{sequentialCounter} (e.g. S7P-abc12345-847) |
Yes |
| Guid | Guid.NewGuid() (internal) |
No (telemetry/async only) |
replicaId=CONTAINER_APP_REPLICA_NAMEif set, elseHostname- Counter is sequential per process/task and resets to 1 on restart/redeploy
Relevant code paths:
- MID generation:
server.cs—IDStr + counter - Header enrichment:
EventDataBuilder.EnrichRequestHeaders()— setsx-S7P-ID - Backend forward:
ProxyWorker→ProxyHelperUtils.CopyHeaders()
Problem
1. Uniqueness / counter reset
After an ECS task restart, the counter resets:
Before restart: S7P-abc12345-847
After restart: S7P-abc12345-1
The same x-S7P-ID value can appear again over time for the same Hostname, which breaks long-lived or persisted correlation in downstream systems.
2. Collision risk across replicas
If multiple tasks share the same Hostname, they can emit identical IDs in parallel (e.g. two tasks both sending S7P-llm-proxy-prod-1).
3. User profiles do not address this
UserProfileHeader / user profile JSON provides static per-user configuration. It does not generate a dynamic per-request correlation ID.
Expected behavior (baseline request)
Provide a GUID-based correlation ID per request that is:
- Generated by the proxy when the request is accepted (or when missing from the client)
- Globally unique across replicas, restarts, and time
- Forwarded to the backend on every proxied request
- Included in proxy telemetry/logs (CloudWatch / App Insights) for cross-system lookup
Suggested approach (open to contractor design)
- Use the existing internal
Guid(rd.Guid) or generate a new UUID per request - Expose it on a standard header forwarded to backend, e.g.:
X-Correlation-ID, and/orx-ms-client-request-id(already referenced in APIM policies)
- Optionally retain
x-S7P-IDfor infrastructure traceability (replica + local sequence), but correlation for backend persistence should be the GUID
Deployment context
- Platform: AWS ECS (Fargate), multiple tasks behind ALB
- Add-in: AWS 2.2.11.2
- Identity segment today:
Hostnamein task definition (or containerHOSTNAMEfallback) - Not available on ECS:
CONTAINER_APP_REPLICA_NAME(ACA-specific)
ECS examples (current x-S7P-ID behavior)
Good configuration — unique Hostname per task
| ECS Task | Hostname | Request # | x-S7P-ID |
|---|---|---|---|
| Task A | a1b2c3d4e5f6 |
1 | S7P-a1b2c3d4e5f6-1 |
| Task A | a1b2c3d4e5f6 |
847 | S7P-a1b2c3d4e5f6-847 |
| Task B | f6e5d4c3b2a1 |
1 | S7P-f6e5d4c3b2a1-1 |
| Task C | 9z8y7x6w5v4u |
1 | S7P-9z8y7x6w5v4u-1 |
Misconfigured — same Hostname on all tasks
| Task | Request # | x-S7P-ID |
|---|---|---|
| Task A | 1 | S7P-llm-proxy-prod-1 |
| Task B | 1 | S7P-llm-proxy-prod-1 (collision) |
| Task C | 15 | S7P-llm-proxy-prod-15 |
Acceptance criteria
- Each proxied request has a unique GUID correlation ID for its lifetime
- ID is stable for that request through backend retries within the same proxy handling
- ID is forwarded to backend on the agreed header name(s)
- ID appears in proxy observability (logs/events) and can be joined with backend logs
- Behavior is documented (config, header name, interaction with existing
x-S7P-IDandParentId) - No reliance on user profile JSON for correlation ID generation
References
- Internal analysis: sequential
x-S7P-IDon ECS and uniqueness limits (counter reset, sharedHostnamecollisions) - Docs:
docs/REQUEST_VALIDATION.md(RequiredHeaders=X-Correlation-IDas client-side pattern only today) - APIM policy maps
x-S7P-id→x-ms-client-request-id(Azure path)
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with MID generation in server.cs, then trace EventDataBuilder.EnrichRequestHeaders(), ProxyWorker, and ProxyHelperUtils.CopyHeaders() to understand request headers and backend forwarding. Review docs/REQUEST_VALIDATION.md and the existing telemetry paths. Done means the agreed GUID header remains stable through retries, reaches every backend request, appears in observability, and is documented alongside x-S7P-ID and ParentId.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, csharp
- Domain
- backend-api-design, cloud, observability
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100