Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Script et charge machine

16 réponses
Avatar
Geo Kosto
Bonjour,
Quelqu'un parmi vous aurait il une idée pour réduire la consommation des
ressources lors de l'exécution d'un script ?
La problématique est la suivante, je parse 4 fichiers de log de 50 Mo sur
des DNS pour récupérer les IP toutes les heures sur des station Sun T1 105,
et je me rend compte que la consommation CPU atteint les 99% durant 3
minutes !!!
Je redoute un ralentissement de l'application qui tourne sur le serveur,
Bind 9.3.1, cad un timeout sur des requêtes lorsque le script tourne.
J'ai essaye 2 méthodes, mais la charge CPU ne se reduit pas, j'en cherche
donc une autre.

1 - Passer les fichiers dans une liste, ensuite utiliser la liste pour
compter.

@liste=("queries.log", "queries.log.0", "queries.log.1", "queries.log.2");
foreach $fichier (@liste) {
open(FIC, "< $fichier") || die "Erreur ouverture du fichier $fichier: $!";
while (<FIC>) {
push (@liste_ip, <FIC>);
};
};
close (FIC);

2 - Lire chaque fichier et traiter ligne à ligne.

my $today = time();
my $minus=$today - 3600;
my $need = strftime "%d-%b-%Y %H", localtime($minus);

@liste=("queries.log", "queries.log.0", "queries.log.1","queries.log.2");
foreach $fichier (@liste) {
open(FIC, "< $fichier") || die "Erreur ouverture du fichier $fichier: $!";
while ($line = <FIC>) {
chomp ($line);
if ($line =~ /^($need)(.*) client (.*)\#(.*) view (.*)$/)
{
$total{$3} += 1;
}
};
};
close (FIC);

Geo
Supprimer nospam dans le domaine pour obtenir mon mail.

10 réponses

1 2
Avatar
Mark Clements
Geo Kosto wrote:
Bonjour,
Quelqu'un parmi vous aurait il une idée pour réduire la consommation des
ressources lors de l'exécution d'un script ?
La problématique est la suivante, je parse 4 fichiers de log de 50 Mo sur
des DNS pour récupérer les IP toutes les heures sur des station Sun T1 105,
et je me rend compte que la consommation CPU atteint les 99% durant 3
minutes !!!
Je redoute un ralentissement de l'application qui tourne sur le serveur,
Bind 9.3.1, cad un timeout sur des requêtes lorsque le script tourne.
J'ai essaye 2 méthodes, mais la charge CPU ne se reduit pas, j'en cherche
donc une autre.

1 - Passer les fichiers dans une liste, ensuite utiliser la liste pour
compter.

@liste=("queries.log", "queries.log.0", "queries.log.1", "queries.log.2");
foreach $fichier (@liste) {
open(FIC, "< $fichier") || die "Erreur ouverture du fichier $fichier: $!";
while (<FIC>) {
push (@liste_ip, <FIC>);
};
};
close (FIC);
Ca marchera pas: tu lis de FIC deux fois chaque tour. Aussi, il vaut

mieux utiliser un hash, sinon on va chercher l'addresse DNS chaque fois
pour chaque ligne.

Le deuxième exemple est mieux.


2 - Lire chaque fichier et traiter ligne à ligne.

my $today = time();
my $minus=$today - 3600;
my $need = strftime "%d-%b-%Y %H", localtime($minus);

@liste=("queries.log", "queries.log.0", "queries.log.1","queries.log.2");
Il vaut mieux donner les noms de fichier sur le ligne de commande.


my @files = @ARGV;

foreach $fichier (@liste) {
open(FIC, "< $fichier") || die "Erreur ouverture du fichier $fichier: $!";
while ($line = <FIC>) {
chomp ($line);
if ($line =~ /^($need)(.*) client (.*)#(.*) view (.*)$/)
Le problème ici est que le regex est calculé chaque fois, mais $need se

change jamais. Mettre /o après le regex.

/^($need)(.*) client (.*)#(.*) view (.*)$/o

voir perldoc perlre pour les informations sur /o.

Aussi, utiliser

Benchmark::Timer

afin d'observer bien la difference en performance.

{
$total{$3} += 1;
}
};
};
close (FIC);



J'espere que tu peux comprendre mon franglais :)

Mark

Avatar
Sébastien Bourgasser
Geo Kosto wrote:
Bonjour,
Quelqu'un parmi vous aurait il une idée pour réduire la consommation des
ressources lors de l'exécution d'un script ?
La problématique est la suivante, je parse 4 fichiers de log de 50 Mo sur
des DNS pour récupérer les IP toutes les heures sur des station Sun T1 105,
et je me rend compte que la consommation CPU atteint les 99% durant 3
minutes !!!


Bonjour,

Ne pouvez-vous pas concevoir autrement ? Déjà vous pouvez, à la fin de
votre cycle d'analyse, stocker dans un fichier la position de la
dernière ligne. L'heure suivante il suffit de commencer l'analyse à la
position précédente.

Une autre méthode serait peut-être de faire un 'tail' sur ces 4
fichiers. L'analyse se ferait alors au fur et à mesure de vos lignes de
logs, ce qui consommera autant de CPU mais reparti sur 1 heure au lieu
de 3 minutes : pas de bloquage de la machine.

Si ces 2 solutions ne sont pas possibles, vous pouvez toujours lancer le
script en priorité basse, il n'utilisera alors que du CPU disponible.

A+

--
Séb

Avatar
Geo Kosto
Le deuxième exemple est mieux.
Donc se sera la base pour la modification.


Il vaut mieux donner les noms de fichier sur le ligne de commande.

my @files = @ARGV;
Ok pour cette methode, elle est appliqué.


/^($need)(.*) client (.*)#(.*) view (.*)$/o

voir perldoc perlre pour les informations sur /o.
Cette option permet en effet de :

1 reduire le temps de traitement.
2 consomme moins de CPU ( l'idée de ne pas recompiler la regex à chaque tour
est excellent, merci encore ) !

Benchmark::Timer
Je ne peux malheureusement pas installer de module sur mon serveur ... mais

je vais sans doute l'essayer ailleurs.

J'espere que tu peux comprendre mon franglais :)
Oui oui parfaitement ; )))


