Skip to main content

Logs

App Hosting exposes three distinct kinds of logs:

KindWhat it containsHow to fetch
Log historyYour container's stdout and stderr, retained and searchable, surviving the container that produced it.GET /app-services/{id}/streamed-logs
Runtime snapshotThe same output read live off the VM right now, retained nowhere.POST /app-services/{id}/logs then GET with the returned task_id.
Deploy logsThe ordered steps the platform ran to roll out a deployment revision: image start, health probe, ingress cutover, previous-color teardown.Returned inline on each revision in GET /app-services/{id}/deployments.

Reach for history when you are investigating something that already happened, and the snapshot when you want to see what the container is doing at this instant.

Log history

Your container's output is collected continuously and stored, so it outlives the container, the VM, and the deployment that produced it. This is what the console's Logs tab shows.

curl -u "$USER:$PASS" \
"https://api.foundrydb.com/app-services/{id}/streamed-logs?limit=100&level=error&search=timeout&start=2026-07-26T00:00:00Z&end=2026-07-26T23:59:59Z"
ParameterMeaning
limitMaximum entries to return.
levelFilter by severity (error, warn, info, debug).
searchFree-text match against the log line.
start / endRFC 3339 bounds on the time range.

Each entry carries a timestamp, a severity, the line itself, and the container slot it came from. Output written to stderr arrives as error, which is what makes a crashing container stand out from ordinary request logging.

Both container slots are collected, so the output of a deployment that lost a blue/green cutover is still readable afterwards. That is usually exactly what you need after a rollout goes wrong.

Runtime snapshot

A snapshot reads the container's current output directly from the VM. Unlike the history above it is not retained anywhere: it answers "what is happening right now", and it keeps working even when the log store is unavailable.

Runtime logs are the standard output and error stream of your running container. They capture whatever your application writes to stdout or stderr, including startup messages, request traces, errors, and structured log lines.

Log capture is asynchronous: first request a capture, then poll for the result.

Step 1: request a capture

curl -u "$USER:$PASS" -X POST \
https://api.foundrydb.com/app-services/{id}/logs

Response:

{ "task_id": "a1b2c3d4-..." }

Step 2: poll for the result

curl -u "$USER:$PASS" \
"https://api.foundrydb.com/app-services/{id}/logs?task_id=a1b2c3d4-..."

While the capture is still running, the response is 202 Accepted. Once complete, the response is 200 OK:

{
"task_id": "a1b2c3d4-...",
"status": "COMPLETED",
"result": {
"lines": [
"2026-06-20T10:45:00Z INFO server listening on :8080",
"2026-06-20T10:45:01Z INFO GET /healthz 200 1ms",
"2026-06-20T10:45:05Z INFO GET /api/orders 200 12ms"
]
}
}

In the dashboard, the Logs tab on the app detail page runs this flow for you and displays the output inline.

What the capture covers

The capture collects recent lines from the journal of the running container process (the green or blue slot, whichever is currently serving). It does not capture logs from a previous revision that has already been torn down. For post-mortem analysis of a failed deploy, use the deploy logs described below.

Deploy logs

Deploy logs are attached to each deployment revision and record exactly what the platform did to roll out that revision. They let you diagnose a failed deploy without needing access to the VM directly.

Deploy logs are returned as part of the deployment history. Each revision in GET /app-services/{id}/deployments includes a deploy_logs array:

curl -u "$USER:$PASS" https://api.foundrydb.com/app-services/{id}/deployments

Deploy log fields

Each step in deploy_logs has:

FieldDescription
stepPhase name (e.g. start-container-green, health-probe-green, point-ingress-green, stop-previous-blue).
statusok, failed, or info.
duration_msWall-clock duration of the phase in milliseconds.
started_atWhen the phase started (ISO 8601).
messageError text on a failed phase, or a note on an info phase.
detailContainer journal tail captured on a failed phase, for diagnosis.

Deploy phases

Each deployment follows these phases in order:

PhaseWhat it does
start-container-greenPulls the image and starts the new container on the inactive slot.
health-probe-greenPolls the container's readiness probe (HTTP GET on the configured port) until it returns 200 or the timeout elapses.
point-ingress-greenFlips the ingress to route traffic to the new container. At this point the new revision is serving.
stop-previous-blueGracefully stops and removes the previous container.

A failed deploy log tells you exactly which phase failed and why. For example, if health-probe-green failed, message explains the probe result and detail shows the last lines from the container's journal: typically the crash output or a missing dependency error.

Reading a failed deploy

A deploy that fails at health-probe-green means the new container started but did not pass its health check before the timeout. The previous revision continues serving. Check the detail field for the container's last log lines, which usually reveal the root cause (bad environment variable, missing dependency, crash on startup, port mismatch).

A deploy that fails at start-container-green means the image could not be pulled (wrong credentials, image not found) or the container exited immediately before the probe was attempted.

Per-deployment scope

Deploy logs are scoped to a single deployment revision. Each time you push a new image or change app_config, a new revision is created with its own deploy_logs entry. Historical revisions and their logs are retained so you can compare what changed between a working and a broken deploy.

See Deployments for the full deploy log reference and rollback details.