---
title: Presets
description: 现成的 dev、prod、json 日志默认值
---

用 `preset` 一行设好环境默认。显式 `config` / `startup` 字段永远覆盖 preset。

```ts
import { Elysia } from 'elysia'
import { createElogs } from '@eastgold15/elogs'

const app = new Elysia().use(
  createElogs({
    preset: 'prod',
    config: {
      service: 'api',
      logFilePath: './logs/app.log',
    },
  })
)
```

## 可用 preset

| Preset | pino.prettyPrint | showContextTree | showStartupMessage | startupMessageFormat | autoRedact | requestId |
| --- | --- | --- | --- | --- | --- | --- |
| `dev` | `true` | `true` | `true` | `"banner"` | — | — |
| `prod` | `false` | `false` | `false` | `"banner"` | `true` | `true` |
| `json` | `false` | `false` | `false` | `"banner"` | — | — |

> 表里 `—` 表示 preset 没设,会沿用 Elogs 的默认(`false` / `undefined`)。

`json` 是给日志聚合器(Datadog、Loki、Elasticsearch)的最小配置 —— 关掉所有装饰性输出,JSON 行就是唯一 payload。下游需要按行解析 JSON、又不需要人类可读格式时用它。

## 覆盖示例

preset 给出基线,显式 `config` / `startup` 字段覆盖单个键:

```ts
import { createElogs } from '@eastgold15/elogs'

createElogs({
  preset: 'prod',
  config: {
    autoRedact: false,        // 覆盖 prod 的 true
    showContextTree: true,    // 单独开
  },
  startup: {
    show: true,               // 覆盖 prod 的 false
  },
})
```

## 程序化解析

`resolveOptions(options)` 是 Elogs 内部用的 merge 函数 —— 拿到 preset 默认值后,把显式 `config` 字段 shallow-merge 上去(对 `pino` / `logFilter` / `logRotation` / `timestamp` 做嵌套深合并)。想先看解析结果再传给 `createElogs` 时用:

```ts
import { resolveOptions } from '@eastgold15/elogs'

const options = resolveOptions({ preset: 'dev', config: { service: 'api' } })
// options.config.service === 'api'
// options.config.showStartupMessage === true (来自 dev preset)
```

行为跟直接传 `createElogs()` 完全一致 —— `resolveOptions` 已经在 `createElogs` 内部被调用过一次,显式调一次只是为了"先看一眼"。

## 自定义 preset

`registerPreset(name, defaults)` 在进程级注册一个 preset,跟内置 `dev` / `prod` / `json` 一样被 `resolveOptions` 查表。适合在 monorepo 里把"staging / edge / canary"等环境的默认值抽到一处,而不是每个项目复制粘贴 12 行 config。

```ts
import { registerPreset } from '@eastgold15/elogs'

registerPreset('staging', {
  pino: { prettyPrint: true },
  showContextTree: true,
  requestId: true,
  autoRedact: true,
  useColors: true,
})

const app = new Elysia().use(createElogs({ preset: 'staging' }))
```

### 规则

- 重复注册同名 preset 抛 `Error("createElogs: preset \"<name>\" already registered")` —— 防止 typo 静默覆盖。
- `name` 必须是非空字符串。
- `defaults` 的 schema 跟 `ElogsConfig` 完全一致,**不**做轻量校验(`resolveOptions` 阶段统一管 `logRotation` 之类)。
- 注册时机:模块加载时一次性注册,放**自己项目的初始化入口**(比如 `src/logging.ts`)。**不要**在请求处理函数里注册 —— 重复抛错会让第一个请求 500。

### 调试用 API

```ts
import { listPresets, getPresetDefaults } from '@eastgold15/elogs'

console.log(listPresets())
// ['dev', 'prod', 'json', 'staging']

console.log(getPresetDefaults('staging'))
// { pino: { prettyPrint: true }, showContextTree: true, requestId: true, ... }
```

### 测试重置

单测之间清掉注册表用 `__resetPresetRegistry()`(注意:会**连同**内置 `dev` / `prod` / `json` 一起清掉,生产代码绝不能调):

```ts
import { __resetPresetRegistry } from '@eastgold15/elogs'

afterEach(() => {
  __resetPresetRegistry()
})
```

### TypeScript 提示

`preset` 字段的提示仍是 `'dev' | 'prod' | 'json'`,但运行时接受任意字符串。IDE 自动补全给内置,用户 preset 用 `as` 断言或 `satisfies` 收口:

```ts
createElogs({ preset: 'staging' as 'dev' | 'prod' | 'json' | 'staging' })
```

## 相关 API

- [`registerPreset`](/api/exports#registerpreset) — 注册自定义 preset
- [`getPresetDefaults`](/api/exports#getpresetdefaults) — 查表
- [`listPresets`](/api/exports#listpresets) — 列出当前已注册名
- [`resolveOptions`](/api/exports#resolveoptions) — 手动跑 merge
- [`__resetPresetRegistry`](/api/exports#resetpresetregistry) — 测试重置
- [`LogPreset`](/api/types#logpreset) / [`PresetConfig`](/api/types#presetconfig) — 类型
