我一直试图设置一个文件监视程序来检测何时将新数据添加到文件中。一般顺序为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 => {
console.log(event);
if (event === 'change') {
console.log('log file has updated');
}
});
function intervalFunc() {
logger.info('new log message');
}
setInterval(intervalFunc, 5000);
fs.watch的节点文档有一个完整的Caveats部分,该部分从一开始就说明:
fs.watch API在各个平台上并非100%一致,在某些情况下不可用。
您应该阅读该部分以获得更多信息,但是如果无法使fs.watchfile可靠地工作,您可能最终不得不使用fs.watch
。
[更新]
Caveats部分的Filename Argument小节也指出了这一点:
即使在受支持的平台上,也不总是保证
filename
是提供。因此,请勿假设filename
参数始终为提供给回调函数,并且如果为null
,则具有一些后备逻辑。
由于您不需要使用filename
参数(而且您已经知道文件名了,所以您的回调不应该测试真实的filename
参数。