---
title: "evlog 与 LogTape：上下文和配置"
description: "比较 LogTape 的类别、应用程序所有者配置、上下文传播，以及使用 evlog 请求事件进行测试"
canonical_url: "https://evlog.zhcndoc.com/compare/logtape"
---
# evlog 与 LogTape：上下文和配置

> 比较 LogTape 的类别、应用程序所有者配置、上下文传播，以及使用 evlog 请求事件进行测试

你是在发布一个库，还是在运营一个应用程序？先从谁应该拥有日志配置开始。LogTape 允许库通过类别记录日志，而使用它的应用程序选择输出方式。evlog 提供事件累积功能，以及面向应用程序请求生命周期的集成。

LogTape 同样适用于应用程序。关键在于判断你需要的是它的类别和配置模型、evlog 累积的事件，还是为库代码和应用程序代码分别安排日志记录。请参阅 [LogTape 的库指南](https://logtape.org/manual/library)，了解由使用方拥有配置的契约。

## 比较上下文和配置

<table>
<thead>
  <tr>
    <th>
      关注点
    </th>
    
    <th>
      evlog
    </th>
    
    <th>
      LogTape
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      事件构建
    </td>
    
    <td>
      <code>
        set()
      </code>
      
       累积字段，直到调用 <code>
        emit()
      </code>
    </td>
    
    <td>
      使用消息模板和属性的结构化记录
    </td>
  </tr>
  
  <tr>
    <td>
      组织方式
    </td>
    
    <td>
      每个操作使用一个 logger，通过 <code>
        fork()
      </code>
      
       创建分支
    </td>
    
    <td>
      具有继承配置的层级类别
    </td>
  </tr>
  
  <tr>
    <td>
      显式上下文
    </td>
    
    <td>
      操作 logger 上的字段
    </td>
    
    <td>
      <code>
        logger.with()
      </code>
      
       附加可复用属性
    </td>
  </tr>
  
  <tr>
    <td>
      隐式访问
    </td>
    
    <td>
      集成中使用由 AsyncLocalStorage 支持的 <code>
        useLogger()
      </code>
    </td>
    
    <td>
      配置了上下文局部存储时使用 <code>
        withContext()
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      级别
    </td>
    
    <td>
      <code>
        trace
      </code>
      
      、<code>
        debug
      </code>
      
      、<code>
        info
      </code>
      
      、<code>
        warn
      </code>
      
      、<code>
        error
      </code>
      
      、<code>
        fatal
      </code>
    </td>
    
    <td>
      <code>
        trace
      </code>
      
      、<code>
        debug
      </code>
      
      、<code>
        info
      </code>
      
      、<code>
        warning
      </code>
      
      、<code>
        error
      </code>
      
      、<code>
        fatal
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      测试
    </td>
    
    <td>
      用于捕获和检查事件的内存 drain
    </td>
    
    <td>
      专用的捕获／断言包和 lint 规则
    </td>
  </tr>
</tbody>
</table>

LogTape 的[上下文文档](https://logtape.org/manual/contexts)区分了显式上下文和隐式上下文。隐式上下文需要兼容的运行时和已配置的 `contextLocalStorage`，例如 Node 的 `AsyncLocalStorage`。它不同于 `log.fork()`，后者会创建一个累积事件的分支。在假定隐式上下文可在浏览器中运行之前，请先检查运行时支持情况。

## 比较一次已完成的结账

下面的每个示例都会输出一条带有明确结果的业务记录。结账流程是模拟的，因此两者都不需要支付服务提供商。安装对应的库，然后使用 Node.js 24 运行文件。传入 `decline` 可测试错误路径。

LogTape 通过应用程序配置的类别记录最终结果：

```typescript [checkout-logtape.ts]
import { configure, getConsoleSink, getLogger } from '@logtape/logtape'

await configure({
  sinks: { console: getConsoleSink() },
  loggers: [
    { category: 'checkout', lowestLevel: 'info', sinks: ['console'] },
    { category: ['logtape', 'meta'], lowestLevel: 'warning', sinks: ['console'] },
  ],
})

const logger = getLogger('checkout').with({ orderId: 'order-123', amount: 2999 })
try {
  if (process.argv.includes('decline')) throw new Error('Payment declined')
  logger.info('Checkout {outcome}', { outcome: 'paid' })
} catch (error) {
  logger.error('Checkout {outcome}: {error}', { outcome: 'declined', error })
  process.exitCode = 1
}
```

evlog 会累积结果，并在 `finally` 中输出：

```typescript [checkout-evlog.ts]
import { createLogger, initLogger } from 'evlog'

initLogger({ env: { service: 'checkout' }, pretty: false })
const log = createLogger({ orderId: 'order-123', amount: 2999 })
try {
  if (process.argv.includes('decline')) throw new Error('Payment declined')
  log.set({ outcome: 'paid' })
} catch (error) {
  log.error(error instanceof Error ? error : new Error(String(error)))
  log.set({ outcome: 'declined' })
  process.exitCode = 1
} finally {
  log.emit()
}
```

这些示例比较的是上下文和输出的所有权，而不是等效的输出格式或速度。这里 LogTape 的控制台 sink 会将记录格式化后输出到终端。evlog 配置为 JSON。两个示例都不会在检查结果之前记录成功，也不会重复记录失败。

## 围绕你使用的功能规划迁移

类别特定的详细程度在 evlog 的操作模型中没有直接对应项。在将类别映射到上下文字段之前，先决定如何保留这种控制。evlog 提供 `trace` 和 `fatal`；请注意，除非设置 `sampling.rates.trace`，否则 `trace` 默认会被丢弃。

LogTape 提供单独的脱敏和测试包。evlog 会在输出前应用已配置的脱敏，并通过 `evlog/memory` 提供 `createMemoryDrain()`、`readMemoryLogs()` 和 `clearMemoryLogs()`。内存缓冲区会为你的断言提供事件，但它并不是等效的断言 DSL。请将这些工作流与 [LogTape 测试指南](https://logtape.org/manual/testing)进行比较。

迁移到 evlog 时，自定义 LogTape sink 也需要明确的交付计划。不要假定配置、刷新或重试行为可以原样迁移。

## 检查你将要发布的包

不同项目发布的测量结果使用了不同的工作负载、版本和导入方式。特别是，LogTape 的[比较表](https://logtape.org/comparison)标明了其数据所使用的历史版本。这并不能确定你当前的应用程序包相对于 evlog 的大小或吞吐量。

[性能参考](https://evlog.zhcndoc.com/reference/performance)解释了 evlog 基准测试的边界。在根据大小或速度做出选择之前，请测量你计划部署的入口点和输出设置。

当使用方拥有的配置、类别或其测试工具是你的设计核心时，请保留 LogTape。当 evlog 的[宽事件生命周期](https://evlog.zhcndoc.com/learn/wide-events)、结构化错误和框架集成能够减少应用程序中的代码时，可以考虑 evlog。对于带有序列化器和 worker 传输的 Node.js logger，请参阅 [evlog 与 Pino](https://evlog.zhcndoc.com/compare/pino)。[logger 概览](https://evlog.zhcndoc.com/reference/vs-other-loggers)介绍了其他选择，而[简单日志记录](https://evlog.zhcndoc.com/learn/simple-logging)则介绍了 evlog 的逐消息 API。

---

- [evlog 与 Pino](https://evlog.zhcndoc.com/compare/pino)
- [性能基准测试](https://evlog.zhcndoc.com/reference/performance)
- [宽事件](https://evlog.zhcndoc.com/learn/wide-events)


## Sitemap

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