Y ahora a la parte Node del meollo. Es fácil:
Nos van a hacer falta unos cuantos módulos: express para mostrar la web, socket.io para enviar los eventos al mapa, chokidar para vigilar los cambios en el fichero del log y geoip-lite para geolocalizar las ips.
Así que creamos un directorio, lo inicializamos para node e instalamos los paquetes necesarios.
mkdir mapa cd mapa npm init npm install express socket.io chokidar geoip-lite --save
Y ahora… a picar código:
nano index.js
Lo primero cargar los módulos que necesitamos.
'use strict'; var express = require('express'); var app = express(); var serverHttp = require('http').Server(app); var io = require('socket.io')(serverHttp); var chokidar = require('chokidar'); // "Vigilante" de fichres var fs = require('fs'); var geoip = require('geoip-lite'); // Librería de localización de ips
Ahora creamos un servidor web que sirva el directorio estático «web» que contendrá un fichero index.html único y que será nuestro mapa.
app.use(express.static('web')); serverHttp.listen(65081, function() { console.log(getDateTime() + " Servidor a la escucha"); });
Y lo que será el meollo del programa:
// Inicializamos el "vigilante" de ficheros var watcher = chokidar.watch('/var/log/netlog.log', { ignored: /(^|[\/\\])\../, persistent: true }); watcher.on('change', (path, stats) => { // Si el tamaño del fichero es mayor de cero lo leemos línea a línea // si está vacio pasamos if (stats.size>0) { var lineReader = require('readline').createInterface({ input: require('fs').createReadStream(path) }); lineReader.on('line', function (line) { // Por cada línea hacemos un pequeño "parsing" y creamos una propiedad en un objeto con cada una var o=line.split(" "); var obj={}; for (var i=0; i<o.length; i++) { var tmp=o[i].split("="); if (tmp.length==2) { obj[tmp[0]]=tmp[1]; } } // Verificamos si hay información geográfica de la ip var pais=geoip.lookup(obj.SRC); if (pais!=null) { //console.log(pais); obj.lat=pais.ll[0]; obj.lng=pais.ll[1]; obj.info=pais.country; // Si la hay enviamos un mensaje "pos" vía socket.io a los clientes que tengamos conectados con los datos io.emit('pos', obj); } else { // Sino hay información lo imprimimos por consola, en el mapa no nos vale para nada. console.log("Sin info de " + obj.SRC); } }); // Cuando acabemos de procesar el ficheo lineReader.on('close', function () { // Lo borramos, igual se pierde algo por el camino pero así limpiamos, esto es un juguete eeeh fs.closeSync(fs.openSync(path, 'w')); }); } });
Nos falta una pequeña función que uso mucho para imprimir la fecha y la hora:
function getDateTime() { var date = new Date(); var hour = date.getHours(); hour = (hour < 10 ? "0" : "") + hour; var min = date.getMinutes(); min = (min < 10 ? "0" : "") + min; var sec = date.getSeconds(); sec = (sec < 10 ? "0" : "") + sec; var year = date.getFullYear(); var month = date.getMonth() + 1; month = (month < 10 ? "0" : "") + month; var day = date.getDate(); day = (day < 10 ? "0" : "") + day; return day + '/' + month + '/' + year + " " + hour + ":" + min + ":" + sec; }
Y con esto tenemos la parte de node. Nos falta la web…
Primera parte: https://blog.norsip.com/2017/09/27/mapear-accesos-al-servidor-i/