You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Prisma的$on('query')日志中关联每个请求的traceId?

如何将请求级traceId关联到Prisma的SQL查询日志

你遇到的核心问题是:Prisma查询引擎运行在独立进程中,$on('query')的回调由引擎触发,无法访问Node.js主进程AsyncLocalStorage中保存的请求上下文(traceId);而Prisma扩展仅能捕获操作耗时,无法直接获取SQL详情。以下是两种可行的解决方案:


方案一:通过SQL注释传递traceId(兼容所有Prisma版本)

思路是在每个Prisma查询中注入包含traceId的SQL注释,再在$on('query')回调中从SQL语句解析出traceId。

1. 扩展Prisma客户端,注入traceId注释

修改扩展代码,为每个查询添加带traceId的SQL注释:

const traceExtension = Prisma.defineExtension((client) => {
  return client.$extends({
    query: {
      $allModels: {
        async $allOperations({ args, query }) {
          const traceId = asyncContext.getStore()?.traceId ?? 'no-trace-id';
          // 为查询添加包含traceId的注释
          const modifiedArgs = {
            ...args,
            comment: `traceId: ${traceId}`
          };
          return query(modifiedArgs);
        },
      },
    },
  });
});

// 使用扩展后的客户端
const prisma = new PrismaClient().$extends(traceExtension);

2. 在$on('query')中解析traceId

修改日志回调,从SQL语句中提取traceId:

prisma.$on('query', (e) => {
  // 从SQL注释中匹配traceId
  const traceIdMatch = e.query.match(/traceId: ([a-f0-9-]+)/);
  const traceId = traceIdMatch ? traceIdMatch[1] : 'no-trace-id';
  
  console.info(`${traceId} SQL: ${e.query}`);
  console.info(`${traceId} Params: ${e.params}`);
  console.info(`${traceId} Duration: ${e.duration}ms`);
});

方案二:使用Prisma自定义日志格式(Prisma 4.16.0+)

从Prisma 4.16.0开始,日志配置支持自定义format函数,该函数运行在主进程的异步上下文中,可直接获取AsyncLocalStorage中的traceId,无需依赖$on('query')。

初始化PrismaClient时配置自定义日志

const prisma = new PrismaClient({
  log: [
    {
      level: 'query',
      emit: 'stdout',
      format: (queryInfo) => {
        const traceId = asyncContext.getStore()?.traceId ?? 'no-trace-id';
        return `[${traceId}] SQL: ${queryInfo.query}, Params: ${queryInfo.params}, Duration: ${queryInfo.duration}ms`;
      },
    },
    // 可选:添加其他日志级别
    { level: 'info', emit: 'stdout' },
    { level: 'warn', emit: 'stdout' },
  ],
});

这种方法无需修改查询逻辑或解析SQL,直接在日志格式化阶段关联traceId,实现更简洁。


注意事项

  • 方案一需确保你的数据库支持SQL注释(PostgreSQL、MySQL、SQLite等主流数据库均支持)。
  • 方案二需要升级到Prisma 4.16.0或更高版本。

内容的提问来源于stack exchange,提问作者Champer Wu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 16:40:56