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

如何使用using关键字实现自动写入文件的单子式日志函数

GCP云函数本地日志自动写入实现方案(基于using上下文管理器)

需求背景

  • 为GCP云函数实现本地日志功能,将日志写入.log文件用于本地调试
  • 现有wrapLogs函数需手动调用done()完成日志写入,易因遗忘导致日志丢失,需通过using上下文管理器+Symbol.dispose实现自动写入

解决方案实现

1. 实现支持自动释放的本地日志类

利用Symbol.dispose钩子,在代码块结束时自动触发日志写入:

import fs from 'fs';
import path from 'path';

class LocalLogger {
  #logEntries = [];
  #logFilePath;

  constructor(logFileName = 'cloud-function.log') {
    this.#logFilePath = path.resolve(process.cwd(), logFileName);
    // 初始化日志文件(不存在则创建)
    if (!fs.existsSync(this.#logFilePath)) {
      fs.writeFileSync(this.#logFilePath, '', 'utf8');
    }
  }

  // 模拟GCP日志info方法
  info(message, metadata = {}) {
    this.#logEntries.push({
      level: 'INFO',
      timestamp: new Date().toISOString(),
      message,
      metadata
    });
  }

  // 模拟GCP日志error方法
  error(message, metadata = {}) {
    this.#logEntries.push({
      level: 'ERROR',
      timestamp: new Date().toISOString(),
      message,
      metadata
    });
  }

  // 自动触发的释放钩子,完成日志写入
  [Symbol.dispose]() {
    if (this.#logEntries.length === 0) return;
    // 将缓存的日志条目追加写入文件
    const logContent = this.#logEntries.map(entry => JSON.stringify(entry)).join('\n') + '\n';
    fs.appendFileSync(this.#logFilePath, logContent, 'utf8');
    this.#logEntries = [];
  }
}

2. 在云函数中使用using关键字

代码块执行完毕(无论正常结束还是异常抛出),会自动调用Symbol.dispose完成日志写入:

// 云函数入口示例
export const myCloudFunction = async (req, res) => {
  using logger = new LocalLogger();

  try {
    logger.info('云函数启动', { path: req.path, method: req.method });
    // 业务逻辑代码
    const result = await someBusinessLogic();
    logger.info('业务执行成功', { result });
    res.status(200).send('Success');
  } catch (err) {
    logger.error('业务执行失败', { error: err.message, stack: err.stack });
    res.status(500).send('Error');
  }
};

3. 异步写入优化(针对大日志量场景)

如果日志量较大,建议使用异步写入,此时需替换为Symbol.asyncDispose并配合await using:

// 修改日志类的释放钩子
[Symbol.asyncDispose]() {
  if (this.#logEntries.length === 0) return Promise.resolve();
  const logContent = this.#logEntries.map(entry => JSON.stringify(entry)).join('\n') + '\n';
  return fs.promises.appendFile(this.#logFilePath, logContent, 'utf8')
    .then(() => {
      this.#logEntries = [];
    });
}

// 云函数中使用方式
export const myCloudFunction = async (req, res) => {
  await using logger = new LocalLogger();
  // 后续业务逻辑不变
};

关键注意事项

  • 确保Node.js版本支持using语法(Node.js 18.11+ 或 16.17+),低版本可通过Babel转译兼容
  • 日志类封装了GCP日志常用方法,原有业务代码的日志调用逻辑无需修改

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 20:57:47