Add logs in different directory using daemon in ruby - ruby

I am using daemon to wrap my script and has specified logs location into that :
Script looks like this :
#!/usr/local/bin/ruby
require 'rubygems'
require 'daemons'
Daemons.run_proc(
'script_test', # name of daemon
:log_output => true,
:output_logfilename => "script-test.log",
:logfilename => "script-test.log"
) do
exec 'ruby /opt/script-test/script-test.rb'
end
Problem is my logs are storing in same directory where my script is present. I have to add my logs to different directory such as /var/log/script-test and later have to rotate those logs weekly.
Provide me with a solution so that i can store the logs of script in /var/log directory.

Make sure you are using an absolute path instead of a relative path
For example:
:output_logfilename => "/var/log/script-test.log",
:logfilename => "/var/log/script-test.log"
In order to logrotate your logs, (assuming Linux) add the following to your logrotate config to rotate on a weekly basis:
/var/log/script-test.log {
weekly
missingok
compress
notifempty
copytruncate
}

It worked for me with this configuration as :
Daemons.run_proc(
'script-test', # name of daemon
:log_output => true,
:dir_mode => :normal,
:dir => "/var/log",
:output_logfilename => "script-test.log",
:logfilename => "script-test.log"
) do
exec 'ruby /opt/script-test/script-test.rb'
end

Related

Upload file to server and delete original using NET::SCP gem in Ruby

I'm using the net/scp gem to upload a file from my machine to a remote Linux server.
require 'net/ssh'
require 'net/scp'
Net::SCP.upload!(10.125.0.0,
user,
local_path,
remote_dir,
:ssh => { :password => psw,
:key_data => keys})
This works perfectly, however I'd like to be able to 'move' the file instead of effectively copying it across.
Is there some scpparameter that will delete the original file?
Net::SCP doesn't have any such parameter:
https://github.com/net-ssh/net-scp/blob/master/lib/net/scp.rb#L259-L267
Since the only difference between a copy and a move is just a final deletion of the source, you should do this manually after upload!.
File.delete(local_path)
You most likely will want to make sure that Net::SCP has finished before doing so:
require 'net/ssh'
require 'net/scp'
channel = Net::SCP.upload!(10.125.0.0,
user,
local_path,
remote_dir,
:ssh => { :password => psw,
:key_data => keys})
channel.wait
File.delete(local_path)

Daemons do not get restarted?

I am trying to run the same script in multiple daemons.
myapp.rb looks like this:
loop do
sleep 5
1 / 0 # crash it
end
my myapp_controller.rb:
require 'rubygems'
require 'daemons'
options = {
:log_output => true,
:backtrace => true,
:monitor => true,
:multiple => true,
:log_dir => '/mnt/log/',
:hard_exit => true
}
Daemons.run(File.join(File.dirname(__FILE__), 'myapp.rb'), options)
When I run ruby myapp_controller.rb start several times in a row, it creates that many daemons, as I expect. But, after a while, due to an error in myapp.rb the daemons crash and the monitor restarts just one and not all. So I end up with a single running daemon.
Why? What am I doing wrong?
I was able to reproduce the behavior. It is not anything you are doing wrong; it is the way the daemons gem behaves.
Going through the code for the daemons gem, turns out the :multiple option doesn't work well with the :monitor option.
The :monitor option works only when the daemon is run in single mode.
I have created a bug report on the daemons project page referencing this question as the source.
More info about the reproduction of the issue:
Multiple daemon processes are created when :multiple => true. Each process has its own pid file in the format of <scriptname>.rb<number>.pid.
However, only one monitor process is created (with a single <scriptname>.rb_monitor.pid file.)
Here are the list of processes started when I start the daemon process 3 times:
$ ps -fe | grep my_server
501 1758 1 0 12:25PM ?? 0:00.63 my_server.rb
501 1759 1 0 12:25PM ?? 0:00.43 my_server.rb_monitor
501 1764 1 0 12:25PM ?? 0:00.54 my_server.rb
501 1834 1 0 12:51PM ?? 0:00.31 my_server.rb
The files in the pid/log folder:
$ ls /tmp/daemons-2013-01-25/
my_server.rb.log my_server.rb1.pid my_server.rb_monitor.pid
my_server.rb0.pid my_server.rb2.pid
Until the issue is resolved, you can change your code to something like this:
#myapp_controller.rb
require 'rubygems'
require 'daemons'
number = ARGV.fetch(1)
options = {
:app_name => "daemon-#{number}" # provide app_name
:log_output => true,
:backtrace => true,
:monitor => true,
:multiple => false, # disable multiple option
:log_dir => '/mnt/log/',
:hard_exit => true
}
Daemons.run(File.join(File.dirname(__FILE__), 'myapp.rb'), options)
And then start your daemons with these commands:
ruby myapp_controller.rb start 1
ruby myapp_controller.rb start 2
...
This slightly changes your startup code, but now you will have a monitor process for each of your daemon processes.

