# 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)
