Subchapter 8.4
references/logs-loki.mdMarkdown4 KBView on GitHub
Neon exposes branch-scoped logs. Today they cover Neon Functions and Object Storage only. Postgres computes and the AI Gateway are coming; until then, neither emits records. Logs are available in aws-us-east-2, aws-us-east-1, aws-eu-central-1, and . A branch that can’t serve logs at all answers with (the message says whether it’s the wrong region or a branch not collecting telemetry yet), versus a empty result when the branch is enabled but has no records in the window; an unknown branch answers .
aws-ap-southeast-1404reason: telemetry_not_enabled200reason: branch_not_foundUse Neon CLI 3.1 or newer first. Decide which branch you are querying. Without --branch, the CLI uses the branch pinned in .neon, or the project’s default branch when the workspace isn’t linked. A deployed function or bucket usually lives on a different branch than the one checked out for development, so an empty result is more often the wrong branch than a missing log.
neon logs query --since 1h
neon logs query --branch production --source function --minimum-severity error --since 6h
neon logs query --source storage --since 1h --output json
neon logs fields
neon logs field-values service_name --since 1h--source accepts function, storage, and pg_endpoint, but only function and storage return records today — pg_endpoint is accepted and comes back empty until Postgres logs ship. The window defaults to 1h on query and 6h on field-values, and cannot exceed 7d on either. If Neon reports --minimum-severity as unsupported on a branch, use --severity-text instead (an exact, case-sensitive match, e.g. ERROR); severities vary by source, so confirm what a branch carries with neon logs field-values severity_text. Run neon logs --help for the full filter and pagination interface.
--logql replaces the structured filters with a raw stream selector or line filter. Its stream label is entity_type, not source:
neon logs query --since 1h --logql '{entity_type="function"} |= "timeout"'If the CLI is unavailable, fall back to the Neon MCP server’s read-only query_logs, list_log_fields, and list_log_field_values tools.
For direct HTTP reads, authenticate with Authorization: Bearer <NEON_API_KEY> and use this branch-scoped base URL:
https://console.neon.tech/telemetry/v1/projects/{projectId}/branches/{branchId}/lokiThe available endpoints are:
GET /api/v1/query_rangeGET /api/v1/labelsGET /api/v1/label/{name}/valuesThis is a read-only Loki-compatible subset, not a push endpoint or complete Loki deployment. query_range supports LogQL stream selectors and line filters, plus since or start/end, limit, and direction; it does not support aggregations, parsers, or formatting stages.
The paths above are the ones to call directly. A Loki client that builds its own paths — a Grafana data source appends /loki/api/v1 to whatever URL it is given — may need a different root, so confirm the data-source URL against the Neon docs rather than pasting this base.
In TypeScript applications, use @neon/sdk. Project and branch are positional, and query returns a lazy paginated iterable rather than a promise:
for await (const record of neon.logs.query(projectId, branchId, {
since: "1h",
source: "function",
})) {
console.log(record.timestamp, record.severity_text, record.message);
}
const { data: fields } = await neon.logs.fields(projectId, branchId);
const { data: serviceNames } = await neon.logs.fieldValues(
projectId,
branchId,
"service_name",
);query‘s iterator always throws on error, but fields and fieldValues follow the client’s throwOnError, which defaults to false and hands back { data, error }. fieldValues resolves to the whole response, not a bare array: read serviceNames.values, and treat them as an arbitrary subset whenever serviceNames.is_truncated is true.