---
title: "Logs"
description: "Wide events per request, console output and isolate events, searchable for 14 days."
canonical_url: "https://wervt.app/guides/logs"
---
# Logs

> Wide events per request, console output and isolate events, searchable for 14 days.

Everything an app writes to the console ends up in its logs, together with what the runtime knows
about its isolates: boots, boot failures, uncaught exceptions and shutdowns (including CPU and
memory limits). Logs are kept for 14 days. Read them on the app's **Logs** page in the dashboard or
with `wervt logs`.

## Wide events

`@wervt/nuxt` sets up [evlog](https://www.evlog.dev): every request logs **one event** with its
method, path, status, duration and request id, and the error with its stack when it failed. Add
what matters for the request to that same event instead of logging separate lines:

```ts [server/api/rooms/[id].post.ts]
import { useLogger } from '@wervt/nuxt/server'
import { defineEventHandler, getRouterParam } from 'nuxt/server'

export default defineEventHandler(async (event) => {
  const log = useLogger(event)
  const user = await requireUser(event)
  log.set({ user: { id: user.id }, room: { id: getRouterParam(event, 'id') } })
  // …
})
```

Each field becomes searchable: `user.id:u_123`, `room.id:abc`. For a line outside a request, use
`log.info('sync', 'calendar refreshed')` (or `console.log`, which works too).

Requests that fail with a 5xx are logged as `error`, with a 4xx as `warn`.

### Personal data

Logged values are masked when they look like an email, a card number, an IP address, a phone
number, a JWT or a bearer token. Don't put request bodies or secrets into events. Logs may be read
by people and agents debugging the app.

### Configuration

Pass evlog's options under `evlog` in `nuxt.config.ts`, for example to sample routine requests:

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  modules: ['@wervt/nuxt'],
  $production: {
    evlog: { sampling: { rates: { info: 20 } } },
  },
})
```

## Searching

Queries are [LogsQL](https://docs.victoriametrics.com/victorialogs/logsql/):

<table>
<thead>
  <tr>
    <th>
      Query
    </th>
    
    <th>
      Finds
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        level:error
      </code>
    </td>
    
    <td>
      errors, uncaught exceptions, failed boots
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        status:>=500
      </code>
    </td>
    
    <td>
      requests that failed on the server
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        path:/api/rooms
      </code>
    </td>
    
    <td>
      requests to a path (prefix: <code>
        path:/api/*
      </code>
      
      )
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        user.id:u_123
      </code>
    </td>
    
    <td>
      a field you set with <code>
        log.set
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        type:=BootFailure
      </code>
    </td>
    
    <td>
      releases that didn't start
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        type:=Shutdown reason:=CPUTime
      </code>
    </td>
    
    <td>
      isolates stopped for using too much CPU
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        timeout
      </code>
    </td>
    
    <td>
      any entry containing the word
    </td>
  </tr>
</tbody>
</table>

## `wervt logs`

```bash
wervt logs todos                        # the last hour, oldest first
wervt logs todos 'level:error' --since 1d
wervt logs todos 'status:>=500' --json  # every field, one JSON object per line
wervt logs todos -f                     # keep printing new entries
```

To let an agent or a script read logs without deploy rights, give it the **read token**: it can
list apps and read logs, nothing else.

```bash
WERVT_URL=https://api.wervt.app WERVT_TOKEN=<read token> wervt logs todos 'level:error'
```


## Sitemap

See the full [sitemap](https://wervt.app/sitemap.md) for all pages.
