Refactor chunkLog function for better performance#3288
Refactor chunkLog function for better performance#3288jpty wants to merge 9 commits intojeedom:fix/chunk-logfrom
Conversation
- Truncates log files only if the file size or row number thresholds are exceeded. - Using uniqid() instead of tempnam()
|
Attention de pas casser le format et de respecter les indentations existantes sur le fichier, j'ai modifié |
|
Concernant le changement, je trouve que la fonction devient trop complex à lire... et il y a trop de if/else imbriqué Le but est la perf, ok mais tu as su mesurer? est-ce que complexifier le code et donc la maintenance vaut le gain de perf? le si vous voulez garder le principe pour raison de perf, je veux refacto pour simplifier le code mais je pense que le mieux est l'ennemi du bien |
Oui. J'ai vu. Désolé. Je me suis contenté de copier / coller depuis mon éditeur. Mon éditeur convertit toutes les tabulations en 2 espaces dès que je modifie un fichier. |
|
bon, j'ai poussé une autre version mais j'ai gardé l'idée des circuit-breaker si taille < autorisée && nbr lines < autorisée mais j'ai simplifié |
Pas vu de comments |
|
pas dans le code, sur la PR, ici plus haut |
|
Bonjour, |
Co-authored-by: jpty <1798636+jpty@users.noreply.github.com>
Co-authored-by: jpty <1798636+jpty@users.noreply.github.com>
Co-authored-by: kwizer15 <kwizer15@users.noreply.github.com>
Co-authored-by: jpty <1798636+jpty@users.noreply.github.com>
Mips2648
left a comment
There was a problem hiding this comment.
It seems my last review was not submitted or discarded
|
|
||
| clearstatcache(true, $rawPath); | ||
| $fSize = filesize($rawPath); | ||
| if ($fSize < ($maxLineLog * 50)) { // 50 characters per line |
There was a problem hiding this comment.
ce n'est pas le role de la fonction de décider de ne pas faire un chunk si le fichier est trop petit
la règle business c'est de limiter en taille et/ou en nombre de ligne; une exception sur la taille est déjà gérée par chunk()
There was a problem hiding this comment.
L'exception sur la taille gérée par chunk() est faite sans bornage de maxSizeLog:
if ($_onlyIfSizeExceeded && filesize($path) < (self::getConfig('maxSizeLog') * 1024 * 1024))
chunkLog est aussi appelé dans log::get() fonction deprecated qui ne signale pas qu'elle l'est et pourra donc générer des erreurs quand elle sera appelée mais supprimée.
| } | ||
|
|
||
| $sudo = system::getCmdSudo(); | ||
| $tmpFile = escapeshellarg(jeedom::getTmpFolder() . '/log_chunk_' . uniqid('', true)); |
There was a problem hiding this comment.
pourquoi concaténer le prefix au lieu de le passer à uniqid() ?
et pourquoi augmenter entropie? on n'est pas dans un truc critique ni à bombarder des milliers de cas par seconde
le but c'était juste d'éviter une collision évidente si 2 chunk arrive en même temps
on peut gagner du temps cpu en gardant la valeur par défaut
There was a problem hiding this comment.
Il faut déjà concaténer le /
Pour le temps cpu, 1 million d'exécution d'uniqid() = 1s avec ou sans entropie.
Je n'ai pas modifié le code.
| if ($fSize < $maxBytes) { // Check by nLines | ||
| $cmd = "wc -l " . escapeshellarg($rawPath); | ||
| $output = trim(com_shell::execute($cmd)); | ||
| $nLines = (int) explode(' ', $output)[0]; |
There was a problem hiding this comment.
je pense qu'on peut éviter l'array et l'explode avec un wc -l < file
There was a problem hiding this comment.
Je suis d'accord. Pas pensé à faire wc -l <
C'est fait dans la version actuelle.
|
|
||
| $sudo = system::getCmdSudo(); | ||
| $tmpFile = escapeshellarg(jeedom::getTmpFolder() . '/log_chunk_' . uniqid('', true)); | ||
| $shellPath = escapeshellarg(realpath($rawPath)); |
There was a problem hiding this comment.
y avait une raison d'ajouter le realpath()?
There was a problem hiding this comment.
Juste résoudre une seule fois les ../.. présents dans le rawPath avant de les passer à bash.
J'avais aussi utilisé shellPath dans mes log::add pour plus de lisibilité.
C'est supprimé dans la version actuelle.
|
|
||
| $maxSizeLog = (int)self::getConfig('maxSizeLog', 10); | ||
| $maxSizeLog = max(1, $maxSizeLog); | ||
| $maxSizeLog = max(1, min(10, $maxSizeLog)); |
There was a problem hiding this comment.
c'est un changement fonctionnel, pourquoi limiter à 10 ici? il ne faut pas faire ca
There was a problem hiding this comment.
/tmp/jeedom a une taille de 256Mo sur la VM de mon NAS.
Sur la Smart debian 12, /tmp est un tmpfs. Taille 955Mo
Dans la config maxSizeLog est du texte libre et tu as écrit plus haut que ca pourrait être 100Mo voir plus.
10 est la limite dans chunkLog avant les modifs.
|
|
||
| $fSize = filesize($rawPath); | ||
| if ($fSize === false) { | ||
| if ($fSize === false || $fSize < ($maxLineLog * 50) ) { |
There was a problem hiding this comment.
pourquoi avoir remis cette ligne?
je suis contre, ce 50 est complétement arbitraire
ca apporte quoi?
There was a problem hiding this comment.
Ca sert à ne pas perdre de temps à compter des lignes sur des petits fichiers pour dans le meilleur des cas gagner quelques octets.
com_shell::execute("wc -l ... prend 2ms sur un fichier vide.
Pour les 50, c'est déduit de mes fichiers de log.
Sur mon relevé d'hier et 21Mo de log, la moyenne du nombre de caractères par ligne est 200.
A voir pour augmenter le 50.
| if ($fSize === false || $fSize < ($maxLineLog * 50) ) { | |
| if ($fSize === false || $fSize < ($maxLineLog * 80) ) { |
Il faut aussi changer filesize en @filesize puisque la vérification de l'existence du fichier n'est plus faite au début et ainsi éviter le PHP Warning dans http.error
|
|
||
| clearstatcache(true, $rawPath); | ||
| if (file_exists($rawPath) && filesize($rawPath) > (1024 * 1024 * $maxSizeLog)) { | ||
| if (file_exists($rawPath) && filesize($rawPath) > (10 *1024 *1024)) { |
There was a problem hiding this comment.
pourquoi remettre en dur 10 au lieu d'utiliser la variable qui calcul déjà ca?
There was a problem hiding this comment.
Je trouve anormal de vider le fichier pour quelques octets en trop.
10 est l'ancienne limite de taille.
|
Bonjour, |
|
Je crois avoir commenté tous vos commentaires. A vous de commenter. Ce ne sont que des logs. Les daemons continuent d'y écrire. Il est fortement possible que le nombre de lignes soit déjà dépassé dès la fin d'une exécution réussie. |
| $maxSizeLog = max(1, min(10, $maxSizeLog)); | ||
| $maxBytes = $maxSizeLog * 1024 * 1024; | ||
|
|
||
| $fSize = filesize($rawPath); |
There was a problem hiding this comment.
Pour éviter les PHP Warning filesize(): stat failed for
| $fSize = filesize($rawPath); | |
| $fSize = @filesize($rawPath); |

Truncates log files only if the file size or row number thresholds are exceeded.
Using uniqid() instead of tempnam() because
Description
Suggested changelog entry
Related issues/external references
Fixes #
Types of changes
PR checklist