How to set an environment variable on a server with puppet?

I'm starting to use puppet in my current project and I'm having some issues.
I'm using a recipe to install jruby, but I want to set a environment variable (in this case, JRUBY_HOME and modify the PATH to include JRUBY_HOME/bin) after it finishes installing jruby.
Here's the recipe:
class jruby {
$jruby_home = "/opt/jruby"
exec { "download_jruby":
command => "wget http://jruby.org.s3.amazonaws.com/downloads/1.7.0.RC2/jruby-bin-1.7.0.RC2.tar.gz",
path => $path,
timeout => 0,
unless => "ls /opt | grep jruby-1.7.0",
require => Package["openjdk-7-jre-headless"]
}
exec { "unpack_jruby" :
command => "tar -zxf jruby-bin-1.7.0.RC2.tar.gz -C /opt",
path => $path,
creates => "${jruby_home}-1.7.0.RC2",
require => Exec["download_jruby"]
}
file { $jruby_home:
ensure => link,
target => "${jruby_home}-1.7.0.RC2",
require => Exec["unpack_jruby"]
}
}
So, what's the best way to add /opt/jruby as JRUBY_HOME and then add JRUBY_HOME/bin to PATH?
Solved it:
# init.pp
$jruby_sh = "/etc/profile.d/jruby.sh"
file { $jruby_sh:
ensure => present,
source => "puppet:///modules/jruby/jruby.sh",
owner => "root",
group => "root",
mode => 644,
require => File[$jruby_home]
}
# jruby.sh
export JRUBY_HOME=/opt/jruby
export PATH=$PATH:$JRUBY_HOME/bin

Gem Daemons - How to run several different daemons

Basically I just want to run several daemons in my ruby script :
require 'daemons'
Daemons.run path_1, { :ARGV => ['start'], :app_name => 'app1', :multiple => true, ... }
Daemons.run path_2, { :ARGV => ['start'], :app_name => 'app2', :multiple => true, ... }
But the second Daemons.run is never called when ARGV[0] == 'start' (works perfectly with 'status'/'stop'). What is the right way to do it ?
from http://daemons.rubyforge.org
3- Control a bunch of daemons from another application
Layout: you have an application my_app.rb that wants to run a bunch of server tasks as daemon processes.
# this is my_app.rb
require 'rubygems' # if you use RubyGems
require 'daemons'
task1 = Daemons.call(:multiple => true) do
# first server task
loop {
conn = accept_conn()
serve(conn)
}
end
task2 = Daemons.call do
# second server task
loop {
something_different()
}
end
# the parent process continues to run
# we can even control our tasks, for example stop them
task1.stop
task2.stop
exit
does it fit?

Ruby Daemons log rotation

When I'm setting logging parameters to the Daemons (1.1.0) gem, how would I achieve similar behavior to this line?
logger = Logger.new('foo.log', 10, 1024000)
Daemon options:
options = {
:ARGV => ['start'],
:dir_mode => :normal,
:dir => log_dir,
:multiple => false,
:ontop => false
:mode => :exec,
:backtrace => true,
:log_output => true
}
Unfortunately the Daemons gem does not use Logger. It redirects STDOUT and STDERR directly to a file.
You can see the details of how the redirection works here:
https://github.com/ghazel/daemons/blob/master/lib/daemons/daemonize.rb#L241-261
Because of this, you will have to use something like logrotate and restart the daemon if you want to do log file rotation.
If this is not acceptable, I would suggest using Logger directly like you provided in the question.

Resources