log4js 生成大量的文件句柄,且沒有釋放,too many open file,最終宕機


問題:使用node里的log4js,生成了大量的文件句柄且沒有釋放(too many open file),最總導致服務宕機。

需求:按用戶和日期級別生成多個log文件。一天有n個用戶請求,生成n份log。

最初的實現:log4js配置,type:file

const app = express()
const log4js = require('log4js')
app.post('/userTest', function(req, res) {
  let expressData = []
  let reqData
  req.on('data', function(data){
    expressData.push(data)    
  })    
  req.on('end', function() {
    reqData = Json.parse(Buffer.concat(expressData).toString())
  })
  // 配置log4js
  log4js.configure({
        appenders: {
            console: {
                type: 'console' }, userLog: { type: 'File', filename: `logs/${userId}_${(new Date()).format('yyyyMMdd')}.log`, maxLogSize: 1024 * 1024 * 1024, //單個log最大size 1GB alwaysIncludePattern: true, layout: { type: 'pattern', pattern: '%d %p %c %X{userId} %m%n' } } }, categories: { default: {appenders: ['console','userLog'], level: 'info'} }, replaceConsole: true })
  let logger = log4js.getLogger('userLog')
  logger.addContext(
'userId', reqData.userId)
  // 記錄log   
  logger.info('just a test')
})

每當執行到log4js.configure時,會生成一個文件句柄,且不會釋放。

看起來寫的很爛,當初自己為什么不把type設成multiFile?

改成multiFile,如下

const app = express()
const log4js = require('log4js')
// 配置log4js
log4js.configure({
    appenders: {
        console: {
            type: 'console'
          },
          multi: {
            type: 'multiFile', 
            base: 'logs/', 
            property: 'label', 
            extension: '.log',      
            maxLogSize: 1024*1024*1024 // backup 1GB
          }
        },
    categories: { default: { appenders: ['console','multi'], level: 'info'} }
})
app.post('/userTest', function(req, res) {
  let expressData = []
  let reqData
  req.on('data', function(data){
    expressData.push(data)    
  })    
  req.on('end', function() {
    reqData = Json.parse(Buffer.concat(expressData).toString())
  })
  let logger =log4js.getLogger(`default`)
            logger.addContext('label',`${reqData.userId}_${new Date().format('yyyyMMdd')}`)
  // 記錄log   
  logger.info('just a test') 
})

但是,還是會產生文件句柄,長時間之后還是會宕機。

so。。。上github 啊

how to close multiFile appender file handle #691

https://github.com/log4js-node/log4js-node/issues/691

added timeout support to multiFile appender

https://github.com/log4js-node/log4js-node/commit/13909b6fe39e75f5b83e3019bde685bd19af8a1e

 

原來只要在配置里面加上timeout,即可

log4js.configure({
        appenders: {
            console: {
                type: 'console'
            },
            multi: {
                type: 'multiFile', 
                base: 'log/', 
                property: 'label', 
                extension: '.log', 
                timeout:20, // optional activity timeout in ms after which the file will be closed.
                maxLogSize: 100*1024*1024 // Backup every 100mb
            }
        },
        categories: { default: { appenders: ['console','multi'], level: loggerLevel } }
    })

另外一點需要注意,這個bug是 3 May 2018 修復的,有些版本不支持

所以用最新的吧!!! 

生成的文件句柄可以用 ProcessExplorer.exe 查看, 可參考: https://www.cnblogs.com/blplusyan/p/12108612.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM