skip to Main Content

I want to send server logs to the telegram bot. Here’s my supervisor config:

[program:telegram-log-nginx]
process_name=%(program_name)s_%(process_num)02d
command=bash -c 'tail -f /var/log/nginx/error.log | /usr/share/telegram_log.sh nginx'
autostart=true
autorestart=true
numprocs=1

When I stop supervisor

supervisorctl stop telegram-log-nginx:*

the process is still running:

ps aux | grep telegram
www-data 32151  0.0  0.0  21608  3804 ?        S    20:53   0:00 /bin/bash /usr/share/telegram_log.sh nginx

Is there a proper way to stop all processes?

telegram_log.sh

#!/bin/bash
CHATID="chat"
KEY="key"

SERVICE=$1

TIME="10"
URL="https://api.telegram.org/bot$KEY/sendMessage"

while IFS= read -r line; do
  read -r -d '' TEXT <<- EOM
  Service: $SERVICE
  $line
EOM
  curl -s --max-time $TIME -d "chat_id=$CHATID&disable_web_page_preview=1&text=$TEXT" $URL >/dev/null
done

├─supervisord,1101 /usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf
  │   ├─php,643187 /var/www/web/artisan queue:work
  │   ├─php,643188 /var/www/web/artisan queue:work
  │   ├─php,643189 /var/www/web/artisan queue:work
  ├─systemd,640839 --user
  │   └─(sd-pam),640841
  ├─systemd-journal,406
  ├─systemd-logind,1102
  ├─systemd-resolve,807
  ├─systemd-timesyn,684
  │   └─{systemd-timesyn},689
  ├─systemd-udevd,440
  ├─tail,643203 -f /var/log/nginx/error.log
  ├─telegram_log.sh,643204 /usr/share/telegram_log.sh nginx

2

Answers


  1. Chosen as BEST ANSWER

    @CharlesDuffy has provided the answer

    bash -c 'tail -f /var/log/nginx/error.log | /usr/share/telegram_log.sh nginx'
    

    should be

    bash -c 'exec < <(exec tail -f /var/log/nginx/error.log); exec /usr/share/telegram_log.sh nginx'
    

  2. Assuming that you have a new enough version of bash that process substitutions update $!, you can have your parent script store the PIDs of both its direct children and signal them explicitly during shutdown:

    #!/usr/bin/env bash
    
    # make our stdin come directly from tail -f; record its PID
    exec < <(exec tail -f /var/log/nginx/error.log); tail_pid=$!
    
    # start telegram_log.sh in the background inheriting our stdin; record its PID
    /usr/share/telegram_log.sh nginx & telegram_script_pid=$!
    
    # close our stdin to ensure that we don't keep the tail alive -- only
    # telegram_log.sh should have a handle on it
    exec </dev/null
    
    # define a cleanup function that shuts down both subprocesses
    cleanup() { kill "$tail_pid" "$telegram_script_pid"; }
    
    # tell the shell to call the cleanup function when receiving a SIGTERM, or exiting
    trap cleanup TERM EXIT
    
    # wait until telegram_log.sh exits and exit with the same status
    wait "$telegram_script_pid"
    

    This means your config file might become something more like:

    command=bash -c 'exec < <(exec tail -f /var/log/nginx/error.log); tail_pid=$!; /usr/share/telegram_log.sh nginx & telegram_script_pid=$!; exec </dev/null; cleanup() { kill "$tail_pid" "$telegram_script_pid"; }; trap cleanup TERM EXIT; wait "$telegram_script_pid"'
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search