@evlog/nuxthub 将你的 evlog 宽事件直接存储在 NuxtHub 数据库中。不需要外部日志服务。你的日志与数据存放在一起,并基于保留策略自动清理。
为什么选择自托管日志?
外部日志服务(如 Axiom、Datadog 等)在大规模生产环境中表现很好。但有时你可能希望:
- 零外部依赖 - 日志存储在与应用相同的数据库中
- 完全的数据所有权 - 第三方无法访问你的日志数据
- 免费层级友好 - 没有按事件计费,仅使用你现有的数据库
- 开发与预发布环境 - 无需付费即可获得完整的日志可见性
@evlog/nuxthub 可以作为一个即插即用的“数据排出器”(drain)。你现有的 evlog 设置保持不变,只需要在上方添加一层数据库支持。
安装
pnpm add @nuxthub/core @evlog/nuxthub
npm install @nuxthub/core @evlog/nuxthub
yarn add @nuxthub/core @evlog/nuxthub
bun add @nuxthub/core @evlog/nuxthub
或者使用 nuxi:
Terminal
npx nuxi module add @nuxthub/core @evlog/nuxthub
配置
将模块添加到你的 nuxt.config.ts:
nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxthub/core', '@evlog/nuxthub'],
evlog: {
retention: '7d',
},
})
即使 @evlog/nuxthub 可以自动注册缺失的模块,我们仍然建议显式安装 @nuxthub/core 并在 modules 中注册它,以获得更清晰、更可预测的配置。
仅此而已。该模块会自动完成以下操作:
- 如果尚未注册,则安装
evlog/nuxt和@nuxthub/core - 使用 NuxtHub 注册
evlog_events数据库架构 - 挂钩到
evlog:drain以将每个事件存储在数据库中 - 根据你的保留策略安排清理任务
前提条件: 你的项目必须使用 NuxtHub 并配置了数据库。
@evlog/nuxthub 使用 Drizzle ORM 与数据库交互。工作原理
请求 → evlog 宽事件 → evlog:drain 钩子 → 插入到 evlog_events 表
↓
定时任务(自动) → 删除早于保留策略的事件
evlog 发出的每个宽事件都会作为一行存储在 evlog_events 表中。drain 插件同时处理单个事件和批量事件(当与 流水线 一起使用时)。
数据库架构
evlog_events 表存储用于快速查询的索引列,以及包含所有其他字段的 data JSON 列:
| 列名 | 类型 | 描述 |
|---|---|---|
id | text | UUID 主键 |
timestamp | text | 事件时间戳 |
level | text | 日志级别(info、warn、error、debug) |
service | text | 服务名称 |
environment | text | 环境(生产、预发布等) |
method | text | HTTP 方法 |
path | text | 请求路径 |
status | integer | HTTP 状态码 |
duration_ms | integer | 请求持续时间(毫秒) |
request_id | text | 请求关联 ID |
source | text | 事件来源(服务器、客户端) |
error | text | 错误详情(JSON 字符串) |
data | text | 所有剩余事件字段(JSON) |
created_at | text | 行插入时间戳 |
索引列:timestamp、level、service、status、request_id、created_at。
方言支持
架构会根据你的 NuxtHub 数据库方言自动注册:
- SQLite(Cloudflare D1 的默认值)
- MySQL
- PostgreSQL
根据你的 NuxtHub 配置,会通过 hub:db:schema:extend 钩子自动选择正确的架构。
与外部适配器结合使用
@evlog/nuxthub 不会取代外部适配器,你可以同时使用两者。该模块注册了自己的 evlog:drain 钩子,因此你拥有的其他任何 drain 插件仍可正常工作:
server/plugins/evlog-drain.ts
import { createAxiomDrain } from 'evlog/axiom'
export default defineNitroPlugin((nitroApp) => {
// 这将与 @evlog/nuxthub 内置的排出器并行运行
nitroApp.hooks.hook('evlog:drain', createAxiomDrain())
})
下一步
- 保留与清理 - 配置保留策略和清理调度