简体   繁体   English

如何访问文件处理程序以使用 Typescript 在 deno 日志模块中运行刷新方法

[英]How can I access file handler to run flush method in deno log module using Typescript

I need to access the fileHandler object of my logger so I can flush the buffer to the file.我需要访问记录器的fileHandler对象,以便将缓冲区刷新到文件中。

This is my program:这是我的程序:

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 })

My problem is that the log message is never being written to file.我的问题是日志消息永远不会写入文件。 If I remove the last line ( app.listen() ) it Does write to the file because the process ends.如果我删除最后一行( app.listen() ),它会写入文件,因为进程结束。 But if I leave it listening process never ends so the log buffer is never flushed.但是如果我让它监听进程永远不会结束,那么日志缓冲区就永远不会被刷新。

If I interrupt the process with Ctrl-C it doesn't write it either如果我用 Ctrl-C 中断进程,它也不会写入

Documentation ( https://deno.land/std@0.75.0/log/README.md ) says I can force log flush using the flush method from FileHandler.文档( https://deno.land/std@0.75.0/log/README.md )说我可以使用 FileHandler 的刷新方法强制日志刷新。 But I don't know how to access the fileHandler object.但我不知道如何访问 fileHandler 对象。
So I've tried this:所以我试过这个:

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

And it works!它有效! but only as javascript, NOT as typescript但仅作为 javascript,而不是作为打字稿
As typescript I get this error:作为打字稿,我收到此错误:

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

Well, I found a solution.嗯,我找到了解决办法。
I just have to import the FileHandler class and cast my handler down from BaseHandler to FileHandler.我只需要导入 FileHandler 类并将我的处理程序从 BaseHandler 转换为 FileHandler。 So I added this line among the imports:所以我在导入中添加了这一行:

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

And then after creating the logger:然后在创建记录器之后:

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

Looks a little weird, I still guess there must be less quirky / more semantic solution for this.看起来有点奇怪,我仍然猜想这一定有不那么古怪/更多语义的解决方案。 But it works ok.但它工作正常。

Let us just recap with the help of Santi's answer.让我们在 Santi 的回答的帮助下回顾一下。

In my experience logs in file work fine in an ending program.根据我的经验,登录文件在结束程序中工作正常。 I mean a program which dies by itself or with Deno.exit(0).我的意思是一个程序会自行消亡或随 Deno.exit(0) 消亡。 Problem occurs in a never ending loop.问题发生在永无止境的循环中。 In this case logs don't append in their files.在这种情况下,日志不会附加到他们的文件中。 Below is how to overcome this situation :以下是如何克服这种情况:

// 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
}

Run with运行

$ deno run -A dev.js

And check the file log.txt with the following trigger并使用以下触发器检查文件 log.txt

$ curl localhost:4321

This is a very low tech, problably adding important delay to the process.这是一项非常低的技术,可能会增加该过程的重要延迟。 The next level will be to fire a time event to flush every minute or so.下一个级别将触发时间事件以每分钟左右刷新一次。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM