javascript - fs.watch() 在 Node v13 中是否损坏或者我做错了什么?

标签 javascript node.js express fs winston

我一直在尝试设置一个文件观察器来检测何时将新数据添加到文件中。一般顺序是 1.) 客户端连接到服务器。 2.) 服务器记录到文件。 3.) fs.watch() 检测到文件已更改并运行一个函数,在本例中是一个简单的 console.log('New log entry')

一切似乎都正常,除了 fs.watch() 无法检测到新消息何时添加到日志文件中。但是,如果我单击 VScode 中的日志文件,它似乎会触发它。这是较新版本的 Node 中的错误还是我在这里做错了什么?

我意识到我可以使用fs.watchFile(),但我希望避免轮询的开销...

// src/index.js
const path = require('path');
const express = require('express');
const app = express();
const server = require('http').createServer(app);
const io = require('socket.io')(server);
const logger = require('./logger');
const fs = require('fs');

fs.watch('./logs/combined.log', (event) => {
  if (event === 'change') {
    console.log('New log entry');
  }
});

app.use(express.static(path.join(__dirname, '../public')));
app.get('/', function(req, res, next) {
  res.sendFile(path.join(__dirname, '../public', 'index.html'));
});

io.on('connection', function(socket) {
  logger.info('a user connected');
});

const PORT = process.env.PORT || 8888;

server.listen(PORT, () => {
  logger.info(`Listening at http://localhost:${port}`);
});

-

// src/logger.js
const winston = require('winston');

const logger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  transports: [
    new winston.transports.File({ filename: 'logs/combined.log' })
  ]
});

module.exports = logger

-

// public/index.html
<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io.connect('http://localhost:8888');
</script>

-

// simplified test
const logger = require('./logger');
const fs = require('fs');

fs.watch('./logs/combined.log', event => {
  if (event === 'change') {
    console.log('log file has updated');
  }
});

function intervalFunc() {
  logger.info('new log message');
}
setInterval(intervalFunc, 5000);

最佳答案

更新:

所以它looks like Winston comes with built-in listeners 。这些监听器的作用类似于文件观察器,并允许您 Hook 某些事件。您可以 Hook 的事件之一称为“数据” - 这可以让您监听数据何时写入文件,并运行回调函数。

这提供了与 file.watch 类似的行为.

它们允许您监听以下事件:

  • 关闭
  • 数据
  • 结束
  • 错误
  • 可读

我在 Windows 上对此进行了测试,它运行良好。

这是我正在使用的测试文件:

const winston = require('winston');

const { createLogger, format: { json }, transports: { File } } = winston;

const logger = createLogger({
  level: 'info',
  format: json(),
  transports: [
    new File({ filename: './log.txt' })
  ],  
});

/**
 * Added a built in Winston listener
 */
logger.addListener('data', chunk => {
    console.log('\r\n[winston listener] we have logged some data:\n', chunk)
})

/**
 * Their documentation seems to use the `.on` method.
 * 
 * This appears to provide the same type of behavior that `.addListener` does.
 * 
 * I'm not sure which is best, or recommended, `.addListener` or `.on` - you
 * may want to dig deeper into that.
 */
logger.on('data', chunk => {
    console.log('\r\n[winston on "data"] we have logged some data:\n', chunk);
});

setInterval(() => {
  logger.info('new log message');
}, 5000);
<小时/>

所以我一直在考虑这个问题,起初我相信这是因为 Winston 使用写入流来更新文件..

然后我继续尝试复制您的问题,但无法重现它。

每次更新日志文件时,都会向控制台写入一条消息(意味着 fs.watch 正在工作。

您使用的是 Windows 吗?您使用的是哪个版本的 Node?

这是我正在使用的测试文件:

const winston = require('winston');
const fs = require('fs');

const { createLogger, format: { json }, transports: { File } } = winston;

const logger = createLogger({
  level: 'info',
  format: json(),
  transports: [
    new File({ filename: './log.txt' })
  ]
});

fs.watch('./log.txt', event => { 
  if (event === 'change') {
    console.log('log file has updated');
  }
});

setInterval(() => {
  logger.info('new log message');
}, 5000);

关于javascript - fs.watch() 在 Node v13 中是否损坏或者我做错了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60386568/

相关文章:

javascript - 创建一个自动 slider

javascript - 将 CSS 规则应用于所有 future 元素

json - 如何检查值是否存在作为 hasOwnProperty JSON NodeJs

node.js - 如何让5个API获取请求并将数据传递到一个 View ?

javascript - jQuery 停止 ajax 异步运行

javascript - 如何订阅事件流 - 服务器端

node.js - 如何创建 Facebook 的应用程序以将叠加层添加到个人资料图片?

node.js - Angular 2无法连接到服务器

Javascript 代码未在 PUG/Jade 文件上运行

node.js - Express静态服务器-设置dir文件夹