# Netlify Logs

Stream function logs into Gonzo with a lightweight `jq` normalizer. Netlify's CLI doesn't have a `--json` flag for function logs — it outputs `LEVEL MESSAGE` text over WebSocket. The normalizer splits the level, promotes any embedded JSON fields, and drops blank lines so Gonzo receives clean JSONL.

#### Quick Start

```bash
netlify login
netlify link
netlify logs:function <function-name> \
  | jq --unbuffered -R '
    select(length > 0) |
    (index(" ")) as $i |
    if $i then
      {level: .[:$i] | ascii_downcase, message: .[($i+1):]}
    else
      {level: "info", message: .}
    end |
    (.message | fromjson? // null) as $json |
    if $json then . + $json else . end |
    select(.message | length > 0)
  ' \
  | gonzo
```

Replace `<function-name>` with your function (e.g. `hello`, `submit-form`). The `--unbuffered` flag on `jq` is required — without it, output buffers and logs stall.

#### Prerequisites

* Gonzo installed
* [Netlify CLI](https://cli.netlify.com/) installed (`npm install -g netlify-cli`)
* `jq` installed (`brew install jq`)
* A Netlify project with at least one deployed serverless function

#### Log Types

| Log type           | CLI access             | Gonzo compatible        | What it captures                                              |
| ------------------ | ---------------------- | ----------------------- | ------------------------------------------------------------- |
| **Function logs**  | `logs:function <name>` | ✅ Yes (with normalizer) | `console.log/warn/error` output + platform invocation metrics |
| **Deploy logs**    | `logs:deploy`          | ⚠️ Limited (plain text) | Build output during git-triggered deploys                     |
| **Edge Functions** | Dashboard only         | ❌ Not via CLI           | Deno-based edge function console output                       |
| **Traffic logs**   | Enterprise Log Drains  | ❌ Not via CLI           | CDN request logs: method, path, status, duration              |

#### Usage Patterns

**Stream a specific function:**

```bash
netlify logs:function hello | jq --unbuffered -R '<normalizer>' | gonzo
```

**Filter by level at the source:**

```bash
netlify logs:function hello --level warn error | jq --unbuffered -R '<normalizer>' | gonzo
```

**Watch a deploy in real time** (plain text, no structured fields):

```bash
netlify logs:deploy | gonzo
```

**Capture to file for replay:**

```bash
netlify logs:function hello | jq --unbuffered -R '<normalizer>' > /tmp/netlify-logs.jsonl &
gonzo -f /tmp/netlify-logs.jsonl --follow
```

**With local AI (logs never leave your machine):**

```bash
export OPENAI_API_KEY="ollama"
export OPENAI_API_BASE="http://localhost:11434"
netlify logs:function hello | jq --unbuffered -R '<normalizer>' | gonzo
```

#### Multiple Functions

The Netlify CLI streams one function at a time — there is no "stream all" mode. To monitor multiple functions, run separate terminal sessions each piping a different function into Gonzo.

#### Platform Latency

Function logs typically appear in the CLI stream **5–15 seconds** after execution. This delay is inherent to Netlify's log delivery and is not affected by the Gonzo pipe or the `jq` normalizer.

#### Structured Logging Tips

Netlify does not add timestamps to function log output. For the best Gonzo experience, emit structured JSON with at least `message`, `level`, and a timestamp:

```javascript
console.log(JSON.stringify({
  message: "User signup completed",
  level: "info",
  ts: new Date().toISOString(),
  userId: 123
}));
```

The normalizer automatically promotes these fields to the top level, giving Gonzo access to timestamps and custom fields for filtering.

Avoid pretty-printed JSON — `JSON.stringify(obj, null, 2)` spans multiple lines and each line becomes a separate log entry. Always use minified: `JSON.stringify(obj)`.

#### Troubleshooting

| Symptom                               | Cause & fix                                                                                                     |
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| "No site linked"                      | Run `netlify link` to connect your terminal session to a project.                                               |
| Function returns 404                  | Verify with `netlify functions:list`. Check `[functions]` directory in `netlify.toml`.                          |
| Logs appear empty                     | Function may not have been invoked. Trigger the endpoint and wait 5–15s for delivery.                           |
| `jq` hangs / no output                | Missing `--unbuffered` on `jq`. Without it, output buffers when writing to a pipe.                              |
| Blank JSON lines in output            | Ensure the full normalizer with `select(length > 0)` and `select(.message \| length > 0)` is included.          |
| `logs:deploy` says "No active builds" | Deploy logs only attach to remote builds (git push / Netlify UI). CLI deploys build locally — no remote stream. |

***

**Time to complete:** 5 minutes **Prerequisites:** Netlify CLI, jq, Gonzo installed **Full guide:** [`guides/NETLIFY_USAGE_GUIDE.md`](https://github.com/control-theory/gonzo/blob/main/guides/NETLIFY_USAGE_GUIDE.md)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.controltheory.com/controltheory-documentation/gonzo-docs/integration-examples/netlify-logs.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
