---
title: "Configuration"
description: "Configure evlog once in evlog.config.ts. Every option, and how framework options override it."
canonical_url: "https://www.evlog.dev/reference/configuration"
---
# Configuration

> Configure evlog once in evlog.config.ts. Every option, and how framework options override it.

evlog reads its options from `evlog.config.ts` at the root of your app. The same file drives your server and the [CLI](https://www.evlog.dev/cli/config).

## The config file

```typescript [evlog.config.ts]
import { defineEvlog } from 'evlog'
import { createAxiomDrain } from 'evlog/axiom'

export default defineEvlog({
  service: 'my-api',
  sampling: { rates: { info: 10 }, keep: [{ status: 400 }] },
  drain: createAxiomDrain(),
})
```

`npx evlog init` writes this file for you.

evlog looks for `evlog.config.ts`, `.mts`, `.js` or `.mjs`, starting in your app and walking up to the workspace root. The nearest file wins, so one file at the root of a monorepo covers every app that has none of its own.

## Load it

Nuxt, Nitro and TanStack Start load the file for you. Other frameworks import it:

```typescript [src/index.ts]
import { initLogger, toLoggerConfig, toMiddlewareOptions } from 'evlog'
import { evlog } from 'evlog/hono'
import config from '../evlog.config'

initLogger(toLoggerConfig(config))
app.use(evlog(toMiddlewareOptions(config)))
```

`toLoggerConfig` passes the logger options, and `toMiddlewareOptions` passes the request options. Each [framework page](https://www.evlog.dev/integrate/frameworks/overview) shows the exact lines.

## Precedence

The file applies first, and options you pass to the framework override it.

On Nuxt and Nitro, the override merges with the file key by key. The file's `drain`, `enrich` and `keep` are never overridden: they run alongside the `evlog:*` hooks, so an event reaches both. On other frameworks, a field you pass next to the file, as in `evlog({ ...toMiddlewareOptions(config), exclude: ['/health'] })`, replaces that field; it is not merged.

## Options

<table>
<thead>
  <tr>
    <th>
      Option
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Default
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        service
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        SERVICE_NAME
      </code>
      
       or <code>
        'app'
      </code>
    </td>
    
    <td>
      Service name on every event
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        environment
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        NODE_ENV
      </code>
      
       or <code>
        'development'
      </code>
    </td>
    
    <td>
      Environment name
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        enabled
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
      
       turns every call into a no-op
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pretty
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
      
       in dev
    </td>
    
    <td>
      Tree output instead of JSON
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        silent
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      No console output; events still reach the drain
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        stringify
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Print JSON strings when <code>
        pretty
      </code>
      
       is off
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        minLevel
      </code>
    </td>
    
    <td>
      <code>
        LogLevel
      </code>
    </td>
    
    <td>
      <code>
        'debug'
      </code>
    </td>
    
    <td>
      Lowest level for the <code>
        log
      </code>
      
       API. Request events use <code>
        sampling
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        sampling
      </code>
    </td>
    
    <td>
      <code>
        SamplingConfig
      </code>
    </td>
    
    <td>
      –
    </td>
    
    <td>
      Head rates and tail <code>
        keep
      </code>
      
       rules. See <a href="https://www.evlog.dev/learn/sampling">
        Sampling
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        redact
      </code>
    </td>
    
    <td>
      <code>
        boolean | RedactConfig
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
      
       in production
    </td>
    
    <td>
      See <a href="https://www.evlog.dev/learn/redaction">
        Redaction
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        drain
      </code>
    </td>
    
    <td>
      <code>
        (ctx) => void
      </code>
    </td>
    
    <td>
      –
    </td>
    
    <td>
      Where events go. See <a href="https://www.evlog.dev/integrate/adapters/overview">
        Adapters
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        plugins
      </code>
    </td>
    
    <td>
      <code>
        EvlogPlugin[]
      </code>
    </td>
    
    <td>
      –
    </td>
    
    <td>
      See <a href="https://www.evlog.dev/extend/plugins">
        Plugins
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        include
      </code>
      
       / <code>
        exclude
      </code>
    </td>
    
    <td>
      <code>
        string[]
      </code>
    </td>
    
    <td>
      –
    </td>
    
    <td>
      Route globs to log or skip
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        routes
      </code>
    </td>
    
    <td>
      <code>
        Record<string, { service }>
      </code>
    </td>
    
    <td>
      –
    </td>
    
    <td>
      Service name per route
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        enrich
      </code>
    </td>
    
    <td>
      <code>
        (ctx) => void
      </code>
    </td>
    
    <td>
      –
    </td>
    
    <td>
      Add fields before the drain
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        keep
      </code>
    </td>
    
    <td>
      <code>
        (ctx) => void
      </code>
    </td>
    
    <td>
      –
    </td>
    
    <td>
      Custom tail sampling
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        dev
      </code>
    </td>
    
    <td>
      <code>
        'evlog' | 'nitro' | 'both' | object
      </code>
    </td>
    
    <td>
      <code>
        'evlog'
      </code>
    </td>
    
    <td>
      Dev terminal output. See <a href="https://www.evlog.dev/learn/structured-errors#development-terminal-output">
        Structured errors
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        extends
      </code>
    </td>
    
    <td>
      <code>
        EvlogConfig
      </code>
    </td>
    
    <td>
      –
    </td>
    
    <td>
      Build on a shared preset. See <a href="https://www.evlog.dev/cli/config#share-settings-with-extends">
        Share settings
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        map
      </code>
      
      , <code>
        logs
      </code>
    </td>
    
    <td>
      –
    </td>
    
    <td>
      –
    </td>
    
    <td>
      CLI only. See <a href="https://www.evlog.dev/cli/config">
        evlog config
      </a>
    </td>
  </tr>
</tbody>
</table>

Nuxt also takes `console` and `transport` in `nuxt.config.ts`. See [Nuxt](https://www.evlog.dev/integrate/frameworks/nuxt).

## Inline config for scripts

For a small standalone script, passing options straight to `initLogger` in the file that starts the logger is fine:

```typescript [scripts/sync.ts]
import { initLogger } from 'evlog'

initLogger({ env: { service: 'sync-job' } })
```

---

- [Sampling](https://www.evlog.dev/learn/sampling)
- [Drain Adapters](https://www.evlog.dev/integrate/adapters/overview)


## Sitemap

See the full [sitemap](https://www.evlog.dev/sitemap.md) for all pages.
