Reputation: 8098
As a freelance SysAdmin/Developer I need to get/update existing app/web on the client server. Sometime I need to update existing NodeJS app that I don't know the port or the path.
If I want to know the port, I can do easily by find apache2/PHP app config using apache2ctl -S
command. But it's difficult to find the nodeJS app path even I know the port.
Usually the node app is running using pm2. pm list
only show list of processes name/command like below:
root@lamp-s-4vcpu-8gb-sgp1-01:~# pm2 list
┌────┬────────────────────┬──────────┬──────┬───────────┬──────────┬──────────┐
│ id │ name │ mode │ ↺ │ status │ cpu │ memory │
├────┼────────────────────┼──────────┼──────┼───────────┼──────────┼──────────┤
│ 11 │ .com │ fork │ 0 │ stopped │ 0% │ 0b │
│ 6 │ DEV API │ fork │ 0 │ stopped │ 0% │ 0b │
│ 0 │ balance Web │ fork │ 7 │ stopped │ 0% │ 0b │
│ 4 │ balance queue │ fork │ 0 │ stopped │ 0% │ 0b │
│ 9 │ index │ fork │ 133… │ online │ 0.3% │ 144.0mb │
│ 10 │ index │ fork │ 21 │ online │ 0.2% │ 134.5mb │
│ 12 │ index │ fork │ 13 │ online │ 0.4% │ 155.4mb │
│ 7 │ longbgst │ fork │ 52 │ online │ 0% │ 40.0mb │
│ 8 │ npm │ fork │ 220… │ stopped │ 0% │ 0b │
│ 2 │ npm run staging │ fork │ 116… │ stopped │ 0% │ 0b │
│ 1 │ old │ fork │ 0 │ stopped │ 0% │ 0b │
│ 5 │ v-api dev │ fork │ 0 │ stopped │ 0% │ 0b │
│ 3 │ develop API │ fork │ 358… │ stopped │ 0% │ 0b │
└────┴────────────────────┴──────────┴──────┴───────────┴──────────┴──────────┘
[PM2][WARN] Current process list running is not in sync with saved list. Type 'pm2 save' to synchronize or enable autosync via 'pm2 set pm2:autodump true'
and pm2 show
command only show path not the port example:
root@lamp-s-4vcpu-8gb-sgp1-01:~# pm2 show 10
Describing process with id 10 - name index
┌───────────────────┬─────────────────────────────────────────┐
│ status │ online │
│ name │ index │
│ namespace │ default │
│ version │ 1.0.0 │
│ restarts │ 21 │
│ uptime │ 2D │
│ script path │ /var/www/api-path-id/dist/index.js │
│ script args │ N/A │
│ error log path │ /root/.pm2/logs/index-error.log │
│ out log path │ /root/.pm2/logs/index-out.log │
│ pid path │ /root/.pm2/pids/index-10.pid │
│ interpreter │ node │
│ interpreter args │ N/A │
│ script id │ 10 │
│ exec cwd │ /var/www/api-path-id │
│ exec mode │ fork_mode │
│ node.js version │ 11.15.0 │
│ node env │ api_path_id │
│ watch & reload │ ✘ │
│ unstable restarts │ 0 │
│ created at │ 2020-11-16T03:29:39.945Z
Usually I need to look up using pm2 show
command for each pm2 process to find the app path then got to the path and find the port on .env/config file. It's very take a long time if there are so many processes. Is any faster way to see list of running nodejs app with the port and path?
I tried commands from this question answer but not returned path or process name like below:
root@lamp-s-4vcpu-8gb-sgp1-01:~# ss -tnlp | grep "node /"
LISTEN 0 128 127.0.0.1:6030 0.0.0.0:* users:(("node /var/www/v",pid=26000,fd=25))
LISTEN 0 128 0.0.0.0:6031 0.0.0.0:* users:(("node /var/www/a",pid=26006,fd=25))
LISTEN 0 128 127.0.0.1:6039 0.0.0.0:* users:(("node /var/www/a",pid=26013,fd=25))
root@lamp-s-4vcpu-8gb-sgp1-01:~#
root@lamp-s-4vcpu-8gb-sgp1-01:~# ss -ntlp | grep $(pm2 ls | grep "SITENAME" | awk '{print $10}') | awk '{print $4}'
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.
ss -lntp | grep node
command show all port but it gives wrong path (maybe cutted/substr).
root@lamp-s-4vcpu-8gb-sgp1-01:~# ss -lntp | grep node
LISTEN 0 128 127.0.0.1:6030 0.0.0.0:* users:(("node /var/www/v",pid=26000,fd=25))
LISTEN 0 128 0.0.0.0:6031 0.0.0.0:* users:(("node /var/www/a",pid=26006,fd=25))
LISTEN 0 128 127.0.0.1:6039 0.0.0.0:* users:(("node /var/www/a",pid=26013,fd=25))
LISTEN 0 128 127.0.0.1:3001 0.0.0.0:* users:(("node",pid=29886,fd=24))
root@lamp-s-4vcpu-8gb-sgp1-01:~# cd /var/www/a
-bash: cd: /var/www/a: No such file or directory
I need list of port and path(or atleast pm2 process name).
Upvotes: 4
Views: 12359
Reputation: 413
These pm2 commands are about you're looking for:
Step #1 : List your pm2 processes to obtain the name of your app.
pm2 list
Step #2 : Replace app_name below with the name from your list.
pm2 describe my_app
This will give you all relevant information about your running process. Look for script path
.
Upvotes: 0
Reputation: 8098
I just learn some Linux commands to make this:
ss
without sorting (not recommended)Step 1 - Get the PIDs
ss -lntp | grep node | cut -d "=" -f2 - | cut -d "," -f 1 - > pids.txt
Explanation:
ss -lntp
will print the list of Socket Statistics.grep node
will print only node process/sockets.cut -d "=" -f2 -
will cut the output of command #2 using =
as the delimiter and get the second column (-f2
). example result is 26000,fd
cut -d "," -f 1 -
to remove ,fd
from command #3 and will cut the output of step #2 using ,
as the delimiter and get the first column (-f1
). example result is 26000
> pids.txt
to save the output to pids.txt file.Step 2 - Get the Ports
ss -lntp | grep node | awk '{ print $4 }' > ports.txt
Explanation:
ss -lntp
will print the list of Socket Statistics.grep node
will print only node process/sockets.awk '{ print $4 }'
will print the fourth column, i.e. the one containing 0.0.0.0:6031
> ports.txt
to save the output to ports.txt file.Step 3 - Get the Paths from the PIDs
ps -eLf | grep -Fwf pids.txt | awk '!x[$2]++' | awk '{ print $11 }' > proc.txt
Explanation:
ps -eLf
will print the list of Process status.grep -Fwf pids.txt
will print only pid/process number from pids.txt.(but its still have so many duplicate main process)awk '!x[$2]++'
will filter only unique pid number only. the pid number is on 2nd column so use $2
awk '{ print $11 }'
will print only 11th column. the path is on 11th column so use $11
> proc.txt
to save the output to proc.txt file.Step 4 - Show list merged paths, ports and processes
paste -d" " proc.txt ports.txt pids.txt
example output(same server as my question)
root@lamp-s-4vcpu-8gb-sgp1-01:~# paste -d" " proc.txt ports.txt pids.txt
/var/www/******/dist/index.js 127.0.0.1:6030 26000
/var/www/api-****-id/dist/index.js 0.0.0.0:6031 26006
/var/www/api.****.com/dist/index.js 127.0.0.1:6039 26013
/var/www/***-nuxt/node_modules/.bin/nuxt 127.0.0.1:3001 29886
can be simply to a line:
ss -lntp | grep node | cut -d "=" -f 2 - | cut -d "," -f 1 - > pids.txt && ss -lntp | grep node | awk '{ print $4 }' > ports.txt && ps -eLf | grep -Fwf pids.txt | awk '!x[$2]++' | awk '{ print $11 }' > proc.txt && paste -d" " proc.txt ports.txt pids.txt
Maybe above commands can be improved, because I just learn today some commands like ss
, sort
, paste
, cut
, awk
and ps
Above method work fine if list of pids from ss
command is ascending sequence. But after try on another server above commands sometime does not work properly because the pids and path position can be swapped. So I tried to find out another way using sort like below:.
netstat
with PID sorting (recommended)Step 1 - Get the PIDs
netstat -lntp | grep node | sort -k 7,7 | awk '{ print $7 }' | cut -d "/" -f 1 - > pids.txt
Step 2 - Get the Ports
netstat -lntp | grep node | sort -k 7,7 | awk '{ print $4 }' > ports.txt
Step 3 - Get the Paths from the PIDs
ps -eLf | grep -Fwf pids.txt | awk '!x[$2]++' | sort -k 2,2 | awk '{ print $11 }' > proc.txt
Step 4 - Show list merged paths, ports and processes
paste -d" " proc.txt ports.txt pids.txt
Upvotes: 3
Reputation: 630
You will still need to issue a pm2 list
command to get the app_name
but this may give you a bit of help.
From the steps below you could set up a script to loop through each of the PID's
returned from the command pm2 pid
. This could be done by storing the output in a file pid.text
and looping through.
pm2 pid > pid.text
Step 1 - Get the PID
TEST_PID=`pm2 pid app_name`
The <app_name>
is the name of the pm2 process. The PID will now be in TEST_PID
Step 2 - Get the path to the script
TEST_PATH=$(ps -f -p $TEST_PID | grep -o "/.*")
This will use the PID obtained in step one and search for it in the entire list of processes. It then pipes this into grep
where we only want the exact text match using the -o
option. The pattern we are looking for is a /
to indicate the start of a directory, followed by any character and we want everything after it.
Step 3 - Get the port
You can use the netstat
command to get the information on the port. This is done by knowing the fact that we have the PID
PORT_TEST=$(sudo netstat -p | grep $TEST_PID | grep ':[0-9]*\s')
Step 4 - Printing them out
echo -e $TEST_PID'\n'$TEST_PATH'\n'$PORT_TEST
319
/home/warren/Ec2/EC2-QueryData/index.js
tcp6 0 0 XXX.XXX.XXX.XXX:33979 TUDBNXJL63:52025 ESTABLISHED 319/node
Upvotes: 4