Running celeryd_multi with supervisor - celery

I'm working with djcelery and supervisor.
I was running a celery with supervisor and everything worked fine, once I realized that I needed to change it to celery multi everything broke up.
If I run celeryd_multi in a terminal it works but always run in background, like supervisor need that the command run in foreground there where the problem is.
This is my celery.ini:
[program:celery_{{ division }}]
command = {{ virtualenv_bin_dir }}/python manage.py celeryd_multi start default mailchimp -c:mailchimp 3 -c:default 5 --loglevel=info --logfile={{ log_dir }}/celery/%n.log --pidfile={{ run_dir }}/celery/%n.pid --schedule=/home/celery/celerybeat-schedule --settings={{ django_settings_python_path }}
autorestart = false
autostart = false
directory = {{ repo_dir }}/{{ division }}
user=celery
numprocs = 1
redirect_stderr = True
stopwaitsecs = 10
startsecs = 10
priority = 997
startretries = 3
Here is the command I put in the terminal that works fine
python manage.py celeryd_multi start default mailchimp -c:mailchimp 3 -c:default 5 --loglevel=info --logfile=/var/log/celery/%n.log --pidfile=/var/log/celery/%n.pid --schedule=/home/celery/celerybeat-schedule --settings=lively.settings_gunicorn

Reply from the main developer of celery (23 Mar 2012):
I'm not aware of any simple solution to start multiple celeryd instances
using supervisor, but you can always use one config for each. Maybe someone
else has a solution for it though.
The generic-init.d/celeryd script uses celeryd-multi to start multiple servers,
and you can use the CELERYD_NODES /etc/init.d/celeryd variable to set a number, or
a list of worker names.
I'm not sure how supervisord could be made to work with celeryd-multi, as it would
probably need to know which of the resulting PIDs should be monitored or not (maybe a supervisord
plugin could be written?)
-- Ask Solem

Daemontools has a utility called fghack designed to make a background process "stay" in the foreground.
pidsig supposedly is similar, but proxies signals:
http://permalink.gmane.org/gmane.comp.sysutils.supervision.general/2010
https://github.com/chexum/pidsig/blob/master/pidsig.c
I believe both are basically wrappers that wait on the backgrounded children.

Related

Supervisord not releasing log file during rotation

