how to get the number of apache children free within php - php

In php, how can I get the number of apache children that are currently available (status = SERVER_READY in the apache scoreboard)?
I'm really hoping there is a simple way to do this in php that I am missing.

You could execute a shell command of ps aux | grep httpd or ps aux | grep apache and count the number of lines in the output.
exec('ps aux | grep apache', $output);
$processes = count($output);
I'm not sure which status in the status column indicates that it's ready to accept a connection, but you can filter against that to get a count of ready processes.

If you have access to the Apache server status page, try using the ?auto flag:
http://yourserver/server-status?auto
The output is a machine-readable version of the status page. I believe you are looking for "IdleWorkers". Here's some simple PHP5 code to get you started. In real life you'd probably want to use cURL or a socket connection to initiate a timeout in case the server is offline.
<?php
$status = file('http://yourserver/server-status?auto');
foreach ($status as $line) {
if (substr($line, 0, 10) == 'IdleWorkers') {
$idle_workers = trim(substr($line, 12));
print $idle_workers;
break;
}
}
?>

Related

Run node file.js from php and kill it on unload - Windows

my goal is to run a node file from my php page at the start of my script and then kill that process when the page is closed. I have been reading several questions and answers without luck. I can run by example
exec("node myapp.js arg1 arg2 2>&1", $retArr);
In my node file i added:
console.log(process.pid);
So now i receive the PID of the process on the output array but have to be ended, with this i could kill it later with exec('taskkill /PID '.$array[x].' /f'), how i can get that process pid from php to kill only that one?.
Any lights will be REALLY appreciated. Thanks in advance.
Windows Users:
Ok I found a workaround for this situation in case someone face the same issue.
In PHP
The node app need to listen in a defined port, so you can pass that port to the node app as argument and I needed to start that node app in the background at the beginning of my PHP, from all the possible solutions this one was the one that worked best for me:
$rshell = new COM("WScript.Shell");
$rexec = $rshell->Run("node C:\PATH\TO\NODE\APP\myapp.js ".$appPort." ", 0, false);
this will run the app in the background and you have the listening port in a variable.
In Node.js
Node apps can receive arguments and you can retrieve them using:
process.argv.forEach((val, index) => {
console.log(`${index}: ${val}`);
});
var appPort = process.argv[2];
...
app.listen(appPort);
Back to the PHP
Fine, so far you can start up the node app from php in the background and you have the listening port, so now we create a new php file to handle the closing process, lets say closeNode.php that will receive our listening variable via AJAX onunload :
$( window ).unload(function() {
<!-- your ajax call sending the appPort variable-->
});
closingNode.php
$appPort = $_POST('appPort')
exec('netstat -a -n -o | find "LISTENING" | find "'.$appPort.'"', $result);
if (!empty($result)) {
$pidArray = array();
foreach ($result as $value) {
// our pid is at the end of the string, then we trim the last 10 characters that is enough for the pid process number
$pidArray[] = substr($value, -10);
}
$pidTrimmed = array_map('trim', $pidArray);
$pid = $pidTrimmed[0];
exec('taskkill /f /PID '.$pid.'', $resultKill);
Maybe is not the more elegant solution, but it works.

Trying to get all the process table

I'm trying to print the whole process table with php (Actually I'm trying to print all the php processes that are running on my server). This is the code I'm using:
var_dump(exec("ps -A | grep php"));
When I start the php file, it returns me its own PID but not the others that are already running. I've checked through ssh console and there are 7, and that code prints me just 1 and completelly different to the others PID's.
Any solution?
Thanks in advance.
I found the answer at PHP Manual: getmypid
function countProcesses($scriptName)
{
// ps aux|grep "[u]pdate.php"|wc -l
$first = substr($scriptName, 0, 1);
$rest = substr($scriptName, 1);
$name = '"['.$first.']'.$rest.'"';
$cmd = "ps aux | grep $name | wc -l";
$result = exec($cmd);
return $result;
}
This function returns the number of processes are already running so I just call echo countProcesses('php6'); and it brings me back the amount of processes running as php6.

Make sure one copy of php script running in background

