An HTTP echo server that captures full request/response exchanges to a log file for debugging. Point traffic at it, inspect what arrived, and optionally copy a ready-made curl command to replay the call elsewhere.
By default the server echoes the request body back to the client. Each captured exchange is written to stdout and appended to the log file at LOG_PATH (default /tmp/requestHeadersQueryParamsAndBody.log).
docker run -d \
-v /tmp:/tmp \
-p 1111:5464 \
--name requestdebugger \
masteralt/requestdebugger:latestSend a test request:
curl "http://127.0.0.1:1111/?size=8192&firstkey=firstvalue%40123" \
-H 'Header1: value1' \
-d '{"dataKey":"dataValue"}'The curl response body (echoed request body):
{"dataKey":"dataValue"}Tail the log file on the host:
tail -f /tmp/requestHeadersQueryParamsAndBody.logStop the container gracefully (sends SIGTERM, drains in-flight requests, then exits):
docker stop requestdebugger
docker rm requestdebuggergit clone git@github.com:SMYALTAMASH/requestdebugger.git
cd requestdebugger
go build -o requestdebugger .
./requestdebuggerThe server listens on port 5464 by default.
Settings can be passed as CLI flags, environment variables, or changed at runtime via HTTP APIs.
| Flag | Default | Description |
|---|---|---|
-curl |
false |
Include a replay curl command in exchange logs |
-log-level |
(see env) | Log verbosity: error, debug, or trace |
-log-format |
(see env) | Exchange log format: text or json |
Examples:
# Full detail in logs + curl commands (text format)
./requestdebugger -log-level trace -curl
# JSON lines on stdout and in the log file (good for log aggregators)
./requestdebugger -log-format json -log-level debug
# Only log failed requests (HTTP 4xx/5xx)
./requestdebugger -log-level error| Variable | Default | Description |
|---|---|---|
PORT |
5464 |
Port the server listens on |
LOG_PATH |
/tmp/requestHeadersQueryParamsAndBody.log |
In-process log file path (same content as stdout) |
LOG_LEVEL |
debug |
Log verbosity: error, debug, or trace |
LOG_FORMAT |
text |
Exchange log format: text or json |
REQUESTDEBUGGER_URL |
(empty) | Base URL used in curl commands; overrides the Requestdebugger_url request header |
Precedence: CLI flags override environment variables where both apply (e.g. -log-level wins over LOG_LEVEL).
Each exchange is written to stdout and LOG_PATH using the same formatted output.
Docker example with all common options:
docker run -d \
-v /tmp:/tmp \
-p 1111:5464 \
-e LOG_LEVEL=trace \
-e LOG_FORMAT=json \
-e REQUESTDEBUGGER_URL=http://api.example.com \
-e LOG_PATH=/tmp/requestHeadersQueryParamsAndBody.log \
--name requestdebugger \
masteralt/requestdebugger:latestTo enable curl generation in Docker without rebuilding, use the runtime API below or pass the flag at entrypoint:
docker run -d \
-v /tmp:/tmp \
-p 1111:5464 \
--entrypoint /app/main \
masteralt/requestdebugger:latest \
-curl -log-level debug -log-format textThese endpoints let you change behaviour without restarting the container.
Get current setting:
curl http://127.0.0.1:5464/_config/curlResponse:
{"curl_enabled":false}Enable curl generation:
curl -X PUT http://127.0.0.1:5464/_config/curl \
-H 'Content-Type: application/json' \
-d '{"enabled": true}'Response:
{"curl_enabled":true}POST is also supported with the same JSON body. Curl commands are off by default and are not generated for /_config/* routes.
Get current level:
curl http://127.0.0.1:5464/_config/log-levelResponse:
{"level":"debug"}Change level at runtime:
curl -X PUT http://127.0.0.1:5464/_config/log-level \
-H 'Content-Type: application/json' \
-d '{"level": "trace"}'Response:
{"level":"trace"}Valid values: error, debug, trace.
Log levels control which exchanges are logged and how much detail each entry contains. The same formatted entry is written to stdout and the log file.
| Level | What gets logged |
|---|---|
error |
Only requests that return HTTP 400+. Failed requests use trace detail (full headers). |
debug |
Every request: timestamp, method, URL, request/response bodies, query params, status. No headers. |
trace |
Everything in debug plus request and response headers. |
Startup, shutdown, config changes, and internal errors are logged separately with [ERROR] or [DEBUG] prefixes. These are not exchange logs.
| Format | Output |
|---|---|
text |
Multi-line block (human-readable, same as before) |
json |
Single JSON object per exchange (one line, ideal for Loki/ELK/CloudWatch) |
./requestdebugger -log-format json -log-level trace -curlJSON example (one line on stdout and in the log file):
{
"timestamp": "2026-06-09T14:32:01.123456789Z",
"log_level": "debug",
"request": {
"method": "POST",
"url": "/",
"body": "{\"dataKey\":\"dataValue\"}",
"query_params": {
"firstkey": ["firstvalue@123"],
"size": ["8192"]
}
},
"response": {
"status": 200,
"body": "{\"dataKey\":\"dataValue\"}"
},
"curl_command": "curl -XPOST 'http://api.example.com/?firstkey=firstvalue%40123&size=8192' ..."
}At trace level, request.headers and response.headers maps are included. curl_command is omitted unless curl generation is enabled.
Use this header (or the REQUESTDEBUGGER_URL env var) to control the host in generated curl commands instead of the {{host}} placeholder.
Priority:
REQUESTDEBUGGER_URLenvironment variable (overrides any incoming header)Requestdebugger_urlrequest header{{host}}placeholder (manual replacement required)
Example with env var:
export REQUESTDEBUGGER_URL=http://api.example.com
curl http://127.0.0.1:5464/orders \
-H 'Requestdebugger_url: http://old-host.com' \
-H 'Authorization: Bearer token' \
-d '{"id":1}'Even though the request sends http://old-host.com, the log and curl command use http://api.example.com because the env var wins.
Example with header only (no env var):
curl http://127.0.0.1:5464/orders \
-H 'Requestdebugger_url: http://staging.example.com' \
-d '{"id":1}'Generated curl target:
curl -XPOST 'http://staging.example.com/orders' ...Use this curl command throughout the examples:
curl "http://127.0.0.1:5464/?size=8192&firstkey=firstvalue%40123" \
-H 'Header1: value1' \
-H 'Content-Type: application/json' \
-d '{"dataKey":"dataValue"}'HTTP response from the server (body is echoed back):
{"dataKey":"dataValue"}./requestdebugger -log-level debug
# or: export LOG_LEVEL=debugLog file and stdout (same content):
###################################################################
TIMESTAMP: 2026-06-09T14:32:01.123456789Z
LOG LEVEL: debug
---------- REQUEST ----------
HTTP Method: POST
REQUEST URL: /
REQUEST BODY: {"dataKey":"dataValue"}
Query Param: firstkey = firstvalue@123
Query Param: size = 8192
---------- RESPONSE ----------
HTTP Status: 200
RESPONSE BODY: {"dataKey":"dataValue"}
###################################################################
Curl commands are not included unless -curl is set or enabled via /_config/curl.
./requestdebugger -log-level traceSame as debug, but headers are included:
###################################################################
TIMESTAMP: 2026-06-09T14:32:01.123456789Z
LOG LEVEL: trace
---------- REQUEST ----------
HTTP Method: POST
REQUEST URL: /
REQUEST BODY: {"dataKey":"dataValue"}
Query Param: firstkey = firstvalue@123
Query Param: size = 8192
REQUEST HEADER: Accept = */*
REQUEST HEADER: Content-Length = 23
REQUEST HEADER: Content-Type = application/json
REQUEST HEADER: Header1 = value1
REQUEST HEADER: User-Agent = curl/8.x
---------- RESPONSE ----------
HTTP Status: 200
RESPONSE BODY: {"dataKey":"dataValue"}
RESPONSE HEADER: Content-Length = 23
RESPONSE HEADER: Content-Type = text/plain; charset=utf-8
###################################################################
Container stdout at trace level includes the same multi-line exchange block plus any [DEBUG] operational lines. There is no separate [TRACE] summary line per request.
./requestdebugger -log-level errorSuccessful requests (HTTP 2xx/3xx) are not written to the log file.
Failed requests (HTTP 400+) are logged with full trace detail. Example after sending a bad config request:
curl -X PUT http://127.0.0.1:5464/_config/log-level \
-H 'Content-Type: application/json' \
-d '{"level": "invalid"}'Log file entry (note LOG LEVEL: trace used for error-detail dumps):
###################################################################
TIMESTAMP: 2026-06-09T14:35:00.987654321Z
LOG LEVEL: trace
---------- REQUEST ----------
HTTP Method: PUT
REQUEST URL: /_config/log-level
REQUEST BODY: {"level": "invalid"}
REQUEST HEADER: Content-Type = application/json
...
---------- RESPONSE ----------
HTTP Status: 400
RESPONSE BODY: invalid log level "invalid" (expected error, debug, or trace)
...
###################################################################
./requestdebugger -log-level debug -curlOr enable at runtime:
curl -X PUT http://127.0.0.1:5464/_config/curl \
-H 'Content-Type: application/json' \
-d '{"enabled": true}'Log file includes a replay command:
...
CURL COMMAND:
curl -XPOST '{{host}}/?firstkey=firstvalue%40123&size=8192' \
-H 'Accept: */*' \
-H 'Content-Type: application/json' \
-H 'Header1: value1' \
-H 'User-Agent: curl/8.x' \
--data-urlencode '{"dataKey":"dataValue"}'
---------- RESPONSE ----------
...
With REQUESTDEBUGGER_URL=http://127.0.0.1:5464:
CURL COMMAND:
curl -XPOST 'http://127.0.0.1:5464/?firstkey=firstvalue%40123&size=8192' \
-H 'Accept: */*' \
...
The Requestdebugger_url header is omitted from -H lines when it is used as the curl URL.
Prebuilt binaries for Windows, macOS, and Linux are published under RequestDebuggerBinariesForAllOS/ in releases.
# Download and unzip the latest release, then:
chmod +x requestDebugger-linux-amd64
./requestDebugger-linux-amd64 -log-level trace -curlSupported architectures: darwin-amd64, linux-386, linux-amd64, linux-arm, linux-arm64, windows-386, windows-amd64.
The server handles SIGTERM and SIGINT (e.g. docker stop, Ctrl+C):
- Stops accepting new connections
- Waits up to 10 seconds for in-flight requests to finish
- Exits cleanly
docker stop requestdebugger # default 10s grace period
docker stop -t 30 requestdebugger # extend grace period if neededNote: SIGKILL (
kill -9) cannot be caught; the process is terminated immediately with no cleanup.
Manifests live under kubernetes/. Deploy with Kustomize:
kubectl apply -k kubernetes/
kubectl -n requestdebugger port-forward svc/requestdebugger 5464:5464
# Exchange logs stream to stdout (and to /tmp inside the pod)
kubectl -n requestdebugger logs -f deploy/requestdebuggerSet JSON format in the deployment or ConfigMap:
env:
- name: LOG_FORMAT
value: "json"Included resources: namespace, configmap, deployment, service, optional service-nodeport, ingress, pdb. No PVC — logs are ephemeral inside the pod; use stdout for aggregation.
See kubernetes/README.md for full deployment details.
- Start the server or container with the desired
-log-level,-log-format, and env vars. - Point your application or curl at the debugger URL.
- Tail stdout or the log file:
kubectl logs -f ...ortail -f /tmp/requestHeadersQueryParamsAndBody.log - Optionally enable curl generation via
/_config/curland copy the curl block from the log. - Set
REQUESTDEBUGGER_URL(or passRequestdebugger_url) so curl commands target your real upstream host. - Stop the container with
docker stopwhen done.