如何使用Typescript访问文件处理程序以在deno-log模块中运行flush方法



我需要访问记录器的fileHandler对象,以便将缓冲区刷新到文件中。

这是我的程序:

import * as log from "https://deno.land/std@0.75.0/log/mod.ts"
import { Application } from "https://deno.land/x/oak@v6.3.1/mod.ts";
const app   = new Application()
const port  = 7001
await log.setup({
handlers:{
file: new log.handlers.FileHandler("DEBUG",{
filename: "logger.log",
formatter: lr => {
return `${lr.datetime.toISOString()} [${lr.levelName}] ${lr.msg}`
}
})
},
loggers: {
default: {
level: "DEBUG",
handlers: ["file"]
}
}
})
const logger = log.getLogger()
logger.debug("hi there")
app.use((ctx) => {
ctx.response.body = 'Hi there'
})
console.log(`listening on port ${port}`)
app.listen({ port })

我的问题是日志消息从未被写入文件。如果我删除最后一行(app.listen(((,它会写入文件,因为进程结束。但若我离开它,监听过程永远不会结束,所以日志缓冲区永远不会被刷新。

如果我用Ctrl-C中断进程,它也不会写入

文件(https://deno.land/std@0.75.0/log/README.md(说我可以使用FileHandler中的flush方法强制日志刷新。但是我不知道如何访问fileHandler对象
所以我试过这个:

const logger = log.getLogger()
logger.debug("hi there")
logger.handlers[0].flush()

它起作用了!但仅作为javascript,而不是作为typescript
作为typescript,我得到了以下错误:

error: TS2339 [ERROR]: Property 'flush' does not exist on type 'BaseHandler'.
logger.handlers[0].flush()

好吧,我找到了一个解决方案
我只需要导入FileHandler类,并将我的处理程序从BaseHandler强制转换为FileHandler。所以我在进口商品中加了一行:

import { FileHandler } from "https://deno.land/std@0.75.0/log/handlers.ts"

然后在创建记录器后:

logger.debug("hi there")
const fileHandler = <FileHandler> logger.handlers[0]
fileHandler.flush()

看起来有点奇怪,我仍然认为一定有一个不那么古怪/更语义的解决方案。但它还可以。

让我们借助Santi的答案来回顾一下。

根据我的经验,登录文件在结束程序中工作得很好。我指的是一个程序本身或在Deno.exit(0(的情况下死亡。问题发生在一个永无止境的循环中。在这种情况下,日志不会附加到它们的文件中。以下是如何克服这种情况:

// dev.js : "I want my logs" example
import {serve} from "https://deno.land/std@0.113.0/http/server_legacy.ts";
import * as log from "https://deno.land/std@0.113.0/log/mod.ts";
// very simple setup, adapted from the official standard lib https://deno.land/std@0.113.0/log
await log.setup({
handlers: {
file: new log.handlers.FileHandler("WARNING", {
filename: "./log.txt",
formatter: "{levelName} {msg}",
}),
},
loggers: {
default: {
level: "DEBUG",
handlers: ["file"],
},
},
});
// here we go
let logger;
logger = log.getLogger();
logger.warning('started');  
const fileHandler = logger.handlers[0];
await fileHandler.flush(); // <---- the trick, need to flush ! Thanks Santi
// loop on requests
const srv = serve(`:4321`);
for await (const request of srv) {
request.respond({body: 'bonjour', status: 200});
logger.warning('hit !');
fileHandler.flush();  // <---- flush again
}

使用运行

$ deno run -A dev.js

并使用以下触发器检查文件log.txt

$ curl localhost:4321

这是一个非常低的技术,可能会给过程增加重要的延迟。下一个级别将是每隔一分钟左右触发一次刷新时间事件

最新更新