I'm using cronjob to run php script that will be executed every 1 minute
I need also to make sure only of copy is running so if this php script is still running after 2 minutes, cronjob should not run another version.
currently I have 2 options and I would like to see your feedback and if you have any more options
Option 1: create a tmp file when the php script start and remove it when php script finish (and check if the file exists) ---> the problem for me with this option is that if I have my php script crash for any reason, it will not run again (the tmp file will not be deleted)
Option 2: run a bash script like the one below to control the php script execution ---> good but looking for something that can be done within php
#!/bin/bash
function rerun {
BASEDIR=$(dirname $0)
echo $BASEDIR/$1
if ps -ef | grep -v grep | grep $1; then
echo "Running"
exit 0
else
echo "NOT running";
/usr/local/bin/php $BASEDIR/$1 &
exit $?
fi
}
rerun myphpscript.php
PS: I just saw "Mutex class" at http://www.php.net/manual/en/class.mutex.php but not sure if it's stable and anyone tried it.
You might want to use my library ninja-mutex which provides simple interface for handling mutex. Currently it can use flock, memcache, redis or mysql to handle lock.
Below is an example which uses memcache:
<?php
require 'vendor/autoload.php';
use NinjaMutex\Lock\MemcacheLock;
use NinjaMutex\Mutex;
$memcache = new Memcache();
$memcache->connect('127.0.0.1', 11211);
$lock = new MemcacheLock($memcache);
$mutex = new Mutex('very-critical-stuff', $lock);
if ($mutex->acquireLock(1000)) {
// Do some very critical stuff
// and release lock after you finish
$mutex->releaseLock();
} else {
throw new Exception('Unable to gain lock!');
}
I often use the program flock that comes with many linux distributions directly in my crontabs like:
* * * * * flock -n /var/run/mylock.LCK /usr/local/bin/myprogram
Of cause it is still possible to actually start two simultaneously instances of myprogram if you do it by hand, but crond will only make one.
Flock being a small compiled binary, makes it super fast to launch compared to a eventually larger chunk of php code. This is especially a benefit if you have many longer running executions, which it is not perfectly clear that you actually have.
If you're not on a NFS mount, you can use flock() (http://php.net/manual/en/function.flock.php):
$fh = fopen('guestbook.txt','a') or die($php_errormsg);
$tries = 3;
while ($tries > 0) {
$locked = flock($fh,LOCK_EX | LOCK_NB);
if (! $locked) {
sleep(5);
$tries--;
} else {
// don't go through the loop again
$tries = 0;
}
}
if ($locked) {
fwrite($fh,$_REQUEST['guestbook_entry']) or die($php_errormsg);
fflush($fh) or die($php_errormsg);
flock($fh,LOCK_UN) or die($php_errormsg);
fclose($fh) or die($php_errormsg);
} else {
print "Can't get lock.";
}
From: http://docstore.mik.ua/orelly/webprog/pcook/ch18_25.htm
I found the best solution for me is creating a separate database user for your Script and limit the concurent connection to 1 for that user.

Passing a variable through to another PHP page

