Trying to get a simple God demo working.
In an empty directory I created the following files as per the God documentation:
simple.rb:
loop do
puts 'Hello'
sleep 1
end
simple.rb:
God.watch do |w|
w.name = "simple"
w.start = "ruby simple.rb"
w.log = 'myprocess.log'
w.keepalive
end
Then I run:
$ sudo god -c simple.god -D
and get this output:
I [2018-10-31 23:19:39] INFO: Loading simple.god
I [2018-10-31 23:19:39] INFO: Syslog enabled.
I [2018-10-31 23:19:39] INFO: Using pid file directory: /var/run/god
I [2018-10-31 23:19:39] INFO: Started on drbunix:///tmp/god.17165.sock
I [2018-10-31 23:19:39] INFO: simple move 'unmonitored' to 'init'
I [2018-10-31 23:19:39] INFO: simple moved 'unmonitored' to 'init'
I [2018-10-31 23:19:39] INFO: simple [trigger] process is running (ProcessRunning)
I [2018-10-31 23:19:39] INFO: simple move 'init' to 'up'
I [2018-10-31 23:19:39] INFO: simple registered 'proc_exit' event for pid 11741
I [2018-10-31 23:19:39] INFO: simple moved 'init' to 'up'
but I can't seem to capture the actual output from the watched process. The 'myprocess.log' file never gets created or written to.
But beyond that I'm just experiencing some really weird behavior. Like sometimes when I run it it spews an endless stream of output showing processes starting and exiting one after another. Sometimes it logs to files after I've renamed them. I can't get a peg on why it's behaving so erratically.
God 0.13.7 / ruby 2.3.0 / OSX 10.13.6
Check the example in the documentation that you linked to again:
God.watch do |w|
w.name = "simple"
w.start = "ruby /full/path/to/simple.rb"
w.keepalive
end
You are using a relative path, not a full path. If you try to use a relative path it's going to error out and say it can't create the log file there. This will cause it to loop through start/exit as you described.
Also, make sure that after you CTRL-C the god process that you kill your backgrounded ruby process. You can see that even after killing god that it's running with ps aux | grep ruby.
Finally, puts does log to the log file, but the output is buffered by god until the ruby process for simple.rb is terminated. Repeat this process to confirm:
# Confirm no running ruby processes, otherwise kill the processes and re-verify
ps aux | grep ruby
# Start the daemon
god -c simple.god -D
Switch to a new shell and run:
ps aux | grep ruby
foo 51279 0.0 0.1 4322084 11888 ?? Ss 12:46AM 0:00.09 ruby /Users/foo/simple.rb
foo 51241 0.0 0.2 4343944 26208 s000 S+ 12:46AM 0:00.45 ruby /Users/foo/.rvm/gems/ruby-2.6.0-preview2/bin/god -c simple.god -D
# Kill the process for simple.rb, which causes god to dump the output to the log and restart it
kill 51279
# Verify log file contains expected output
cat myprocess.log
Hello
Hello
Hello
Hello
I recommend you keep reading the documentation for god. There's a lot to it, and the answers are all there.
Related
My make serve command runs my jupyter-book fine with make serve
codio#anita-doctor:~/workspace/Introduction-to-Data-Science/IntroBook$ make serve
bundle exec guard
Configuration file: _config.yml
15:21:53 - INFO - Jekyll building...
15:21:54 - INFO - Jekyll build completed in 0.75s /home/codio/workspace/Introduction-to-Data-
Science/IntroBook → _site
15:21:54 - INFO - Jekyll watching and serving using jekyll at 0.0.0.0:4000/jupyter-book
15:21:54 - INFO - Jekyll watching
15:21:54 - INFO - LiveReload is waiting for a browser to connect.
15:21:54 - INFO - Guard is now watching at '/home/codio/workspace/Introduction-to-Data-
Science/IntroBook'
Server address: http://0.0.0.0:4000/jupyter-book/
Server running... press ctrl-c to stop.
/home/codio/anaconda/lib/ruby/gems/2.6.0/gems/guard-2.14.2/lib/guard/jobs/pry_wrapper.rb:279:
warning: method Pry#input_array is deprecated. Use Pry#inp
ut_ring instead
[1] guard(main)>
So I tried using this nohup command to run it in the background
codio#anita-doctor:~/workspace/Introduction-to-Data-Science/IntroBook$ nohup make serve >/dev/null
2>&1 &
[2] 2135
[1] Done nohup make serve < /dev/null > /dev/null 2>&1
This command or type of commands usually does nothing. I believe I may be close. But, the nohup commands do not seem to allow the ruby 'make serve' command to work. My goal is to host the server, as I did in the first line of code with the make serve command from my ubuntu box, in the background. Any help would be appreciated.
I've found that nohup can be a bit problematic. It is better to either set your server up as a service (like mysqld, sshd, etc.) or to use "at" to kick it off.
If the command works when you run it in the foreground (without nohup) then running it with "at" will work since it applies the current environment to the command and has "atd" as a parent process that won't go away when you log off (which sometimes breaks nohup when it tries to re-assign the parent process):
at now
at> make serve >>/var/log/rubyserver.log 2>&1
at> ^D
My system is Ubuntu 14, im running several game servers in screens on it, the session where the game servers are running is "alle_server", my screens are "server0", "server1" until "server9"
i have a script that should check if there is a process "server#" while # is the server-number:
#!/usr/bin/env ruby
require 'open3'
while true
x = Array.new(1)
x = Open3.capture3('ps -aux |grep "scripts/server." | grep "[0-9]$" -o')
for i in 0..10
if !(x[0].include? i.to_s)
p i
`screen -S alle_server -X screen -L /home/u220324/cod2/scripts/server#{i}`
end
end
sleep(60)
end
Ok, I know its dumb to create that array, still it shouldnt do some weird stuff.... when I run this script in a screen session (even when I don't attach it to the "alle_server" screen, sooner or later ALL screensessions disappear at the same moment), but at this moment all servers from 0 to 9 are online and not down
Is it because i try to start that server10 script which doesn't exist?
ps: I had to use that code snippet because the backticks in the code where messing it up
I'm working on a piece of code which monitors a directory and performs certain tasks when a new file is created in that directory. I'm using FSSM and my (simplified) code looks like this:
require 'fssm'
class FileWatcher
def initialize
FSSM.monitor('./temp/', '**/*', :directories => true) do
create do |base, relative|
puts "Create called with #{relative}"
end
end
end
end
FileWatcher.new
The file monitoring aspect works well, but my problem is when I halt this script. What happens is the "file_monitor" process remains running. E.g. this is after running and halting the script 3 times:
$ ps aux | grep file_watcher
root 3272 1.0 5.3 9760 6596 pts/0 Tl 00:11 0:02 ruby file_watcher.rb
root 3302 1.5 5.2 9760 6564 pts/0 Tl 00:14 0:02 ruby file_watcher.rb
root 3314 2.2 5.2 9764 6564 pts/0 Sl+ 00:14 0:02 ruby file_watcher.rb
I.e. there are 3 processes still running. So, how to clean up upon exit of the script?
Install a signal handler in the father process which triggers when it is about to get killed by a signal (SIGINT, SIGTERM, SIGQUIT, SIGHUP) and which then in turn sends an appropriate signal to the child process (FSSM monitor).
I have a few Ruby scripts: a.rb, b.rb and c.rb. These scripts are called from corresponding wrapper shell scripts: a.sh, b.sh and c.sh.
All these scripts are in a distributed environment:
`a.sh` and `a.rb` are on serverA
`b.sh` and `b.rb` are on serverB
`c.sh` and `c.rb` are on serverC
I need to write a script call.rb and its wrapper call.sh script, which should check for all the scripts currently running on the distributed environment.
I have the logic which will determine the different hosts that I have and how to communicate to these different hosts.
When any Ruby script is running, the command:
ps aux
shows:
ruby a.rb
I have no ideas on how to query for different scripts currently running. One thing to note is that there might be other Ruby scripts running in the system too, but I need to check only for a.rb, b.rb, or c.rb.
If you're doing a heartbeat check, or setting up a keep-alive check, why not have the files save their PID to a file at their startup, and then delete it when they quit?
The building blocks are:
$$ is the current process ID for a running script.
Ruby will run a block named BEGIN {} at start-up, before variables are defined. You can use that to create a PID file. Typically we use something like "#{ File.basename($0) }.pid" to create the filename.
Ruby will run a block named END {} at shut-down, as a last task. You can use that to remove the PID file.
Put the PID files in a well-known place. Where that is is left as an exercise for you to figure out for your OS.
Have your watchdog scan those, grab the PIDs, scan the process list for the PID IDs, possibly correlating them to the name of the pid file.
You can figure out more icing to put on your cake.
You can simply execute commands via SSH like this:
ssh user#host "ps -ef | grep '(ruby|[^.]+\.rb)'"
Grepping the output of ps for the script names would also work:
ps -ef | grep '(a.rb|b.rb|c.rb)'
Edit: If you don't want grep itself to show up in the process list, filter it like this:
ps -ef | grep '(a.rb|b.rb|c.rb)' | grep -v grep
If you want to solve this in Ruby, you could use a process monitoring tool like God. Monit, Bluepill or Eye
If ruby myapp.rb starts sinatra previewing at localhost:4567, how can I programatically stop/halt/kill it? Terminal command (other than Ctrl-C), or Rake tasks would be fine.
I need to incorporate this into a Rake task or terminal.
In myapp.rb, add this before sinatra starts:
puts "This is process #{Process.pid}"
When you want to kill it, do this in a shell:
kill <pid>
Where <pid> is the number outputted by myapp.rb. If you want to do it in ruby:
Process.kill 'TERM', <pid>
Both of these will let sinatra run it's exit routine. If you don't want to type in the pid every time, have myapp.rb open a file and put it's pid in it. Then when you want to stop it, read the file and use that. Example:
# myapp.rb:
File.open('myapp.pid', 'w') {|f| f.write Process.pid }
# shell:
kill `cat myapp.pid`
# ruby:
Process.kill 'TERM', File.read('myapp.pid')
In OS X, from the command line (Terminal.app, or DTerm) just enter:
$ killall ruby
every ruby process will stop. Sinatra too.
In Linux (and other UNIXes), you can:
$ ps aux | grep ruby
$ kill <ruby-process-id>
The simples way to do that:
kill #{Process.pid}
To do this in a simple repeatable way, there's a few methods.
Record the PID as you start your Sinatra server, e.g.
# Run the Sinatra server and send it to background (using &)
ruby my_sinatra_server.rb &
# Record the PID of the last background process (using $!)
MY_SINATRA_SERVER_PID=$!
# Now go ahead and do your stuff...
# When finished, kill the sinatra server (from the same shell)
kill $MY_SINATRA_SERVER_PID
Instead of using an env variable ($MY_SINATRA_SERVER) you can use a temporary file e.g. my_sinatra_server.pid
# Run the Sinatra server and send it to background (using &)
ruby my_sinatra_server.rb &
# Record the PID of the last background process (using $!)
echo $! > my_sinatra_server.pid
# Now go ahead and do your stuff...
# When finished, kill the sinatra server (from the same shell)
kill $(< my_sinatra_server.pid)