Mais je pense que traiter environ 600 000 ligne sans charge CPU tiendrait du
miracle.
Je pense peux être faire un pré traitement, un grep sur la date ainsi
j'aurais un seul fichier a parser.

Merci
Georges

"Mark Clements" a écrit dans le message
news: 43292acb$0$27408$
Geo Kosto wrote:
Bonjour,
Quelqu'un parmi vous aurait il une idée pour réduire la consommation des
ressources lors de l'exécution d'un script ?
La problématique est la suivante, je parse 4 fichiers de log de 50 Mo
sur


des DNS pour récupérer les IP toutes les heures sur des station Sun T1
105,


et je me rend compte que la consommation CPU atteint les 99% durant 3
minutes !!!
Je redoute un ralentissement de l'application qui tourne sur le serveur,
Bind 9.3.1, cad un timeout sur des requêtes lorsque le script tourne.
J'ai essaye 2 méthodes, mais la charge CPU ne se reduit pas, j'en
cherche


donc une autre.

1 - Passer les fichiers dans une liste, ensuite utiliser la liste pour
compter.

@liste=("queries.log", "queries.log.0", "queries.log.1",
"queries.log.2");


foreach $fichier (@liste) {
open(FIC, "< $fichier") || die "Erreur ouverture du fichier $fichier:
$!";


while (<FIC>) {
push (@liste_ip, <FIC>);
};
};
close (FIC);
Ca marchera pas: tu lis de FIC deux fois chaque tour. Aussi, il vaut

mieux utiliser un hash, sinon on va chercher l'addresse DNS chaque fois
pour chaque ligne.

Le deuxième exemple est mieux.


2 - Lire chaque fichier et traiter ligne à ligne.

my $today = time();
my $minus=$today - 3600;
my $need = strftime "%d-%b-%Y %H", localtime($minus);

@liste=("queries.log", "queries.log.0",
"queries.log.1","queries.log.2");


Il vaut mieux donner les noms de fichier sur le ligne de commande.

my @files = @ARGV;

