- PVSM.RU - https://www.pvsm.ru -
Иногда возникает потребность динамически отслеживать появление новых файлов в определенных папках, а также выводить содеримое лог файлов в окно броузера. Данным упрощенным примером я хочу показать как это можно сделать.
Для серверной части был выбран Node.js. Но похожий пример можно аналогично реализовать и с использованием EM на руби. В данном случае подкупила библиотека Socket.IO [1], а также несколько простых модулей для работы с файлами.
Utilities for watching file trees in node.js [2] — смысл которого отслеживать появление, удаления, а также изменения в файлах внутри указаной папки.
Пример отслеживания появления/удаления файлов внутри common.NODES_PATH и отсылка сообщения об этих событиях.
watch.createMonitor(common.NODES_PATH, function (monitor) {
monitor.on("created", function (f, stat) {
var file_name = common.removeRoot(f);
console.log(file_name + ' created');
var idx = log_files.indexOf(file_name);
if (idx < 0) {
log_files.push(file_name);
io.sockets.emit('log_files_add', [file_name]);
watchFile(file_name);
}
})
monitor.on("removed", function (f, stat) {
var file_name = common.removeRoot(f);
console.log(file_name + ' removed');
var idx = log_files.indexOf(file_name);
if (idx >= 0) {
log_files.splice(idx, 1);
io.sockets.emit('log_files_remove', [file_name]);
unwatchFile(file_name);
}
})
})
A nodejs directory walker [3] — пакет который позволяет пройтись по внутренностям указаной папки и получать события на нахождения того или иного типа файла. Или если упрощенно то просто рекурсивно пройтись по всем вложеным папкам и посомтреть что там лежит. (пример чуть ниже)
Jade — Template engine [4] — чтобы быстро набросать упрощенный UI и проверить задумку.
io.sockets.on('connection', function(socket) {
var walk = require('walk');
// receive list of log files
var walker = walk.walk(common.NODES_PATH, { followLinks: false });
walker.on('file', function(root, stat, next) {
if(/log$/.test(stat.name)) {
var file_name = common.removeRoot(root + '/' + stat.name);
var idx = log_files.indexOf(file_name);
if (idx < 0) {
log_files.push(file_name);
// send initial data portion
var tail = spawn('tail', ['-n', 20].concat(common.NODES_PATH + '/' + file_name));
tail.stdout.on('data', function(data) {
console.log('emit starting ' + file_name + ':lines' + ' with ' + data.toString('utf-8'));
io.sockets.emit(file_name + ':lines', data.toString('utf-8').split('n'));
});
watchFile(file_name);
}
}
next();
});
walker.on('end', function() {
socket.emit('log_files_add', log_files);
});
})
function watchFile(file) {
console.log('start watching: ' + file);
var tail = spawn('tail', ['-f'].concat(common.NODES_PATH + '/' + file));
watching_processes[file] = tail;
tail.stdout.on('data', function(data) {
console.log('emit ' + file + ':lines' + ' with ' + data.toString('utf-8'));
io.sockets.emit(file + ':lines', data.toString('utf-8').split('n'));
})
}
function unwatchFile(file) {
console.log('end watching: ' + file);
var process = watching_processes[file];
process.kill();
watching_processes[file] = null;
}
В common.js настройка за какой папкой следить
var NODES_PATH = pathResolver.resolve(__dirname + '/../nodes');
При появлении *.log внутри папок и подпапок они будут отображаться в окне броузера
npm install для установки пакетов
[~/Projects/autotest_node] git:master $ mkdir nodes
[~/Projects/autotest_node] git:master $ mkdir nodes/test1
[~/Projects/autotest_node] git:master $ mkdir nodes/test2
[~/Projects/autotest_node] git:master $ echo "test_message1" >> nodes/test1/first.log
[~/Projects/autotest_node] git:master $ echo "test_message1" >> nodes/test2/first.log
[~/Projects/autotest_node] git:master $ echo "test_message2" >> nodes/test2/first.log
[~/Projects/autotest_node] git:master $ echo "test_message2" >> nodes/test1/first.log
npm start для запуска сервера

https://github.com/catz/autotest_node [5]
Данный пример может быть полезен, к примеру, если вы хотите расшарить результаты выполнения автоматических тесткейсов и дать возможность следить за результатом их выполнения другим лицам. Хотя для таких задач и есть более продвинутые средства, но если вы хотите сделать простой tail -f в броузере, то подобный пример вполне может подойти.
Автор: roman_truschev
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/node-js/8171
Ссылки в тексте:
[1] Socket.IO: http://socket.io/
[2] Utilities for watching file trees in node.js: https://github.com/mikeal/watch
[3] A nodejs directory walker: https://github.com/nshah/nodejs-walker
[4] Jade — Template engine: http://jade-lang.com/
[5] https://github.com/catz/autotest_node: https://github.com/catz/autotest_node
Нажмите здесь для печати.