I've got a pair of CentOS 7 servers that are running SupervisorD with one program. Supervisord is not set to handle any log rotations.. supervisord.conf's lines related to size and backups both = 0.
supervisord.conf
[unix_http_server]
file=/var/run/dir1/supervisor.sock ; the path to the socket file
[supervisord]
logfile=/var/log/dir1/supervisord.log ; main log file; default $CWD/supervisord.log
logfile_maxbytes=0
; logfile_maxbytes=50MB ; max main logfile bytes b4 rotation; default 50MB
logfile_backups=0
;logfile_backups=10 ; # of main logfile backups; 0 means none, default 10
loglevel=trace ; log level; default info; others: debug,warn,trace
pidfile=/var/run/dir1/supervisord.pid ; supervisord pidfile; default supervisord.pid
nodaemon=false ; start in foreground if true; default false
minfds=786068
minprocs=200 ; min. avail process descriptors;default 200
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///var/run/dir1/supervisor.sock ; use a unix:// URL for a unix socket
[include]
files = /etc/supervisord.d/*.conf
program1.conf
[program:jobengine]
; Set full path to Job Engine program if using virtualenv
command=python /opt/program1/jobengine/jobengine.pyc --namespace=worker%(process_num)02d
environment=PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:
directory=/opt/program1
user=root
numprocs=4
process_name=%(process_num)01d
stdout_logfile=/var/log/dir1/jobengine.log
stderr_logfile=/var/log/dir1/jobengine.log
autostart=true
autorestart=true
startsecs=10
startretries=999
; Below lines added to ensure supervisord does not perform any log handling, in favor of logrotate
stdout_logfile_maxbytes=0
stderr_logfile_maxbytes=0
stdout_logfile_backups=0
stderr_logfile_backups=0
; Need to wait for currently executing tasks to finish at shutdown.
; Increase this if you have very long running tasks.
stopwaitsecs = 600
; Causes supervisor to send the termination signal (SIGTERM) to the whole process group.
stopasgroup=false
; default (999)
priority=999
logrotate/program1.conf
# Track main logs, jobengine logs, etc.
/var/log/dir1/*log {
# Run as the Apache user
su apache apache
# CloudBolt will create the log file
missingok
# Do not rotate empty logs
notifempty
# Do not compress logs
nocompress
# Use `*.log.1` naming instead of `*.log-YYYYMMDD` format
nodateext
# Keep 5 archived logs
rotate 5
# Rotate files larger than this size
size 5M
}
So what happens is logrotate kicks off at it's appropriate time, however supervisord refuses to move from the old to the new log file. I'm used to the logrotate having a postscript for a restart signal however I'm 100% new to supervisord so I've been trying to verify how to gracefully restart supervisord and it's child processes. The way I understand it, 'stopwaitsecs' force supervisord to wait the specified time if busy and when I test the 4 child pids are killed via SIGTERM immediately.
What I need is supervisord to only restart once the child pids have completed w/e they're doing.
I also, on a whim, tried sending supervisord a SIGUSR2, and also a supervisorctl reload.. everything seems to kill the processes immediately.
What am I doing wrong here?

Raspberry Pi not picking up Wii controller or not communicating

I am trying to connect my Wii-mote's to my Raspberry Pi, so I can use them in pygame. I know to use the Wii controller, I need to make some configurations, and I have made them. However, when I run my .sh script to connect the remotes, I am thrown some errors. Here are the scripts:
/mywinput
#WiiMote
Wiimote.A = BTN_A
Wiimote.B = BTN_B
Wiimote.Dpad.X = ABS_Y
Wiimote.Dpad.Y = -ABS_X
Wiimote.Minus = BTN_SELECT
Wiimote.Plus = BTN_START
Wiimote.Home = BTN_MODE
Wiimote.1 = BTN_X
Wiimote.2 = BTN_Y
# Nunchuk
Nunchuk.C = BTN_C
Nunchuk.Z = BTN_Z
Plugin.led.Led1 = 1
#Plugin.led.Led2 = 1
Plugin.led.Led3 = 1
#Plugin.led.Led4 = 1
/wiicontroller.sh
#!/bin/bash
sleep 1 # Wait until Bluetooth services are fully initialized
hcitool dev | grep hci >/dev/null
if test $? -eq 0 ; then
wminput -d -c /home/pi/mywinput CC:FB:65:2C:52:8F &
else
echo "Blue-tooth adapter not present!"
exit 1
fi
I have made wiicontoller.sh executable:
sudo chmod 775 /home/pi/bin/connectwii.sh
Supposedly, I should press one and two one the controller and it should connect. However, the script returns immediately. And even then, when I press one and two, I get thrown errors. I don't think that should be possible as the script has returned, but here is the output:
Socket connect error (control channel)
I am also aware that using cwiid in python is another option. But that doesn't work either, as it does not detect my remote. wmgui also cannot pickup my remote. The only way I am able to detect my remote is through the hcitool scan command. Any help would be appreciated!

How do I run a function in only one thread in a multi-threaded Unicorn Sinatra server?

I put my cron task in a module, and then in my Sinatra server.
module Cron
scheduler = Rufus::Scheduler.new
scheduler.every "30m", :first => :now do
run_cmd('git pull')
puts "pulled the repo!!!"
end
end
class MyServer < Sinatra::Base
include Cron
end
The entry point for the app is unicorn (unicorn config/config.ru -p 9393 -c config/unicorn.rb), and in unicorn.rb, there's this line
worker_processes 7
Because of this, git pull is running seven times every 30 minutes, and pulled the repo!!! is printed seven times.
Is there a way I can run this task only in one thread? I tried putting it in unicorn.rb above worker_processes 7 line but I'm not sure if that's the best place for this code to live in.
Unicorn is a multi-process (not multi-threaded) Rack server. There's no native support for executing a specific code path only in one of the worker processes.
However, you can work around that by saving the worker number after fork into an environment variable and then checking its value in your application code.
In config/unicorn.rb use
after_worker_ready do |server, worker|
ENV["WORKER_NR"] = worker.nr.to_s
end
In your Sinatra app do:
if unicorn_worker_nr == "0"
scheduler.every "30m", :first => :now do
...
end
end
def unicorn_worker_nr
ENV["WORKER_NR"]
end

The command of 'notify-send' does not work in supervisor

My Operating System is Manjora17.1.12, the Python version is 3.7.0, and the Supervisor's version is 3.3.4.
I have a python script, it just shows a notification. The code is:
import os
os.system('notify-send hello')
The supervisor config is :
[program:test_notify]
directory=/home/zz
command=python -u test_notify.py
stdout_logfile = /home/zz/supervisord.d/log/test_notify.log
stderr_logfile = /home/zz/supervisord.d/log/test_notify.log
But when I execute the python script with the supervisor, it doesn't show the notification.
Proper environment variables need to be set (DISPLAY & DBUS_SESSION_BUS_ADDRESS). You can do it in many different ways, depending on your needs, like e.g.
a) per subprocess
import os
os.system('DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus notify-send hello')
b) in script globally
import os
os.environ['DISPLAY'] = ':0'
os.environ['DBUS_SESSION_BUS_ADDRESS'] = 'unix:path=/run/user/1000/bus'
os.system('notify-send hello')
c) in supervisor config per program
[program:test_notify]
;
; your variables
;
user=john
environment=DISPLAY=":0",DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus"
The above examples have a couple of assumptions (you may want to change these settings accordingly):
script is run as user john
UID of user john is 1000
notification appear on display :0
To run script as root and show notification for regular user, use sudo as described on Arch wiki Desktop_notifications.

Where to find logs for a cloud-init user-data script?

I'm initializing spot instances running a derivative of the standard Ubuntu 13.04 AMI by pasting a shell script into the user-data field.
This works. The script runs. But it's difficult to debug because I can't figure out where the output of the script is being logged, if anywhere.
I've looked in /var/log/cloud-init.log, which seems to contain a bunch of stuff that would be relevant to debugging cloud-init, itself, but nothing about my script. I grepped in /var/log and found nothing.
Is there something special I have to do to turn logging on?
The default location for cloud init user data is already /var/log/cloud-init-output.log, in AWS, DigitalOcean and most other cloud providers. You don't need to set up any additional logging to see the output.
You could create a cloud-config file (with "#cloud-config" at the top) for your userdata, use runcmd to call the script, and then enable output logging like this:
output: {all: '| tee -a /var/log/cloud-init-output.log'}
so I tried to replicate your problem. Usually I work in Cloud Config and therefore I just created a simple test user-data script like this:
#!/bin/sh
echo "Hello World. The time is now $(date -R)!" | tee /root/output.txt
echo "I am out of the output file...somewhere?"
yum search git # just for fun
ls
exit 0
Notice that, with CloudInit shell scripts, the user-data "will be executed at rc.local-like level during first boot. rc.local-like means 'very late in the boot sequence'"
After logging in into my instance (a Scientific Linux machine) I first went to /var/log/boot.log and there I found:
Hello World. The time is now Wed, 11 Sep 2013 10:21:37 +0200! I am
out of the file. Log file somewhere? Loaded plugins: changelog,
kernel-module, priorities, protectbase, security,
: tsflags, versionlock 126 packages excluded due to repository priority protections 9 packages excluded due to repository
protections ^Mepel/pkgtags
| 581 kB 00:00
=============================== N/S Matched: git =============================== ^[[1mGit^[[0;10mPython.noarch : Python ^[[1mGit^[[0;10m Library c^[[1mgit^[[0;10m.x86_64 : A fast web
interface for ^[[1mgit^[[0;10m
...
... (more yum search output)
...
bin etc lib lost+found mnt proc sbin srv tmp var
boot dev home lib64 media opt root selinux sys usr
(other unrelated stuff)
So, as you can see, my script ran and was rightly logged.
Also, as expected, I had my forced log 'output.txt' in /root/output.txt with the content:
Hello World. The time is now Wed, 11 Sep 2013 10:21:37 +0200!
So...I am not really sure what is happening in you script.
Make sure you're exiting the script with
exit 0 #or some other code
If it still doesn't work, you should provide more info, like your script, your boot.log, your /etc/rc.local, and your cloudinit.log.
btw: what is your cloudinit version?