Muhammad Dyas Yaskur
Muhammad Dyas Yaskur

Reputation: 8098

How to get list nodejs processes/app port and path?

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

Answers (3)

JacobRossDev
JacobRossDev

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

Muhammad Dyas Yaskur
Muhammad Dyas Yaskur

Reputation: 8098

I just learn some Linux commands to make this:

METHOD 1 usingss without sorting (not recommended)

Step 1 - Get the PIDs

ss -lntp | grep node | cut -d "=" -f2 - | cut -d "," -f 1 - > pids.txt

Explanation:

  1. ss -lntp will print the list of Socket Statistics.
  2. grep node will print only node process/sockets.
  3. 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
  4. 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
  5. > 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:

  1. ss -lntp will print the list of Socket Statistics.
  2. grep node will print only node process/sockets.
  3. awk '{ print $4 }' will print the fourth column, i.e. the one containing 0.0.0.0:6031
  4. > 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:

  1. ps -eLf will print the list of Process status.
  2. grep -Fwf pids.txt will print only pid/process number from pids.txt.(but its still have so many duplicate main process)
  3. awk '!x[$2]++' will filter only unique pid number only. the pid number is on 2nd column so use $2
  4. awk '{ print $11 }' will print only 11th column. the path is on 11th column so use $11
  5. > 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:.

METHOD 2 using 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

WK123
WK123

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

Related Questions