foreach $fichier (@liste) {
open(FIC, "< $fichier") || die "Erreur ouverture du fichier $fichier:
$!";


while ($line = <FIC>) {
chomp ($line);
if ($line =~ /^($need)(.*) client (.*)#(.*) view (.*)$/)
Le problème ici est que le regex est calculé chaque fois, mais $need se

change jamais. Mettre /o après le regex.

/^($need)(.*) client (.*)#(.*) view (.*)$/o

voir perldoc perlre pour les informations sur /o.

Aussi, utiliser

Benchmark::Timer

afin d'observer bien la difference en performance.

{
$total{$3} += 1;
}
};
};
close (FIC);



J'espere que tu peux comprendre mon franglais :)

Mark



Avatar
Geo Kosto
"Sébastien Bourgasser" a écrit dans le
message news: 43293169$0$14584$
Geo Kosto wrote:
Bonjour,
Quelqu'un parmi vous aurait il une idée pour réduire la consommation des
ressources lors de l'exécution d'un script ?
La problématique est la suivante, je parse 4 fichiers de log de 50 Mo
sur


des DNS pour récupérer les IP toutes les heures sur des station Sun T1
105,


et je me rend compte que la consommation CPU atteint les 99% durant 3
minutes !!!


Bonjour,

Ne pouvez-vous pas concevoir autrement ? Déjà vous pouvez, à la fin de
votre cycle d'analyse, stocker dans un fichier la position de la
dernière ligne. L'heure suivante il suffit de commencer l'analyse à la
position précédente.
Oui en effet, j'avais penser faire un flag pour determiner la ligne de

debut.
Cependant, lors de la rotation des logs le fichier change de nom ( .log en
log.0, log.0 en log.1 etc ), et si les requetes sont excessives ( + 1 000
000 de requetes pour un ip en une heure !!! ), le debut de ligne se trouve
dans le 2 eme fichier de log. La manipe devient un peu tordu.
Mais je vais quand meme essayer en changeant la taille des fichiers de logs.

Une autre méthode serait peut-être de faire un 'tail' sur ces 4
fichiers. L'analyse se ferait alors au fur et à mesure de vos lignes de
logs, ce qui consommera autant de CPU mais reparti sur 1 heure au lieu
de 3 minutes : pas de bloquage de la machine.
Le parse ne doit pas exceder 5 minutes, car d'autres scripts attendent le

resultat.

Si ces 2 solutions ne sont pas possibles, vous pouvez toujours lancer le
script en priorité basse, il n'utilisera alors que du CPU disponible.
Oui, le nice fonctionne tres bien, trop bien en fait, car on depasse le

temps limite de 5 minutes pour obtenir le resultat.
Manifestement, il existe un module "BSD::Resource" qui permet de manager les
ressources, mais, et c'est pas de chance, je ne peux me permettre
d'installer de nouveaux modules sur mes serveurs ;
(

A+
Merci pour vos conseils.

--
Séb
Georges



Avatar
Mark Clements
Geo Kosto wrote:

Mais je pense que traiter environ 600 000 ligne sans charge CPU tiendrait du
miracle.
Tu pourrais "nice" le processus.


eg

Proc::NiceSleep

Je pense peux être faire un pré traitement, un grep sur la date ainsi
j'aurais un seul fichier a parser.
Probablement c'est possible de le faire avec "at" où "cron", et faire

marcher le processus à , per exemple, 02h00, quand la machine n'est pas
trop chargé.



Merci
De rien.


Mark

Avatar
Geo Kosto
Tu pourrais "nice" le processus.

eg

Proc::NiceSleep
C'est plutot cool comme module, mais je ne peux pas l'installer ( prb

secu ). J'ai utiliser le shell pour le lancer, ca marche mais c'est trop
long.

Je pense peux être faire un pré traitement, un grep sur la date ainsi
j'aurais un seul fichier a parser.
Probablement c'est possible de le faire avec "at" où "cron", et faire

marcher le processus à , per exemple, 02h00, quand la machine n'est pas
trop chargé.
Je vais te detailler le but complet de la manoeuvre.

J'ai 14 DNS CACHE, sur lesquels mes clients viennent se connecter.
Malheureusement, la mode des tryens, spyware et autres consomme un nombre
grandissant de requetes DNS ( ex : 1 000 000 pour un client sur une heure il
y a une semaine !!! ).
Donc le but du script est de parser les logs de Bind, pour ensuite alimenter
une blackliste et bloquer les abus. Cela marche en heure - 1 et dure 24h00.
C'est pourquoi j'ai besoin d'un traitement toutes les heures pour capturer
les nouvelles ip "strange".

De rien.
A mais merci bcp encore une fois.


Mark
Georges



Avatar
Paul Gaborit
À (at) Thu, 15 Sep 2005 09:32:21 +0200,
"Geo Kosto" écrivait (wrote):
La problématique est la suivante, je parse 4 fichiers de log de 50 Mo sur
des DNS pour récupérer les IP toutes les heures sur des station Sun T1 105,
et je me rend compte que la consommation CPU atteint les 99% durant 3
minutes !!!


Et alors, où est le problème ? Votre machine travaille : c'est son
rôle ;-)

Je redoute un ralentissement de l'application qui tourne sur le serveur,
Bind 9.3.1, cad un timeout sur des requêtes lorsque le script tourne.
J'ai essaye 2 méthodes, mais la charge CPU ne se reduit pas, j'en cherche
donc une autre.


Il ne sert strictement à rien de réduire la charge de la CPU. Elle est
faite pour travailler. Et si c'est à 100% c'est là où elle travaille
le mieux. Si elle n'est pas à 100%, c'est qu'elle attend à ne rien
faire !

Votre problème n'est pas qu'elle travaille beaucoup mais plutôt à quoi
elle travaille : c'est donc un problème de priorité ! Baissez la
priorité de votre script pour qu'il soit beaucoup moins prioritaire
que bind. Par exemple, en le lançant via :

nice +10 lescript.pl

Comme ça, votre CPU travaillera à 100% mais utilisera sa puissance de
calcul prioritairement pour bind (et autres processus avec priorité
normal) puis pour votre script (mais uniquement si elle n'a rien à
faire d'autre).

1 - Passer les fichiers dans une liste, ensuite utiliser la liste pour
compter.


C'est idiot parce que cela oblige votre script à stocker en mémoire le
fichier entier. S'il est très gros, c'est même impossible.


2 - Lire chaque fichier et traiter ligne à ligne.


C'est la bonne méthode.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
Mark Clements
Geo Kosto wrote:
Tu pourrais "nice" le processus.

eg

Proc::NiceSleep


C'est plutot cool comme module, mais je ne peux pas l'installer ( prb
secu ). J'ai utiliser le shell pour le lancer, ca marche mais c'est trop
long.


C'est possible d'installer les modules sans avoir root. Si ça c'est la
problème, lire

perldoc -q lib

Je vais te detailler le but complet de la manoeuvre.
J'ai 14 DNS CACHE, sur lesquels mes clients viennent se connecter.
Malheureusement, la mode des tryens, spyware et autres consomme un nombre
grandissant de requetes DNS ( ex : 1 000 000 pour un client sur une heure il
y a une semaine !!! ).
On peut pas bloquer / reparer le client? :)


Donc le but du script est de parser les logs de Bind, pour ensuite alimenter
une blackliste et bloquer les abus. Cela marche en heure - 1 et dure 24h00.
C'est pourquoi j'ai besoin d'un traitement toutes les heures pour capturer
les nouvelles ip "strange".


D'accord - je comprend maintenant.

Sébastien a dit:

Une autre méthode serait peut-être de faire un 'tail' sur ces 4 fichiers.
L'analyse se ferait alors au fur et à mesure de vos lignes de logs,
ce qui

consommera autant de CPU mais reparti sur 1 heure au lieu
de 3 minutes : pas de bloquage de la machine.


Je pense que c'est l'idée la meilleur. En fait, j'ai fait ça il y a
plusieurs années pour lire les logs d'une système d'email pour 30000
utilisateurs en temps réel, afin d'ajouter les addresses dans une base a
données d'adresses qui pouvaient envoyer les emails ailleurs
(third-party relaying). Avec File::Tail, c'est facile.

Mark


Avatar
Paul Gaborit
À (at) Thu, 15 Sep 2005 12:03:56 +0200,
"Geo Kosto" écrivait (wrote):
Je vais te detailler le but complet de la manoeuvre.
J'ai 14 DNS CACHE, sur lesquels mes clients viennent se connecter.
Malheureusement, la mode des tryens, spyware et autres consomme un nombre
grandissant de requetes DNS ( ex : 1 000 000 pour un client sur une heure il
y a une semaine !!! ).


277 requêtes DNS par seconde !!! Ça c'est du troyen !!!

Donc le but du script est de parser les logs de Bind, pour ensuite alimenter
une blackliste et bloquer les abus. Cela marche en heure - 1 et dure 24h00.
C'est pourquoi j'ai besoin d'un traitement toutes les heures pour capturer
les nouvelles ip "strange".


La fonction (de filtrage des denis de service ou DOS) que vous
décrivez me semblerait beaucoup plus facile à mettre en oeuvre a
priori par un firewall plutôt que par une analyse a posteriori des
logs de bind. De plus, plutôt que de s'apercevoir de l'abus au bout
d'une heure et de bloquer tout pendant 24h00, votre firewall ne ferait
que ralentir les clients qui abusent... en temps réel.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
Geo Kosto
C'est possible d'installer les modules sans avoir root. Si ça c'est la
problème, lire

perldoc -q lib
Le problème c'est ma cellule securité, elle refuse d'installer quoi que se

soit sans validation ,et cela prend bcp de temps ; ))))

On peut pas bloquer / reparer le client? :)
C'est le but finale,identifier, informer et bloquer si il n'y a pas de mise

a jour faite par le client sur son poste.

Je pense que c'est l'idée la meilleur. En fait, j'ai fait ça il y a
plusieurs années pour lire les logs d'une système d'email pour 30000
utilisateurs en temps réel, afin d'ajouter les addresses dans une base a
données d'adresses qui pouvaient envoyer les emails ailleurs
(third-party relaying). Avec File::Tail, c'est facile.
Je vais me pencher sur cette solution des que possible, ca semble repondre a

ma question de facon plus elegante que mes scripts ; ))

Merci bcp
Georges

1 2