Augustin82 / omegawatt

0 stars 0 forks source link

Parser les logs du serveur FTP et catégoriser les fichiers #22

Open Augustin82 opened 3 years ago

Augustin82 commented 3 years ago

À compléter

pf26 commented 3 years ago

By default vsftpd has a very chatty log: (tiré d'internet, à vérifier) Mon Mar 23 06:00:00 2020 [pid 11111] CONNECT: Client "1.1.1.1" Mon Mar 23 06:00:00 2020 [pid 11111] [ftp] OK LOGIN: Client "1.1.1.1", anon password "blablabla" Mon Mar 23 06:00:00 2020 [pid 11111] [ftp] FAIL DOWNLOAD: Client "1.1.1.1", "/file1", 0.00Kbyte/sec Mon Mar 23 06:00:00 2020 [pid 11111] [ftp] OK DOWNLOAD: Client "1.1.1.1", "/file2", 17500 bytes, 203.15Kbyte/sec

Pour les lignes contenant OK DOWNLOAD, lire le path/file entre les 2 premières virgules. Si le path contient _done ou _error, ne rien faire (possible en cas de déplacement manuel de fichiers sur le serveur FTP) Sinon, si le path contient EXPORT_SOCOMEC -> parser SOCOMEC Sinon, si l'extension fichier est .tsv -> parser OMEGAWATT Sinon, si l'extension fichier est .cmd -> envoi de commande à InfluxDb par le script déjà fait (issue #21) Sinon, ne rien faire

Augustin82 commented 3 years ago

OK pour les règles.

Il me semble qu'il y a un problème à résoudre au niveau du fonctionnement concret du parsing. En effet, on ne peut pas vraiment parser "la dernière ligne" du fichier de log, ni "les dernières lignes depuis la dernière fois". Cela implique que notre poller va devoir parser l'intégralité du fichier de logs à chaque fois, et que cela va prendre de plus en plus de temps. Ce temps sera peut-être négligeable, je ne suis pas en mesure de me prononcer. De même, est-ce que ce temps entraînera des erreurs (parce que le fichier sera modifié pendant la lecture par le poller) ou pas, je n'en sais rien.

Une solution de contournement, qui externalise une partie de la logique mais permet de contourner tout un tas de problèmes est d'imposer au serveur FTP utilisé de ne mettre que des fichiers "terminés" dans le répertoire qui sera surveillé par le poller. Typiquement, le serveur télécharge chaque fichier sous un nom du genre mon-fichier.csv.incomplete et, une fois que c'est terminé, le déplace (opération qui est virtuellement instantanée sur les systèmes de fichiers).

On pourrait aussi imaginer de surveiller toute l'arborescence des fichiers uploadés et, quand on en détecte un nouveau, de lancer un nouveau processus de surveillance sur celui-là en particulier, attendre qu'il ne soit plus modifié pendant X secondes, et en déduire que l'upload est terminé. Mais c'est une déduction faillible, et ça ne garantit pas que l'upload a été complété correctement.

Il y a peut-être d'autres solutions à envisager, comme d'utiliser un serveur FTP avec des hooks (comme tu l'avais évoqué initialement).

pf26 commented 3 years ago

Je pensais à une solution où le fichier log serait reçu comme un stream de caractères, permettant de lire ligne par ligne. Je ne sais pas si c'est possible. Sinon, il me semble possible d'utiliser une notification de modification du fichier log (comme fs.watch ? - https://thisdavej.com/how-to-watch-for-files-changes-in-node-js/ ) et peut-être stocker la position ( où on en était dans le fichier ? - When you use the fs.read function, there is a parameter called position, that works as the seek position - https://stackoverflow.com/questions/17855186/seek-equivalent-in-javascript-node-js) Pour lire une ligne, peut-être s'inspirer de https://stackoverflow.com/questions/6156501/read-a-file-one-line-at-a-time-in-node-js

Ensuite, pour éviter les gros fichiers log, je propose que tous les 4 jours, le parser de log archive le log en cours et clear (il y a un petit risque de conflit à gérer si vsftpd reçoit en même tps, je propose de juste archiver le fichier, l'effacer et s'il y a un retour en erreur d'accès lors de l'effacement, de relire et traiter le log, puis retenter d'archiver /effacer)