简体   繁体   English

如何将Winston限制为每个日志文件仅1个文件描述符

[英]How to limit Winston to only 1 file descriptor per log file

I'm currently using Winston in my project to log to a handful of log files - 4 different files to be exact. 我目前在我的项目中使用Winston来登录少数日志文件-确切地说是4个不同的文件。 Each file is leveraged by a large number of classes to group specific functionality - a pretty typical use case for an application. 每个文件都被大量的类用来组合特定功能-这是应用程序的一种非常典型的用例。 My problem is that as of now, Winston is opening up a separate file descriptor for the same log file for every single class, every single time the class is even used. 我的问题是,到目前为止,Winston甚至在每次使用该类时,都为每个单个类为同一日志文件打开一个单独的文件描述符。 I'm running on the most recent version of Amazon Linux and my baseline is 470 file descriptors in use. 我正在最新版本的Amazon Linux上运行,基准是使用了470个文件描述符。 As soon as I start up my application, I jump to over 1700. From there, thousands of additional file descriptors are used as the app runs and instantiates new classes that utilize the loggers. 一旦启动应用程序,我便跳到1700多个。从那里开始,在应用程序运行并实例化利用记录器的新类时,会使用成千上万的其他文件描述符。 All our logs are pulled in using Winston's container (see code below). 我们所有的日志都是使用Winston的容器提取的(请参见下面的代码)。

Update: I just created a barebones app with ONLY winston, and I used it to create 1 parent logger and thousands upon thousands of child loggers. 更新:我只是用Winston创建了一个准系统应用程序,并用它来创建1个父记录器和成千上万个子记录器。 I'm also using the child loggers to log a message when they're created. 我还使用子记录器在创建消息时记录一条消息。 This whole process only takes 1 file descriptor on the OS, so clearly something we're doing in our app (it's far more complex) is causing Winston to open a separate FD...but that's not the default behavior. 整个过程在OS上仅需要1个文件描述符,因此很明显,我们在应用程序中正在做的事情(要复杂得多)导致Winston打开单独的FD ...但这不是默认行为。 Has anyone seen this before? 谁看过这个吗? I am working on adding more and more to the test app just to see if I can find the point when it actually starts using more file descriptors. 我正在努力将越来越多的东西添加到测试应用程序中,只是为了看看我是否可以真正开始使用更多的文件描述符。

We have the method to retrieve a logger set up to be static, and so I'm starting to think that is the issue. 我们有一种方法可以检索设置为静态的记录器,因此我开始认为这是问题所在。

This only means that the class doesn't have to be instantiated to run that method. 这仅意味着不必实例化该类即可运行该方法。 It has no bearing on the lifetime of the return value. 它与返回值的生存期无关。

The way I handle this is with a simple script where I export the Winston instance. 我的处理方式是使用一个简单的脚本导出Winston实例。 For example: 例如:

const winston = require('winston');

const applog = winston.createLogger({
  transports: [
    new (winston.transports.Console)({ 
      level: 'debug',
      handleExceptions: true
    })
  ],
  format: winston.format.simple()
});

module.exports = applog;

Then, in any module where I want the logger, something like this: 然后,在需要记录器的任何模块中,如下所示:

const applog = require('./lib/applog');

Node.js caches the result of require() , so whatever you export is guaranteed to be the exact same instance for anywhere that the module is required. Node.js缓存了require()的结果,因此,无论您导出的内容是什么,对于任何需要该模块的地方,都可以保证是完全相同的实例

You can adapt this method to your class and static method if you'd like. 您可以根据需要将此方法适应您的类和静态方法。 Just do all of your Winston setup outside of the class (in that same file), and have the static method return the instance. 只需在类之外(在同一文件中)进行所有Winston设置,并让静态方法返回实例。

Well now I just feel stupid. 好吧,现在我觉得自己很蠢。 The issue had nothing to do with child loggers at all, creating a child logger definitely does not open a new file descriptor. 这个问题根本与子记录器无关,创建子记录器肯定不会打开新的文件描述符。 The issue was that we were always passing logger options to our loggers.get(id, options) method, rather than just passing the id with no options if the logger already existed. 问题在于,我们总是将记录器选项传递给loggers.get(id,options)方法,而不是仅传递没有选项的id(如果记录器已经存在)。 The fix took all of a few lines of code and now we only have 1 file descriptor open per log file. 该修复程序花费了几行代码,现在每个日志文件只有1个文件描述符打开。 D'oh! 天哪!

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

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