How many open files for each process running for a specific user in Linux - linux

Running Apache and Jboss on Linux, sometimes my server halts unexpectedly saying that the problem was Too Many Open Files.
I know that we might set a higher limit for nproc and nofile at /etc/security/limits.conf to fix the open files problem, but I am trying to get better output, such as using watch to monitor them in real-time.
With this command line I can see how many open files per PID:
lsof -u apache | awk '{print $2}' | sort | uniq -c | sort -n
Output (Column 1 is # of open files for the user apache):
1 PID
1335 13880
1389 13897
1392 13882
If I could just add the watch command it would be enough, but the code below isn't working:
watch lsof -u apache | awk '{print $2}' | sort | uniq -c | sort -n

You should put the command insides quotes like this:
watch 'lsof -u apache | awk '\''{print $2}'\'' | sort | uniq -c | sort -n'
or you can put the command into a shell script like test.sh and then use watch.
chmod +x test.sh
watch ./test.sh

This command will tell you how many files Apache has opened:
ps -A x |grep apache | awk '{print $1}' | xargs -I '{}' ls /proc/{}/fd | wc -l
You may have to run it as root in order to access the process fd directory. This sounds like you've got a web application which isn't closing its file descriptors. I would focus my efforts on that area.

Related

Bash script works locally but not on a server

This Bash script is called from a SlackBot using a Python script that uses the paramiko library. This works perfectly when I run the script locally from the bot. It runs the application and then kills the process after the allotted time. But when I run this same script on a server from the SlackBot, it doesn't kill the process. Any suggestions?? The script name is "runslack.sh" which is what is called with the grep command below.
#!/bin/bash
slack-export-viewer -z "file.zip"
sleep 10
ps aux | grep runslack.sh | awk '{print $2}' | xargs kill
Please try this and let me know if this helps you
ps -ef | grep runslack.sh | grep -v grep | awk '{print $2}' |xargs -i kill -9 {}
and i hope your user has sufficient permission to execute/kill this action on your server environment.

how to get PIDs spawn from a particular folder

I have a program that in distributed mode creates a folder and spawns a bunch of sub processes. Is there any way to find all PIDs that were executed from this folder? Sort of opposite of
$ pwdx pid
where you give a path name and you get a bunch of pids.
thanks
Reporting all processes which absolute path is inside '/usr/bin/' may be done like this:
ls -l /proc/*/exe 2>/dev/null | grep /usr/bin/ | sed 's#.*/proc/##;s#/exe.*##;' | grep -v "self"
Reporting all processes which working directory (working directory can be changed by a simple cd) is inside /tmp/a could be done like this:
ps axo pid | xargs -n1 pwdx 2>/dev/null | grep ': /tmp/a' | sed 's/:.*//'

Find out if process / file is running linux

I want to check if a process is running or not. I've been trying by
ps -C /path/file
and get this response:
PID TTY TIME CMD
If I do
pgrep php
I get a list of php processes running, but only the PID.
Is there a possibility to
determine the PID of a file I specify (I want to type the file and get the PID)
get the filename if I type the PID
get all the running processes PIDs in a file to work with that in a later script
OS: Ubuntu 14.04 LTS
I've been looking for this since quite some time, tried all the possibilities I found on SO and else but just can't figure out how to do this best.
"Determine the PID of a file I specify."
lsof | grep <file> | awk '{print $2}'
"Get the filename if I type the PID."
lsof | grep <PID>
lsof | grep <PID> | awk '{print $NF}'
"Get all the running processes PIDs in a file to work with that in a later script."
ps x | awk '{print $1}' > pid-list.txt # PIDs of all processes run by current user
ps ax | awk '{print $1}' > pid-list.txt # PIDs of all processes run by all users
What about ps aux | grep <the-name-of-the-process>.

How do I get "awk" to work correctly within a "su -c" command?

I'm running a script at the end of a Jenkins build to restart Tomcat. Tomcat's shutdown.sh script is widely known not to work all in many instances and so my script is supposed to capture the PID of the Tomcat process and then attempt to manually shut it down. Here is the command I'm using to capture the PID:
ps -ef | grep Bootstrap | grep -v grep | awk '{print $2}' > tomcat.pid
The output when manually runs retrieves the PID perfectly. During the Jenkins build I have to switch users to run the command. I'm using "su user -c 'commands'" like this:
su user -c "ps -ef | grep Bootstrap | grep -v grep | awk '{print $2}' > tomcat.pid"
Whenever I do this however, the "awk" portion doesn't seem to be working. Instead of just retrieving the PID, it's capturing the entire process information. Why is this? How can I fix the command?
The issue is that $2 is being processed by the original shell before being sent to the new user. Since the value of $2 in the shell is blank, the awk command at the target shell essentially becomes awk {print }. To fix it, you just escape the $2:
su user -c "pushd $TOMCAT_HOME;ps -ef | grep Bootstrap | grep -v grep | awk '{print \$2}' > $TOMCAT_HOME/bin/tomcat.pid"
Note that you want the $TOMCAT_HOME to be processed by the original shell so that it's value is set properly.
You don't need the pushd command as you can replace the awk command with:
cut -d\ -f2
Note: two 2 spaces between -d\ and -f2

Shell script for logging cpu and memory usage of a linux process

I am looking for a way to log and graphically display cpu and RAM usage of linux processes over time. Since I couldn't find a simple tool to so (I tried zabbix and munin but installation failed) I started writing a shell script to do so
The script file parses the output of top command through awk and logs into a csv file. It
Figures out the pid of the processes through ps command
Uses top and awk to log cpu and memory usage.
Here is how the script looks like
#!/bin/sh
#A script to log the cpu and memory usage of linux processes namely - redis, logstash, elasticsearch and kibana
REDIS_PID=$(ps -ef | grep redis | grep -v grep | awk '{print $2}')
LOGSTASH_PID=$(ps -ef | grep logstash | grep -v grep | awk '{print $2}')
ELASTICSEARCH_PID=$(ps -ef | grep elasticsearch | grep -v grep | awk '{print $2}')
KIBANA_PID=$(ps -ef | grep kibana | grep -v grep | awk '{print $2}')
LOG_FILE=/var/log/user/usage.log
echo $LOG_FILE
top -b | awk -v redis="$REDIS_PID" -v logstash="$LOGSTASH_PID" '/redis|logstash/ {print $1","$9","$10","$12}'
How do I
Print the resource usage for multiple processes. Specifying multiple
variables in the awk pattern is not working. It prints the usage for
the first pid (redis in the above script)
Print current timestamp when printing the resource details (through date +"%T")
Print the process name along with the resource usage. Redis, Logstash, ElasticSearch or Kibana in the above case
Redirect the above commands output to a log file. I tried > $LOG_FILE but it didn't work.
Thoughts/Inputs?
Thanks in advance.
To figure out PIDs you can simplify your script greatly using pgrep:
REDIS_PID=$(pgrep -f redis)
LOGSTASH_PID=$(pgrep -f logstash)
ELASTICSEARCH_PID=$(pgrep -f elasticsearch)
KIBANA_PID=$(pgrep -f kibana)
EDIT: Sorry had to leave for some work and couldn't provide the full answer.
In order to capture top's output use following script:
while :; do
top -n 1 -b | awk -v redis="$REDIS_PID" -v logstash="$LOGSTASH_PID"
'$1 == redis || $1 == logstash {print $1","$9","$10","$12}' >> $LOG_FILE
sleep 3
done

Resources