7

Im using Monit to monitor a ruby script that uses Ruby daemons gem, which launches a separate process with PID - following the instructions from Monitor ruby processes with Monit

In order to execute the ruby script I need to include RVM in the Monit start and stop strings, so I have access to all the gems.

However when .monitrc executes I get the following error:

$rvm_path (/usr/local/rvm) does not exist./home/william/.rvm/scripts/rvm: line 174: rvm_is_a_shell_function: command not found
/home/william/.rvm/scripts/rvm: line 185: __rvm_teardown: command not found
'myserver_1' failed to start
Aborting event

I added PATH=$PATH:/home/william/.rvm/bin && . /home/william/.rvm/scripts/rvm to the start and stop command strings to try and include RVM. However still it doesn't work

Config file .monitrc:

....

check process myserver_1
  with pidfile /home/william/ruby/barclays/myapp.rb.pid
  start = "/bin/bash -c 'PATH=$PATH:/home/william/.rvm/bin && . /home/william/.rvm/scripts/rvm && ruby /home/william/ruby/barclays/daemonloader.rb start'"
  stop = "/bin/bash -c 'PATH=$PATH:/home/william/.rvm/bin && . /home/william/.rvm/scripts/rvm && ruby /home/william/ruby/barclays/daemonloader.rb stop'"

  ....

Thanks for your help.

EDIT

Ive got a feeling the problem is related to environment variables. Quoting from this page

You should also know that for security reasons Monit purges the environment and only sets a spartan PATH variable that contains /bin, /usr/bin, /sbin and /usr/sbin. If your program or script dies, the reason could be that it expects certain environment variables or to find certain programs via PATH. If this is the case you should set the environment variables you need directly in the start or stop script called by monit.

Finally, Monit uses the system call execv to execute a program or a script. This means that you cannot write shell commands directly in the start, stop or exec statements. To do this, you must do as above; start a shell and issue your commands there. For example:

start program = "/bin/bash -c 'my shell command && my other command'"

Community
  • 1
  • 1
Imme22009
  • 3,992
  • 7
  • 31
  • 47

3 Answers3

3

Use this:

/path/to/rvm/bin/rvm in /path/to/project do ...

Replace the paths with proper directories for rvm and project and the ... with the commands to stop/start - try:

/usr/bin/env "HOME=/home/william rvm_path=/home/william/.rvm 
  /home/william/.rvm/bin/rvm in /home/william/ruby/project do
  ruby daemonloader.rb start"

This command will load RVM, cd into project path, load ruby for this ruby and execute given command.

mpapis
  • 52,729
  • 14
  • 121
  • 158
  • I tried this: `start = "/home/william/.rvm/bin/rvm in /home/william/ruby/project do ruby daemonloader.rb start"`. Unfortunately now I get the error message "Can't find rvm install!" and it fails. What does `xxxx in yyy do zzz` do? Could you explain the answer a little? Thanks. – Imme22009 Apr 09 '13 at 00:55
  • are you running this as the user `william`? – mpapis Apr 09 '13 at 02:44
  • Now I tried your edits also. However, now I get the error message: `/home/william/.monitrc:12: Warning: Program does not exist: 'HOME=/home/william' Error: Could not execute HOME=/home/william 'myserver_1' failed to start` (myserver_1 is the name of the process). I also tried $HOME and $rvm_path, but still it doesn't work. Are you sure this is the correct way to define a variable? (Im assuming this is what you are doing) given that the strings are NOT bash but some DSL that AFAIK is undocumented. Id appreciate if you could maybe explain the in.....do statement and how this DSL works. Thanks – Imme22009 Apr 11 '13 at 07:31
  • updated with `/usr/bin/env` -should solve the program not found problem – mpapis Apr 11 '13 at 16:08
0

You could try something like this in Monit.

start = "/bin/su - william -c 'cd /home/william/ruby/project && ~/.rvm/bin/rvm default do bundle exec ruby daemonloader.rb start'"

This worked for me.

Martin
  • 11,216
  • 23
  • 83
  • 140
0

Mentioning the gemset and ruby source solves the problem for me.

start program = "/bin/bash -c 'cd /home/project_path && source /home/user/.rvm/environments/ruby-2.4.2@global && RAILS_ENV=production bundle exec rails s'"
Kshitij
  • 339
  • 1
  • 10