Monadic 日志函数使用“using”关键字写入文件

Monadic log function writing to file utilizing 'using' keyword

提问人:liminor 提问时间:10/13/2023 最后编辑:liminor 更新时间:10/14/2023 访问量:55

问:

块上有一个新的上下文管理器。 悄无声息地死去,所以自然是重塑品牌和重振:)的时候了with

设置: 看着新关键字,我立即发现了一个非常棒的模式。Google Cloud Platform (GCP) 具有 ,并用于其云功能。不过,很多时候我需要先在本地运行它们,而且有些日志非常广泛。我不想通过终端窗口查看,而是希望从帮助程序文件中导入我自己的这些函数的实现,保持实现语法不变。这将允许我在本地文件夹中拥有用于调试和测试的文件。usinglog()warn()error().log

我一直在尝试像这样完成它:

// localLogger.ts

import { createWriteStream } from "fs"
import { fileURLToPath } from "url"
import { dirname, join } from "path"

export function wrapLogs(
  callee: string,
  type: "info" | "warn" | "error" = "info"
) {
  const logs: {
    when: string
    logs: string
    payload?: any
  }[] = []
  const __importFile = fileURLToPath(import.meta.url)
  const __logFileDir = dirname(__importFile)
  const __logFile = join(__logFileDir, "../logs", `${type}.log`)
  const stream = createWriteStream(__logFile, {
    flags: "a",
    encoding: "utf8",
  })
  return function (input?: string, payload: any = {}) {
    if (input) {
      const timeStamp = new Date().toISOString().split("T")[1].slice(0, -1)
      logs.push({ when: timeStamp, logs: input })
      if (Object.keys(payload).length) {
        logs[logs.length - 1].payload = payload
      }
    }
    return {
      callee,
      logs,
      done: () => {
        logs.forEach((log) => {
          stream.write(`${log.when} - [${callee}] - ${type}: ${log.logs}\n`)
          if (log.payload) {
            stream.write(`payload: ${JSON.stringify(log.payload, null, 2)}\n`)
          }
        })
        stream.on("finish", () => {
          console.log("done")
        })
        stream.end()
      },
    }
  }
}

这很接近,但没有雪茄。此实现需要在实现记录器的每个函数的末尾运行该方法 - 不太理想,因为这为遗忘错误留下了很大的空间。从理论上讲,这应该是应该进来的地方。.done()using

// implementer.ts
import { wrapLogs } from './localLogger.ts'

function myCloudFuntion(){
 const log = wrapLogs('myCloudFunction')
 // does something and then logs
 const data = { payload: 'relevant data' }
 log("some useful log here", data)
 // more stuff
 log().done() // <- this part i would like to do without
 return
}

因此,在理想世界中,我想这样定义记录器:

// localLogger.ts

...
// last return of the wrapLogs definition

    return {
      callee,
      logs,
      [Symbol.dispose]() {
        logs.forEach((log) => {
          stream.write(`${log.when} - [${callee}] - ${type}: ${log.logs}\n`)
          if (log.payload) {
            stream.write(`payload: ${JSON.stringify(log.payload, null, 2)}\n`)
          }
        })
        stream.on("finish", () => {
          console.log("done")
        })
        stream.end()
      },
    }

在实现文件中:

// implementer.ts

function myCloudFunction(){
  using log = wrapLogs("myCloudFunction")
  //...
  log("some message", data)
  return  // <- no more log().done()
}

不幸的是,这会导致各种问题。

欢迎任何帮助。

这些是我进入单子土地的第一步,所以要温柔:)using

编辑:我创建了一个存储库,它应该使设置不那么耗时 https://github.com/kolchurinvv/logger-replacements

javascript typescript google-cloud-platform monads 使用

评论

0赞 Nick Parsons 10/13/2023
您遇到了哪些类型的问题?
0赞 jcalz 10/13/2023
如果您能提供一个最小的可重现示例,该示例可以粘贴到独立 IDE 中的单个文件中,而无需依赖 TS 外部的库(例如,适合 TypeScript Playground 的库),您可能会在这里获得更多帮助。“最小”还意味着我们可能不需要查看时间戳操作的内部结构、日志文件位置等......任何你没有问的东西都应该被删除,这样就不会分散注意力。现在,由于开始所需的设置时间/精力,我不倾向于对此进行过多的涉足。
0赞 liminor 10/14/2023
我听到了。我在想,通过提供更多的背景信息会有所帮助。本着这种精神,我创建了一个存储库,它应该使设置过程不那么耗时。将其添加到问题中

答: 暂无答案