I'm making a server manager. I want to add a "kill" command, which would call a php script that would essentially run a shell_exec('kill $arrtext'); and kill the process, thus closing the server down. Here is the part of my script that returns the results and checks to see which servers are running:
<?php
$COMMAND = shell_exec('ps -o command ax | grep skulltag | grep -v grep');
$old = array("skulltag-server", "-port", "-iwad", "-wad", "+exec");
$new = array("SKULLTAG", "Running on Port", "Using IWAD", "+ PWAD", "with Config");
$COMMAND = str_replace($old, $new, $COMMAND);
$arr = explode("./",$COMMAND);
$text = shell_exec('pgrep -u doom');
$arrtext = preg_split('/\s+/', $text);
for( $i = 1; $i < count($arr); $i++ ) {
echo '<div class = "serverborder">';
echo '<div class = "servertextalign">';
echo $i,'. PROCESS ID <span style="color: #f00;">',$arrtext[$i],'</span> with server parameters: <span style="color: #777;">',$arr[$i],'</span>';
echo '</div>';
echo '</div>';
echo '<br>';
}
?>
However, I have no idea how I would add a link or something that would set the proper $arrtext[] variable (depending on which one they picked) and pass it to the PHP script that would kill the server.
The live demo can be found at http://server.oblivionro.net/servers/
Thanks!
Could you try using a shell_exec in another, tiny, script to run that kill script in the command line? Don't use a GET variable. I would rather create a small form for each server in the list and passing it through POST ie. requiring the tiny script that takes hidden POST variables, sending the form action to the same page, and passing the array as a parameter
// In form
echo '<input type="hidden" name="pid" value="'.$arrtext[$i].'"/>';
// In script
$pid = $_POST['pid'];
shell_exec('php -f /location/of/kill_script.php -- -'. $pid)
Where pid is your process ID. Obviously, you should set up your kill script to check that the pid is valid. The benefit of this is that the script's true location can stay hidden and doesn't need even need to be in the www root. You shouldn't need to link the real script directly.
The dirty, dirty (not recommended) way to do it is to have the link go to the script with the command, like:
KILL
Then in the killScript, you RIGOROUSLY verify that the process they are killing something they're supposed to be killing.
A better way would be to avoid using as powerful a command as "kill", so that someone doesn't go to killScript.php?p=1230 where 1230 is the process number of your Minecraft game or something...
I am confused why you feel the need to ask since you seem to have a grasp of PHP scripting and already create spans etc with the proper data. it is trivial to construct an anchor tag. The anchor tag might reference a GET variable, which could be the PID. After proper validation such as ensuring the PID references a doom server process (and proper login credentials), the PID can then be used to shell a kill command.
Note that you are potentially opening your server up to allow the world to shut down processes on your server.

Check if a process is running using PHP in Linux

I am using kannel to send SMS via PHP. I want to know how can I check if a particular process is running. For kannel to run, a process named bearerbox should be running all time. I want to check if this process is running or not. Because if the process is not running then a mail will be sent to me notifying me about it.
The easiest is to use pgrep, which has an exit code of 0 if the process exists, 1 otherwise.
Here's an example.
exec("pgrep bearerbox", $output, $return);
if ($return == 0) {
echo "Ok, process is running\n";
}
You can use the exec command to find your process and then act accordingly.
Something like:
exec('ps aux | grep bearerbox', $output);
You'll need to work out what is returned on your server to decide if it's running or not.
Good luck.
There are a lot of ways to deal with this. The easiest (and a direct answer to your question) is to grab the output of 'ps'.
Deamons tend to always create a 'pid' file though. This file contains the process-id of the daemon. If yours has that, you can check the contents of the file and see if the process with that id is still running. This is more reliable.
supervisord might also have this functionality. Lastly, maybe it's better to get a real monitoring system rather than build something yourself. Nagios might be a good pick, but there might be others.
Simple yet handy solution to monitor processes through PHP: PHP-Linux-Process-Monitor.
The code goals like:
$ps = explode("\n", trim(shell_exec('ps axo pid,ppid,%cpu,pmem,user,group,args --sort %cpu')));
foreach($ps AS $process){
$processes[]=preg_split('#\s+#', trim($process), 7 );
}
$head= array_shift($processes);
$processes = array_reverse($processes);
$output='';
foreach ($head AS $f) $output.="<td class=\"head\">$f</td>";
$output=sprintf('<tr class="head">%s</tr>',$output);
foreach($processes AS $p){
$output.='<tr>';
foreach ($p AS $i=>$f){
if($i==0) $output.=sprintf('<td>%1$s</td>',$f);
elseif($i==2) $output.=sprintf('<td class="cpu">%1$s<ins style="width:%1$s%%"></ins></td>',$f);
elseif($i==3) $output.=sprintf('<td class="mem">%1$s<ins style="width="%1$s%%"></ins></td>',$f);
elseif($i == 6) $output.=sprintf('<td class="command">%1$s</td>',$f);
else $output.=sprintf('<td>%1$s</td>',$f);
}
$output.='</tr>';
}
$cpu=implode(' ', sys_getloadavg());
$output=sprintf('<table data-cpu="%s" id="process">%s</table>',$cpu, $output);
This is the best way
<?php
exec("ps -eo comm,pid | awk '$1 == "."\"gs\""." { print $2 }'", $output);
if ($output != 0) {
echo "The process gs is running\n";
}
?>
in the above code gs is the process that I was checking

Categories