See HLS viewer number in Nginx + RTMP module - nginx

I am trying to fetch the actual number of HLS viewers in an Nginx with the RTMP module.
I have tried this solution but it is not giving me the real number, I think maybe because it's not counting the viewers who are pulling the stream in HLS format.
Is there any 'good' way to achieve that?
Thanks.

There is a way by counting the number of IPs that requested HLS/DASH fragments in the last 10 to 20 minutes:
#!/bin/bash
date_prefix=$(date +'%d/%b/%Y:%H')
cur_min=$(date +'%M')
cur_min_decimal=${cur_min:0:1}
if [[ $cur_min_decimal == '0' ]]
then
prev_min_decimal=5
else
prev_min_decimal=$(($cur_min_decimal - 1))
fi
cur_minuted_date="${date_prefix}:${cur_min_decimal}"
prev_minuted_date="${date_prefix}:${prev_min_decimal}"
tail -n 10000 /var/log/nginx/access.log \
| grep -E 'GET /(hls|dash)/key-' \
| grep -E "${cur_minuted_date}|${prev_minuted_date}" \
| awk '{print $1}' \
| sort \
| uniq \
| wc -l
If you want to show it on the website, you can CRON that script every minute and output it in the /var/www/html folder

Related

How can I ssh into a second server, run a command, and assign the output to a variable?

This is what I am attempting to do:
fromServer=$(ssh -A first.com ssh second.com rpm -qa | grep exampleString)
echo $fromServer
echo does not print anything. If I manually shh into first and then ssh into second then run the command I get output:
ssh first.com
ssh second.com
rpm -qa | grep exampleString
How can I combine these three steps into one line and store the output into a variable?
Use proper quoting or escaping:
fromServer=$(ssh -A first.com 'ssh second.com rpm -qa | grep exampleString')
echo $fromServer
or
fromServer=$(ssh -A first.com ssh second.com rpm -qa \| grep exampleString)
echo $fromServer
% VAR=$(ssh -C user#server ls -la \| grep vim)
% echo $VAR
-rw------- 1 user user 15153 Mar 22 13:45 .vimrc
edit: oooooooh, sneaky, I did not see you were doing two SSH ☺
So then you'll need a bit more quoting, because you don't want to have your pipe being interpreted by first.com. Here's three ways to work around that:
fromServer=$(ssh -A first.com ssh second.com rpm -qa \\\| grep exampleString)
fromServer=$(ssh -A first.com 'ssh second.com rpm -qa \| grep exampleString')
fromServer=$("ssh -A first.com 'ssh second.com rpm -qa | grep exampleString'")
What's happening is that you want to execute:
user#second % rpm -qa | grep exampleString
on the second.com server, so you have to escape the pipe so it's not interpreted by the first.com server:
user#first % ssh second.com rpm -qa \| grep exampleString
or
user#first % ssh second.com 'rpm -qa | grep exampleString'
but then again, you need to have that executed on first.com, from your local workstation, as you still don't want to see the pipe interpreted, you need to add a second layer of escaping/quoting:
user#workstation % ssh first.com "ssh second.com 'rpm -qa | grep exampleString'"
or
user#workstation % ssh first.com 'ssh second.com rpm -qa \| grep exampleString'
and then, once you're sure you get an output you can put that whole command's output in a variable:
VAR=$(ssh first.com "ssh second.com 'rpm -qa | grep exampleString'")
HTH

UNIX for loop with some options

I have for loop:
for mnt `cat $file.txt`
do
grep -h -i -A 3 -B 4 *log | grep -v "10001" >> extrafile.txt
done
What does -A 3 and -B 4 means?
After and Before followed by number of lines
After en Before. After and before what?
No wonder the grep is confusing: You don't mention the "${mnt}" you are searching for. When I improve your script (moving input and output to the end, outside the loop, and using ${mnt}), the script looks like
while read -r mnt; do
grep -h -i -A 3 -B 4 "${mnt}" *log | grep -v "10001"
done < "${file.txt}" >> extrafile.txt
You get the context of every hit from $file.txt and delete all lines with 10001.

fetch the value of number of active threads in a process

I am trying to fetch the number of threads of a process in a UNIX using command line. After going through the man page of unix command, I learnt that following command:
ps -o nlwp <pid>
returns the number of threads spawned in a process.
Whenever i executed above command in unix, it returned:
NLWP
7
Now, I want to neglect NLWP and a space before 7.
That is I am just interested in a value, as I will be using it in a script, that I am writing for unit testing?
Is it possible to fetch only value, and neglect everything(Title NLWP, space)?
You can always use the --no-headers option in ps to get rid of the headers.
In that case, use awk to just print the first value:
ps --no-headers -o nlwp <pid> | awk '{print $1}'
Or tr to remove the spaces:
ps --no-headers -o nlwp <pid> | tr -d ' '
If --no-headers is not supported in your ps version, either of these make it:
ps -o nlwp <pid> | awk 'END {print $1}'
ps -o nlwp <pid> | tail -1 | tr -d' '

How to find most frequent user agent in nginx access.log

In order to counter a botnet attack, I am trying to analyze a nginx access.log file to find which user agents are the most frequent, so that I can find the culprits and deny them. How can I do that?
Try something like this on your access log, replace with the path to your access log, also keep in mind that some log files would get zipped and new one would be created
sudo awk -F" " '{print $1}' /var/log/nginx/access.log | sort | uniq -dc
EDIT:
Sorry I just noticed you wanted user agent instead of IP
sudo awk -F"\"" '{print $6}' /var/log/nginx/access.log | sort | uniq -dc
To sort ascending append | sort -nr and to limit to 10 append | head -10
so the final total line would be
sudo awk -F"\"" '{print $6}' /var/log/nginx/access.log | sort | uniq -dc | sort -nr | head -10
To get user agent
sudo awk -F'"' '/GET/ {print $6}' /var/log/nginx-access.log | cut -d' ' -f1 | sort | uniq -c | sort -rn
awk(1) - selecting full User-Agent string of GET requests
cut(1) - using first word from it
sort(1) - sorting
uniq(1) - count
sort(1) - sorting by count, reversed

Kill respawing server running on port 3000 created by `node . > /dev/null 2> /dev/null < /dev/null &`

I'm using AWS CodeDeploy in which server running on pm2 dose not work due to explanation given here in troubleShoot documentation.
I followed the documentation and in AfterInstall script used node . > /dev/null 2> /dev/null < /dev/null & to run the node server in the background.
I've tried following ways to kill the server
fuser -k 3000/tcp
lsof -P | grep ':3000' | awk '{print $2}' | xargs kill -9
kill -9 $(lsof -t -i:3000)
but each time a new process respwans with a different PID.
How can I kill this background process and add it to the ApplicationStop script for CodeDeploy?
One of the problems with finding a pid with grep is that the grep pid will also show up as a result and can kill itself before the target, so try;
ps ax | grep node | grep -v grep
if it looks reasonable, review this;
ps ax | grep node | grep -v grep | awk '{print $1}'
then run the kill;
ps ax | grep node | grep -v grep | awk '{print $1}' | xargs kill -9
pkill is a less flexible option (no regex filtering) but if you use that be sure to use the -I flag so you don't kill anything you did not intend to.
I was able to kill using pkill node command.

Resources