Dans un script de HealthCheck l'utilisateur peut tester si un ou plusieurs processus sont actifs sur le serveur.
Voici un exemple adapté du code :
Cette version scan /proc/*/cmdline à la recherche des logiciels demandés par l'user.
<?php
$softwareName = array( "syncthing", "top" ); /* add name for check if these softwares names is active running */
$chkSoftIsLunch=true;
if(is_array($softwareName)) {
foreach($softwareName as $name){
$pids=null;
exec("pidof ".$name, $pids);
if(empty($pids)) {
$chkSoftIsLunch=false;
}
}
}
if($chkSoftIsLunch){
echo "processus actif";
}else{
echo "processus PAS actif";
}
?>
Néanmoins l'activation de ce block de code double voir triple la durée d’exécution du script PHP. (ce qui me parait beaucoup)
Auriez-vous d'autre solution plus rapide et moins énergivore que d’exécuter pidof via exec() ? 😀
Dans le cas ci-présent, chaque itération de la boucle foreach semble prendre a elle seule entre 20ms et 30ms (sur ARM, sur X64 c'est divisé par 5).
EDIT : nouvelle édition du code :
Cette version parse /proc///cmdline une fois par nom de logiciel. La fonction est optimisée au max.
$chkSoftwareName = array( "software1", "software2" ); /* uncomment and edit for check if these softwares names are running */
if(is_array($chkSoftwareName)) {
if(!checkIfSoftwareIsRunning ($chkSoftwareName)){
echo "un des logiciels ne fonctionne pas !";
}
}
function checkIfSoftwareIsRunning ($chkSoftwareName){
$path="/proc/";
$subfile="cmdline";
foreach($chkSoftwareName as $softName){
$check=false;
$listFiles = scandir($path, 1);
$lenght = count($listFiles);
foreach ($listFiles as $filename) {
if(!$check && is_dir($path.$filename)){
if(is_file($path.$filename.'/'.$subfile)){
if ($myFile = @fopen($path.$filename."/".$subfile, "r")) {
while (($buffer = fgets($myFile)) !== false) {
if(preg_match("/".$softName."/i", $buffer)){
$check=true;
}
}
fclose($myFile);
}
}
}
$lenght--;
if ($lenght<=0 && $check==false) { return false; } // last tab
}
}
return true;
}
Cette deuxième implémentation parse une seule fois /proc/*/cmdline mais est quand même plus lente que la version juste ci-haut. La fonction peut encore être un peu optimisée.
function checkIfSoftwareIsRunning2($chkSoftwareName){
$path="/proc/";
$subfile="cmdline";
foreach($chkSoftwareName as $softName){
$check[$softName]=false;
}
$listFiles = scandir($path, 1);
foreach ($listFiles as $filename) {
if(is_dir($path.$filename)){
if(is_file($path.$filename.'/'.$subfile)){
if ($myFile = @fopen($path.$filename."/".$subfile, "r")) {
while (($buffer = fgets($myFile)) !== false) {
foreach($chkSoftwareName as $softName){
if(preg_match("/".$softName."/i", $buffer, $match[0])){
$check[$softName]=true;
}
}
}
fclose($myFile);
}
}
}
}
foreach($check as $k=>$v){
if(!$v){ return false; }
}
return true;
}
# man pidof
Posté par lolop (site web personnel) . Évalué à 3.
Il semble que tu puisses ne l'appeler qu'une seule fois avec tous les programmes que tu veux tester.
Votez les 30 juin et 7 juillet, en connaissance de cause. http://www.pointal.net/VotesDeputesRN
[^] # Re: man pidof
Posté par voxdemonix . Évalué à 1. Dernière modification le 17 mars 2019 à 20:24.
Merci, update faites 😉
Le type de commande :
Puis comparé la taille du nombre qui sort de la commande avec le nombre de logiciels recherché.
Par contre même en ne recherchant qu'un seul software, l'utilisation de pidof fait tripler le temps de chargement du script sur x64 (passe de 5ms a 17-25ms) et entre 3x et 4x sur ARM (de 8-20ms à 45-65ms).
[^] # Re: man pidof
Posté par Cyril Brulebois (site web personnel) . Évalué à 3.
Si tu en es à compter les millisecondes, pourquoi forker ? S'il n'y a pas de wrapper PHP pour
libproc
, consulter/proc
directement depuis PHP pourrait améliorer les choses, non ?Debian Consultant @ DEBAMAX
[^] # Re: man pidof
Posté par voxdemonix . Évalué à 1.
Ce n'est pas un fork.
J'avoue ne pas voir comment utiliser le contenu de /proc en partant de noms de processus.
[^] # Re: man pidof
Posté par Cyril Brulebois (site web personnel) . Évalué à 2.
Tu penses qu'
exec
est implémenté comment ?Debian Consultant @ DEBAMAX
[^] # Re: man pidof
Posté par arnaudus . Évalué à 1. Dernière modification le 18 mars 2019 à 13:20.
Sur ma machine, qui n'est pas à genoux, un simple pidof firefox prend en effet à peu près 10ms. Il faut quand même lancer un shell qui charge un exécutable (deux avec wc) et faire plein d'appels système, puis matcher une chaine de caractères sur plusieurs centaines de candidats. Du coup, ça prend le temps que ça prend, on parle quand même de moins de 1/50e de seconde pour une tâche que tu ne vas pas réaliser toutes les secondes…
Si tu as le contrôle de soft1 et soft2, pourquoi ne pas leur faire créer un fichier vide quelque part dans /tmp, ou un truc comme ça? Ça devrait aller beaucoup plus vite de vérifier l'existence d'un fichier plutôt que d'appeler pidof…
Tu peux parser le nom du soft, par exemple dans /proc/*/cmdline sur tous les pid. Est-ce que pidoff ne ferait pas un truc comme ça?
[^] # Re: man pidof
Posté par voxdemonix . Évalué à 1. Dernière modification le 18 mars 2019 à 13:33.
Bah justement si, le but de ce script est d'être appelé le plus souvent possible (plus d'une fois par seconde si l'on considère le nombre de machines). Par conséquent, diminuer au maximum son impacte est primordiale.
Avec une moyenne de 55ms de réponse et un appel tout les 5 secondes ça fait une durée d’exécution de 950,4 secondes par jours (soit 15,84 minutes/jours) ou encore 96,36 heures par an, le tout a multiplié par le nombre de serveurs backends.
Je vais regarder pour tenter de convertir ce calcul en consommation énergétique.
Parce que ce fichier permettrait de savoir si les softwares ont été lancé, pas s'ils sont toujours en cours de fonctionnement au moment du check.
[^] # Re: man pidof
Posté par lolop (site web personnel) . Évalué à 3.
Si tu leur fais écrire leur pid dans un fichier, tu devrais pouvoir le lire et regarder ensuite directement dans
/proc/lepid/status
l'état du processus, sans avoir besoin d'exec.Votez les 30 juin et 7 juillet, en connaissance de cause. http://www.pointal.net/VotesDeputesRN
[^] # Re: man pidof
Posté par voxdemonix . Évalué à 1. Dernière modification le 18 mars 2019 à 16:30.
Hmmm, l'idée est très bonne mais il semble que l'utilisateur www-data ne puisse accéder à ces fichiers :
Testé avec le code suivant :
[^] # Re: man pidof
Posté par voxdemonix . Évalué à 1. Dernière modification le 18 mars 2019 à 17:20.
Rectification de ma part, c'est mon code qui était pourris. Cette version fonctionne et est beaucoup plus rapide que via pidof.
[^] # Re: man pidof
Posté par voxdemonix . Évalué à 1. Dernière modification le 18 mars 2019 à 17:36.
Excusez pour le copié-collé foireux, j'ai mis le code dans le message du thread.
Par contre il y a risque de faux positifs avec cette méthode je pense.
Si je lance un script qui à comme paramètre "syncthing" et que justement l'utilisateur recherche "syncthing", je pense que ça va grep.
# utiliser ce qui est prevu pour ca
Posté par NeoX . Évalué à 4.
le SNMP permet de lister les processus en cours
donc tu n'as plus qu'à parser la sortie ou demander une branche speciale pour ne sortir que les process listés
ca devrait etre plus rapide qu'ouvrir une page php, appeler un shell, executer une commande, parser le resultat, redonner le resultat à php, etc
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.