Hello community, here is the log from the commit of package rubygem-daemons for openSUSE:Factory checked in at 2016-08-25 09:55:15 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/rubygem-daemons (Old) and /work/SRC/openSUSE:Factory/.rubygem-daemons.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rubygem-daemons" Changes: -------- --- /work/SRC/openSUSE:Factory/rubygem-daemons/rubygem-daemons.changes 2015-06-30 10:16:37.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.rubygem-daemons.new/rubygem-daemons.changes 2016-08-25 09:55:16.000000000 +0200 @@ -1,0 +2,6 @@ +Wed Aug 3 04:30:21 UTC 2016 - [email protected] + +- updated to version 1.2.4 + no changelog found + +------------------------------------------------------------------- Old: ---- daemons-1.2.3.gem New: ---- daemons-1.2.4.gem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ rubygem-daemons.spec ++++++ --- /var/tmp/diff_new_pack.eJIEs0/_old 2016-08-25 09:55:17.000000000 +0200 +++ /var/tmp/diff_new_pack.eJIEs0/_new 2016-08-25 09:55:17.000000000 +0200 @@ -1,7 +1,7 @@ # # spec file for package rubygem-daemons # -# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -24,7 +24,7 @@ # Name: rubygem-daemons -Version: 1.2.3 +Version: 1.2.4 Release: 0 %define mod_name daemons %define mod_full_name %{mod_name}-%{version} ++++++ daemons-1.2.3.gem -> daemons-1.2.4.gem ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/LICENSE new/LICENSE --- old/LICENSE 2015-06-25 22:24:19.000000000 +0200 +++ new/LICENSE 2016-08-02 20:22:22.000000000 +0200 @@ -1,4 +1,4 @@ -Copyright (c) 2005-2015 Thomas Uehlinger, 2014-2015 Aaron Stone +Copyright (c) 2005-2016 Thomas Uehlinger, 2014-2016 Aaron Stone Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/README.md new/README.md --- old/README.md 2015-06-25 22:24:19.000000000 +0200 +++ new/README.md 2016-08-02 20:22:22.000000000 +0200 @@ -1,5 +1,6 @@ Ruby Daemons ============ +[](https://codeclimate.com/github/acuppy/daemons)[](https://circleci.com/gh/acuppy/daemons) Daemons provides an easy way to wrap existing ruby scripts (for example a self-written server) to be _run as a daemon_ and to be _controlled by simple start/stop/restart commands_. @@ -203,4 +204,4 @@ Author ------ -Written 2005-2015 by Thomas Uehlinger <[email protected]>, 2014-2015 by Aaron Stone <[email protected]>. +Written 2005-2016 by Thomas Uehlinger, 2014-2016 by Aaron Stone. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Releases new/Releases --- old/Releases 2015-06-25 22:24:19.000000000 +0200 +++ new/Releases 2016-08-02 20:22:22.000000000 +0200 @@ -1,5 +1,11 @@ = Daemons Release History +== Release 1.2.4: August 1, 2016 + +* add :shush option +* add :monitor_interval option +* add :log_output_syslog option + == Release 1.2.3: June 25, 2015 * fix: ApplicationGroup now waits on subprocesses in start_all (thanks to tobithiel) @@ -27,12 +33,12 @@ == Release 1.1.9: August 10, 2012 -* daemonize.rb: do srand in the forked child process both in daemonize and call_as_daemon +* daemonize.rb: do srand in the forked child process both in daemonize and call_as_daemon (thanks to Andrew Havens). == Release 1.1.8: February 7, 2012 -* rename to daemonization.rb to daemonize.rb (and Daemonization to Daemonize) to +* rename to daemonization.rb to daemonize.rb (and Daemonization to Daemonize) to ensure compatibility. == Release 1.1.7: February 6, 2012 @@ -46,57 +52,57 @@ == Release 1.1.5: December 19, 2011 -* Catch the case where the pidfile is empty but not deleted +* Catch the case where the pidfile is empty but not deleted and restart the app (thanks to Rich Healey) == Release 1.1.4: June 17, 2011 -* Do not change the umask to 0000 when daemonizing anymore, just leave it as it +* Do not change the umask to 0000 when daemonizing anymore, just leave it as it was (thanks to Jon Botelho). == Release 1.1.3: April 14, 2011 * Fixed a bug in Application.stop: the cached pid number needs to be used to check for the status of a killed process (thanks to Jimmy Sieben). - + == Release 1.1.2: March 29, 2011 * Fixed gemspec to include all needed files. - + == Release 1.1.1: March 29, 2011 -* Make the logging facilities work in :mode => :none (i.e. when calling +* Make the logging facilities work in :mode => :none (i.e. when calling Daemons.daemonize) (thanks to the input from Peter Hegedus). - + == Release 1.1.0: June 20, 2010 * Honour the options[:app_name] in Daemons.daemonize (thanks to Ryan Tecco). -* Included a new option :stop_proc to specify a proc that will be called when a +* Included a new option :stop_proc to specify a proc that will be called when a daemonized process receives a request to stop (thanks to Dave Dupre). * Only delete the pidfile if the current pid is the original pid (ghazel). * Start when restart but no application running (pcreux). * Silently continue if there is no pidfile (ghazel). * We now per default wait for processes to stop and - kill them automatically it if they do not stop within a given time - (force_kill_waittime). Use the option --no_wait to not wait for processes to + kill them automatically it if they do not stop within a given time + (force_kill_waittime). Use the option --no_wait to not wait for processes to stop. * Set log files mode to 0644 (mikehale). * Set pid file permissions to 0644 (mikehale). * Added ability to change process uid/gid (mikehale). -* Fix for: If you happen to start a daemon from a process that has open file - descriptors these will stay open. As it is daemonize.rb only closes ruby IO +* Fix for: If you happen to start a daemon from a process that has open file + descriptors these will stay open. As it is daemonize.rb only closes ruby IO objects (thanks to Han Holl). * New reload command (SIGHUP) (thanks to Michael Schuerig). == Release 1.0.10: March 21, 2008 -* By default, we now delete stray pid-files (i.e. pid-files which result for - example from a killed daemon) automatically. This function can be deactivated +* By default, we now delete stray pid-files (i.e. pid-files which result for + example from a killed daemon) automatically. This function can be deactivated by passing :keep_pid_files => true as an option. -* All pid files of :multiple daemons new get deleted correctly upon exit of the +* All pid files of :multiple daemons new get deleted correctly upon exit of the daemons (reported by Han Holl). * Use the signal 'KILL' instead of 'TERM' on Windows platforms. -* Use exit! in trap('TERM') instead of exit when option :hard_exit is given +* Use exit! in trap('TERM') instead of exit when option :hard_exit is given (thanks to Han Holl). * Did some clarification on the exception log. @@ -107,12 +113,12 @@ == Release 1.0.8: September 24, 2007 -* new Pid.running? function. Checking whether a process exists by sending +* new Pid.running? function. Checking whether a process exists by sending signal '0' (thanks to Dru Nelson). == Release 1.0.7: July 7, 2007 -* Patch to fix wrong ARGV when using :exec (in def start_exec: +* Patch to fix wrong ARGV when using :exec (in def start_exec: Kernel.exec(script(), *(@app_argv || []))) (thanks to Alex McGuire). == Release 1.0.6: Mai 8, 2007 @@ -122,7 +128,7 @@ == Release 1.0.5: February 24, 2007 -* Applied patch that makes daemons to use '/var/log' as logfile +* Applied patch that makes daemons to use '/var/log' as logfile directory if you use :dir_mode = :system (thanks to Han Holl). * Daemons should now work with Ruby 1.9 (at least the basic features). @@ -130,7 +136,7 @@ * Document the :log_output option (thanks to Andrew Kuklewicz). * Set STDOUT.sync = true when redirecting to a logfile (thanks to Andrew Kuklewicz). -* Should now run also correctly when there is no working 'ps ax' on the system +* Should now run also correctly when there is no working 'ps ax' on the system (thanks to Daniel Kehoe). == Release 1.0.3: November 1, 2006 @@ -142,7 +148,7 @@ * Changed the 'ps -ax' call back to 'ps ax'. * Fixed the documentation for the :normal :dir_mode. * As a default for Daemons.run_proc, the pid file is now saved in the current directory. -* In :ontop mode for running a proc (this is equal to calling something like 'ruby ctrl_proc.rb run'), +* In :ontop mode for running a proc (this is equal to calling something like 'ruby ctrl_proc.rb run'), the proc now runs directly in the calling script, not in a forked process anymore (thanks to Paul Butcher). * Set $0 to app_name in the daemons (thanks to Ilya Novoselov). @@ -156,7 +162,7 @@ == Release 0.4.4: February 14, 2006 -* Several fixes that allow us to use the Daemons::Controller +* Several fixes that allow us to use the Daemons::Controller with a proc instead of wrapping a script file. This gives us all the PID file management, monitoring, command line options, etc. without having to specify a path to our script which can be tricky, especially when using @@ -168,7 +174,7 @@ on calling Daemons.run. This will be used to contruct the name of the pid files and log files. Defaults to the basename of the script. (thanks to Stephen R. Veit) -* Bugfix: Handle the case where no controller options are given when calling Daemons, +* Bugfix: Handle the case where no controller options are given when calling Daemons, just options after "--". (thanks to Stephen R. Veit) Files old/checksums.yaml.gz and new/checksums.yaml.gz differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/examples/run/ctrl_optionparser.rb new/examples/run/ctrl_optionparser.rb --- old/examples/run/ctrl_optionparser.rb 2015-06-25 22:24:19.000000000 +0200 +++ new/examples/run/ctrl_optionparser.rb 2016-08-02 20:22:22.000000000 +0200 @@ -28,7 +28,7 @@ def run Daemons.run_proc('myapp', :ARGV => @args, :ontop => [email protected]) do puts "@options.daemonize: #{@options.daemonize}" - STDOUT.sync = true + $stdout.sync = true loop do print '.' sleep(2) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/daemons/application.rb new/lib/daemons/application.rb --- old/lib/daemons/application.rb 2015-06-25 22:24:19.000000000 +0200 +++ new/lib/daemons/application.rb 2016-08-02 20:22:22.000000000 +0200 @@ -3,6 +3,7 @@ require 'daemons/change_privilege' require 'daemons/daemonize' require 'daemons/exceptions' +require 'daemons/reporter' require 'timeout' @@ -33,6 +34,8 @@ @show_status_callback = method(:default_show_status) + @report = Reporter.new(@options) + unless @pid = pid if @options[:no_pidfiles] @pid = PidMem.new @@ -51,47 +54,45 @@ def change_privilege user = options[:user] group = options[:group] - CurrentProcess.change_privilege(user, group) if user + if user + @report.changing_process_privilege(user, group) + CurrentProcess.change_privilege(user, group) + end end def script - @script || @group.script + @script or group.script end def pidfile_dir - Pid.dir(@dir_mode || @group.dir_mode, @dir || @group.dir, @script || @group.script) + Pid.dir dir_mode, dir, script end def logdir - logdir = options[:log_dir] - unless logdir - logdir = options[:dir_mode] == :system ? '/var/log' : pidfile_dir - end - logdir + options[:log_dir] or + options[:dir_mode] == :system ? '/var/log' : pidfile_dir end def output_logfilename - filename = options[:output_logfilename] - unless filename - filename = @group.app_name + '.output' - end - filename + options[:output_logfilename] or "#{@group.app_name}.output" end - + def output_logfile - (options[:log_output] && logdir) ? File.join(logdir, output_logfilename) : nil + if log_output_syslog? + 'SYSLOG' + elsif log_output? + File.join logdir, output_logfilename + end end def logfilename - filename = options[:logfilename] - unless filename - filename = @group.app_name + '.log' - end - filename + options[:logfilename] or "#{@group.app_name}.log" end - + def logfile - logdir ? File.join(logdir, logfilename) : nil + if logdir + File.join logdir, logfilename + end end # this function is only used to daemonize the currently running process (Daemons.daemonize) @@ -139,7 +140,7 @@ def start_exec if options[:backtrace] - puts 'option :backtrace is not supported with :mode => :exec, ignoring' + @report.backtrace_not_supported end unless options[:ontop] @@ -152,7 +153,7 @@ @pid.pid = Process.pid ENV['DAEMONS_ARGV'] = @controller_argv.join(' ') - + started Kernel.exec(script, *(@app_argv || [])) end @@ -300,8 +301,7 @@ def started if pid = @pid.pid - puts "#{group.app_name}: process with pid #{pid} started." - STDOUT.flush + @report.process_started(group.app_name, pid) end end @@ -324,7 +324,7 @@ # one cannot catch exceptions that are thrown in threads other than the main # thread. # - # This function searches for all exceptions in memory and outputs them to STDERR + # This function searches for all exceptions in memory and outputs them to $stderr # (if it is connected) and to a log file in the pid-file directory. # def exception_log @@ -373,14 +373,14 @@ begin Process.kill(SIGNAL, pid) rescue Errno::ESRCH => e - puts "#{e} #{pid}" - puts 'deleting pid-file.' + @report.output_message("#{e} #{pid}") + @report.output_message('deleting pid-file.') end unless no_wait if @force_kill_waittime > 0 - puts "#{group.app_name}: trying to stop process with pid #{pid}..." - STDOUT.flush + @report.stopping_process(group.app_name, pid) + $stdout.flush begin Timeout.timeout(@force_kill_waittime, TimeoutError) do @@ -389,8 +389,8 @@ end end rescue TimeoutError - puts "#{group.app_name}: process with pid #{pid} won't stop, we forcefully kill it..." - STDOUT.flush + @report.forcefully_stopping_process(group.app_name, pid) + $stdout.flush begin Process.kill('KILL', pid) @@ -404,8 +404,8 @@ end end rescue TimeoutError - puts "#{group.app_name}: unable to forcefully kill process with pid #{pid}." - STDOUT.flush + @report.cannot_stop_process(group.app_name, pid) + $stdout.flush end end end @@ -418,8 +418,8 @@ # didn't clean it up. begin; @pid.cleanup; rescue ::Exception; end - puts "#{group.app_name}: process with pid #{pid} successfully stopped." - STDOUT.flush + @report.stopped_process(group.app_name, pid) + $stdout.flush end end @@ -438,7 +438,7 @@ def default_show_status(daemon = self) running = daemon.running? - puts "#{group.app_name}: #{running ? '' : 'not '}running#{(running and daemon.pid.exist?) ? ' [pid ' + daemon.pid.pid.to_s + ']' : ''}#{(daemon.pid.exist? and not running) ? ' (but pid-file exists: ' + daemon.pid.pid.to_s + ')' : ''}" + @report.status(group.app_name, running, daemon.pid.exist?, daemon.pid.pid.to_s) end # This function implements a (probably too simle) method to detect @@ -449,11 +449,25 @@ # system. # def running? - if @pid.exist? - return Pid.running?(@pid.pid) - end + @pid.exist? and Pid.running? @pid.pid + end + + private + + def log_output? + options[:log_output] && logdir + end + + def log_output_syslog? + options[:log_output_syslog] + end + + def dir_mode + @dir_mode or group.dir_mode + end - false + def dir + @dir or group.dir end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/daemons/application_group.rb new/lib/daemons/application_group.rb --- old/lib/daemons/application_group.rb 2015-06-25 22:24:19.000000000 +0200 +++ new/lib/daemons/application_group.rb 2016-08-02 20:22:22.000000000 +0200 @@ -69,7 +69,7 @@ if x && x.chomp! processes = x.split(/\n/).compact processes = processes.delete_if do |p| - pid, name, add = p.split(/\s/) + _pid, name, add = p.split(/\s/) # We want to make sure that the first part of the process name matches # so that app_name matches app_name_22 @@ -90,7 +90,11 @@ def find_applications_by_pidfiles(dir) @monitor = Monitor.find(dir, app_name + '_monitor') - pid_files = PidFile.find_files(dir, app_name, ! @keep_pid_files) + reporter = Reporter.new(options) + pid_files = PidFile.find_files(dir, app_name, ! @keep_pid_files) do |pid, file| + reporter.deleted_found_pidfile(pid, file) + end + pid_files.map do |f| app = Application.new(self, {}, PidFile.existing(f)) setup_app(app) @@ -137,7 +141,9 @@ end if options[:monitor] - @monitor = Monitor.new(an_app) + opt = {} + opt[:monitor_interval] = options[:monitor_interval] if options[:monitor_interval] + @monitor = Monitor.new(an_app, opt) @monitor.start(self) end end @@ -186,12 +192,12 @@ def show_status @applications.each { |a| a.show_status } end - + # Check whether at least one of the applications in the group is running. If yes, return true. def running? @applications.each { |a| return true if a.running? } return false end - + end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/daemons/change_privilege.rb new/lib/daemons/change_privilege.rb --- old/lib/daemons/change_privilege.rb 2015-06-25 22:24:19.000000000 +0200 +++ new/lib/daemons/change_privilege.rb 2016-08-02 20:22:22.000000000 +0200 @@ -2,8 +2,6 @@ class CurrentProcess def self.change_privilege(user, group = user) - puts "Changing process privilege to #{user}:#{group}" - uid, gid = Process.euid, Process.egid target_uid = Etc.getpwnam(user).uid target_gid = Etc.getgrnam(group).gid diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/daemons/cmdline.rb new/lib/daemons/cmdline.rb --- old/lib/daemons/cmdline.rb 2015-06-25 22:24:19.000000000 +0200 +++ new/lib/daemons/cmdline.rb 2016-08-02 20:22:22.000000000 +0200 @@ -12,6 +12,10 @@ opts.on('-t', '--ontop', 'Stay on top (does not daemonize)') do |t| @options[:ontop] = t end + + opts.on('-s', '--shush', 'Silent mode (no output to the terminal)') do |t| + @options[:shush] = t + end opts.on('-f', '--force', 'Force operation') do |t| @options[:force] = t diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/daemons/daemonize.rb new/lib/daemons/daemonize.rb --- old/lib/daemons/daemonize.rb 2015-06-25 22:24:19.000000000 +0200 +++ new/lib/daemons/daemonize.rb 2016-08-02 20:22:22.000000000 +0200 @@ -19,7 +19,7 @@ module_function :safefork # Simulate the daemonization process (:ontop mode) - # NOTE: STDOUT and STDERR will not be redirected to the logfile, + # NOTE: $stdout and $stderr will not be redirected to the logfile, # because in :ontop mode, we normally want to see the output def simulate(logfile_name = nil, app_name = nil) $0 = app_name if app_name @@ -29,8 +29,8 @@ close_io - # Free STDIN and point it to somewhere sensible - begin; STDIN.reopen '/dev/null'; rescue ::Exception; end + # Free $stdin and point it to somewhere sensible + begin; $stdin.reopen '/dev/null'; rescue ::Exception; end # Split rand streams between spawning and daemonized process srand @@ -58,7 +58,7 @@ rd.close # Detach from the controlling terminal - unless sess_id = Process.setsid + unless Process.setsid fail Daemons.RuntimeException.new('cannot detach from controlling terminal') end @@ -100,7 +100,7 @@ # Prevent the possibility of acquiring a controlling terminal trap 'SIGHUP', 'IGNORE' - exit if pid = safefork + exit if safefork $0 = app_name if app_name @@ -120,40 +120,49 @@ def close_io # Make sure all input/output streams are closed - # Part I: close all IO objects (except for STDIN/STDOUT/STDERR) + # Part I: close all IO objects (except for $stdin/$stdout/$stderr) ObjectSpace.each_object(IO) do |io| - unless [STDIN, STDOUT, STDERR].include?(io) + unless [$stdin, $stdout, $stderr].include?(io) io.close rescue nil end end # Make sure all input/output streams are closed - # Part II: close all file decriptors (except for STDIN/STDOUT/STDERR) + # Part II: close all file decriptors (except for $stdin/$stdout/$stderr) 3.upto(8192) do |i| IO.for_fd(i).close rescue nil end end module_function :close_io - # Free STDIN/STDOUT/STDERR file descriptors and + # Free $stdin/$stdout/$stderr file descriptors and # point them somewhere sensible def redirect_io(logfile_name) - begin; STDIN.reopen '/dev/null'; rescue ::Exception; end + begin; $stdin.reopen '/dev/null'; rescue ::Exception; end - if logfile_name + if logfile_name == 'SYSLOG' + # attempt to use syslog via syslogio begin - STDOUT.reopen logfile_name, 'a' - File.chmod(0644, logfile_name) - STDOUT.sync = true + require 'syslogio' + $stdout = ::Daemons::SyslogIO.new($0, :local0, :info, $stdout) + $stderr = ::Daemons::SyslogIO.new($0, :local0, :err, $stderr) + # error out early so we can fallback to null + $stdout.puts "no logfile provided, output redirected to syslog" rescue ::Exception - begin; STDOUT.reopen '/dev/null'; rescue ::Exception; end + # on unsupported platforms simply reopen /dev/null + begin; $stdout.reopen '/dev/null'; rescue ::Exception; end + begin; $stderr.reopen '/dev/null'; rescue ::Exception; end end + elsif logfile_name + $stdout.reopen logfile_name, 'a' + File.chmod(0644, logfile_name) + $stdout.sync = true + begin; $stderr.reopen $stdout; rescue ::Exception; end + $stderr.sync = true else - begin; STDOUT.reopen '/dev/null'; rescue ::Exception; end + begin; $stdout.reopen '/dev/null'; rescue ::Exception; end + begin; $stderr.reopen '/dev/null'; rescue ::Exception; end end - - begin; STDERR.reopen STDOUT; rescue ::Exception; end - STDERR.sync = true end module_function :redirect_io end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/daemons/etc_extension.rb new/lib/daemons/etc_extension.rb --- old/lib/daemons/etc_extension.rb 2015-06-25 22:24:19.000000000 +0200 +++ new/lib/daemons/etc_extension.rb 2016-08-02 20:22:22.000000000 +0200 @@ -3,11 +3,9 @@ Etc.instance_eval do def groupname(gid) Etc.group { |e| return e.name if gid == e.gid } - nil end def username(uid) Etc.passwd { |e| return e.name if uid == e.uid } - nil end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/daemons/exceptions.rb new/lib/daemons/exceptions.rb --- old/lib/daemons/exceptions.rb 2015-06-25 22:24:19.000000000 +0200 +++ new/lib/daemons/exceptions.rb 2016-08-02 20:22:22.000000000 +0200 @@ -1,6 +1,5 @@ - module Daemons - class Exception < ::RuntimeError + class Exception < RuntimeError end class RuntimeException < Exception diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/daemons/monitor.rb new/lib/daemons/monitor.rb --- old/lib/daemons/monitor.rb 2015-06-25 22:24:19.000000000 +0200 +++ new/lib/daemons/monitor.rb 2016-08-02 20:22:22.000000000 +0200 @@ -25,9 +25,10 @@ nil end - def initialize(an_app) + def initialize(an_app, options = {}) @app = an_app @app_name = an_app.group.app_name + '_monitor' + @monitor_interval = options[:monitor_interval] || 30 if an_app.pidfile_dir @pid = PidFile.new(an_app.pidfile_dir, @app_name, false) @@ -46,13 +47,13 @@ sleep(1) - Process.detach(fork { a.start(restart = true) }) + Process.detach(fork { a.start(true) }) sleep(5) end end - sleep(30) + sleep(@monitor_interval) end end private :watch @@ -105,8 +106,8 @@ end end rescue ::Exception => e - puts "exception while trying to stop monitor process #{pid}: #{e}" - puts 'deleting pid-file.' + $stderr.puts "exception while trying to stop monitor process #{pid}: #{e}" + $stderr.puts 'deleting pid-file.' end # We try to remove the pid-files by ourselves, in case the monitor diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/daemons/pidfile.rb new/lib/daemons/pidfile.rb --- old/lib/daemons/pidfile.rb 2015-06-25 22:24:19.000000000 +0200 +++ new/lib/daemons/pidfile.rb 2016-08-02 20:22:22.000000000 +0200 @@ -40,8 +40,8 @@ pid = File.open(f) { |h| h.read }.to_i rsl = !Pid.running?(pid) if rsl - puts "pid-file for killed process #{pid} found (#{f}), deleting." begin; File.unlink(f); rescue ::Exception; end + yield(pid, f) if block_given? end rsl end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/daemons/reporter.rb new/lib/daemons/reporter.rb --- old/lib/daemons/reporter.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/lib/daemons/reporter.rb 2016-08-02 20:22:22.000000000 +0200 @@ -0,0 +1,55 @@ +module Daemons + class Reporter + attr_reader :options + + def initialize(options) + @options = options + + if !options[:shush] + $stdout.sync = true + end + end + + def output_message(message) + if !options[:shush] + puts message + end + end + + def changing_process_privilege(user, group = user) + output_message "Changing process privilege to #{user}:#{group}" + end + + def deleted_found_pidfile(pid, f) + output_message "pid-file for killed process #{pid} found (#{f}), deleting." + end + + def process_started(app_name, pid) + output_message "#{app_name}: process with pid #{pid} started." + end + + def backtrace_not_supported + output_message 'option :backtrace is not supported with :mode => :exec, ignoring' + end + + def stopping_process(app_name, pid) + output_message "#{app_name}: trying to stop process with pid #{pid}..." + end + + def forcefully_stopping_process(app_name, pid) + output_message "#{app_name}: process with pid #{pid} won't stop, we forcefully kill it..." + end + + def cannot_stop_process(app_name, pid) + output_message "#{app_name}: unable to forcefully kill process with pid #{pid}." + end + + def stopped_process(app_name, pid) + output_message "#{app_name}: process with pid #{pid} successfully stopped." + end + + def status(app_name, running, pid_exists, pid) + output_message "#{app_name}: #{running ? '' : 'not '}running#{(running and pid_exists) ? ' [pid ' + pid.to_s + ']' : ''}#{(pid_exists and not running) ? ' (but pid-file exists: ' + pid.to_s + ')' : ''}" + end + end +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/daemons/syslogio.rb new/lib/daemons/syslogio.rb --- old/lib/daemons/syslogio.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/lib/daemons/syslogio.rb 2016-08-02 20:22:22.000000000 +0200 @@ -0,0 +1,240 @@ +# This is a simple class meant to allow using syslog through an IO-like object. Code +# borrowed from https://github.com/phemmer/ruby-syslogio +# +# The usage is simple: +# +# require 'syslogio' +# $stdout = SyslogIO.new("myapp", :local0, :info, $stdout) +# $stderr = SyslogIO.new("myapp", :local0, :err, $stderr) +# $stdout.puts "This is a message" +# $stderr.puts "This is an error" +# raise StandardError, 'This will get written through the SyslogIO for $stderr' + +class Daemons::SyslogIO + require 'syslog' + + # Indicates whether synchonous IO is enabled. + # @return [Boolean] + attr_reader :sync + + # @!visibility private + def self.syslog_constant_sym(option) + return unless option.is_a?(Symbol) or option.is_a?(String) + option = option.to_s.upcase + option = "LOG_#{option}" unless option[0..4] == 'LOG_' + option = option.to_sym + option + end + # @!visibility private + def self.syslog_constant(option) + return unless option = syslog_constant_sym(option) + return Syslog.constants.include?(option) ? Syslog.const_get(option) : nil + end + # @!visibility private + def self.syslog_facility(option) + return unless option = syslog_constant_sym(option) + return Syslog::Facility.constants.include?(option) ? Syslog.const_get(option) : nil + end + # @!visibility private + def self.syslog_level(option) + return unless option = syslog_constant_sym(option) + return Syslog::Level.constants.include?(option) ? Syslog.const_get(option) : nil + end + # @!visibility private + def self.syslog_option(option) + return unless option = syslog_constant_sym(option) + return Syslog::Option.constants.include?(option) ? Syslog.const_get(option) : nil + end + + # Creates a new object. + # You can have as many SyslogIO objects as you like. However because they all share the same syslog connection, some parameters are shared. The identifier shared among all SyslogIO objects, and is set to the value of the last one created. The Syslog options are merged together as a combination of all objects. The facility and level are distinct between each though. + # If an IO object is provided as an argument, any text written to the SyslogIO object will also be passed through to that IO object. + # + # @param identifier [String] Identifier + # @param facility [Fixnum<Syslog::Facility>] Syslog facility + # @param level [Fixnum<Syslog::Level>] Syslog level + # @param option [Fixnum<Syslog::Options>] Syslog option + # @param passthrough [IO] IO passthrough + def initialize(*options) + options.each do |option| + if option.is_a?(String) + @ident = option + elsif value = self.class.syslog_facility(option) + @facility = value + elsif value = self.class.syslog_level(option) + @level = value + elsif value = self.class.syslog_option(option) + @options = 0 if @options.nil? + @options |= value + elsif option.is_a?(IO) + @out = option + else + raise ArgumentError, "Unknown argument #{option.inspect}" + end + end + + @options ||= 0 + @ident ||= $0.sub(/.*\//, '') + @facility ||= Syslog::LOG_USER + @level ||= Syslog::LOG_INFO + + if Syslog.opened? then + options = Syslog.options | @options + @syslog = Syslog.reopen(@ident, options, @facility) + else + @syslog = Syslog.open(@ident, @options, @facility) + end + + @subs = [] + @sync = false + @buffer = '' + + at_exit { flush } + end + + # Add a substitution rule + # + # These substitutions will be applied to each line before it is logged. This can be useful if some other gem is generating log content and you want to change the formatting. + # @param regex [Regex] + def sub_add(regex, replacement) + @subs << [regex, replacement] + end + + # Enable or disable synchronous IO (buffering). + # + # When false (default), output will be line buffered. For syslog this is optimal so the log entries are complete lines. + def sync=(sync) + if sync != true and sync != false then + raise ArgumentError, "sync must be true or false" + end + @sync = sync + if sync == true then + flush + end + end + + # Write to syslog respecting the behavior of the {#sync} setting. + def write(text) + if @sync then + syswrite(text) + else + text.split(/(\n)/).each do |line| + @buffer = @buffer + line.to_s + if line == "\n" then + flush + end + end + end + end + alias_method :<<, :write + + # Write to syslog directly, bypassing buffering if enabled. + def syswrite(text) + begin + @out.syswrite(text) if @out and [email protected]? + rescue SystemCallError => e + end + + text.split(/\n/).each do |line| + @subs.each do |sub| + line.sub!(sub[0], sub[1]) + end + if line == '' or line.match(/^\s*$/) then + next + end + Syslog.log(@facility | @level, line) + end + nil + end + + # Immediately flush any buffered data + def flush + syswrite(@buffer) + @buffer = '' + end + + # Log at the debug level + # + # Shorthand for {#log}(text, Syslog::LOG_DEBUG) + def debug(text) + log(text, Syslog::LOG_DEBUG) + end + + # Log at the info level + # + # Shorthand for {#log}(text, Syslog::LOG_INFO) + def info(text) + log(text, Syslog::LOG_INFO) + end + + # Log at the notice level + # + # Shorthand for {#log}(text, Syslog::LOG_NOTICE) + def notice(text) + log(text, Syslog::LOG_NOTICE) + end + alias_method :notify, :notice + + # Log at the warning level + # + # Shorthand for {#log}(text, Syslog::LOG_WARNING) + def warn(text) + log(text, Syslog::LOG_WARNING) + end + + # Log at the error level + # + # Shorthand for {#log}(text, Syslog::LOG_ERR) + def error(text) + log(text, Syslog::LOG_ERR) + end + + # Log at the critical level + # + # Shorthand for {#log}(text, Syslog::LOG_CRIT) + def crit(text) + log(text, Syslog::LOG_CRIT) + end + alias_method :fatal, :crit + + # Log at the emergency level + # + # Shorthand for {#log}(text, Syslog::LOG_EMERG) + def emerg(text) + log(text, Syslog::LOG_EMERG) + end + + # Log a complete line + # + # Similar to {#write} but appends a newline if not present. + def puts(*texts) + texts.each do |text| + write(text.chomp + "\n") + end + end + + # Write a complete line at the specified log level + # + # Similar to {#puts} but allows changing the log level for just this one message + def log(text, level = nil) + if priority.nil? then + write(text.chomp + "\n") + else + priority_bkup = @priority + #TODO fix this to be less ugly. Temporarily setting an instance variable is evil + @priority = priority + write(text.chomp + "\n") + @priority = priority_bkup + end + end + + # @!visibility private + def noop(*args) + end + alias_method :reopen, :noop + + # false + def isatty + false + end +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/daemons/version.rb new/lib/daemons/version.rb --- old/lib/daemons/version.rb 2015-06-25 22:24:19.000000000 +0200 +++ new/lib/daemons/version.rb 2016-08-02 20:22:22.000000000 +0200 @@ -1,3 +1,3 @@ module Daemons - VERSION = '1.2.3' + VERSION = '1.2.4' end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/daemons.rb new/lib/daemons.rb --- old/lib/daemons.rb 2015-06-25 22:24:19.000000000 +0200 +++ new/lib/daemons.rb 2016-08-02 20:22:22.000000000 +0200 @@ -47,7 +47,7 @@ # the potential of acquiring a controlling terminal. # 4. Changes the current working directory to "/". # 5. Clears the file creation mask (sets +umask+ to 0000). -# 6. Closes file descriptors (reopens +STDOUT+ and +STDERR+ to point to a logfile if +# 6. Closes file descriptors (reopens +$stdout+ and +$stderr+ to point to a logfile if # possible). # # So what does this mean for your daemons: @@ -101,17 +101,20 @@ # same time # <tt>:ontop</tt>:: When given (i.e. set to true), stay on top, i.e. do not daemonize the application # (but the pid-file and other things are written as usual) + # <tt>:shush</tt>:: When given (i.e. set to true), turn on silent mode (no output to the terminal) # <tt>:mode</tt>:: <tt>:load</tt> Load the script with <tt>Kernel.load</tt>; # note that :stop_proc only works for the :load (and :proc) mode. # <tt>:exec</tt> Execute the script file with <tt>Kernel.exec</tt> # <tt>:backtrace</tt>:: Write a backtrace of the last exceptions to the file '[app_name].log' in the # pid-file directory if the application exits due to an uncaught exception # <tt>:monitor</tt>:: Monitor the programs and restart crashed instances + # <tt>:monitor_interval</tt>:: Interval in sesconds at which to check whether the instances are still running # <tt>:log_dir</tt>:: A specific directory to put the log files into (when not given, resort to the default # location as derived from the :dir_mode and :dir options # <tt>:logfilename</tt>:: Specifiy a custom log file name - # <tt>:log_output</tt>:: When given (i.e. set to true), redirect both STDOUT and STDERR to a logfile named '[app_name].output' (or as given in :output_logfilename) in the pid-file directory + # <tt>:log_output</tt>:: When given (i.e. set to true), redirect both $stdout and $stderr to a logfile named '[app_name].output' (or as given in :output_logfilename) in the pid-file directory # <tt>:output_logfilename</tt>:: Specifiy a custom output redirection file name + # <tt>:log_output_syslog</tt>:: When set to true, redirect output into SYSLOG instead of the file. This overrides log_output setting. # <tt>:keep_pid_files</tt>:: When given do not delete lingering pid-files (files for which the process is no longer running). # <tt>:hard_exit</tt>:: When given use exit! to end a daemons instead of exit (this will for example # not call at_exit handlers). @@ -127,6 +130,7 @@ # :dir => 'pids', # :multiple => true, # :ontop => true, + # :shush => false, # :mode => :exec, # :backtrace => true, # :monitor => true, @@ -210,6 +214,8 @@ # === Options: # <tt>:multiple</tt>:: Specifies whether multiple instances of the same script are allowed to run at the # same time + # <tt>:monitor</tt>:: Monitor the programs and restart crashed instances + # <tt>:monitor_interval</tt>:: Interval in sesconds at which to check whether the instances are still running # <tt>:ontop</tt>:: When given, stay on top, i.e. do not daemonize the application # <tt>:backtrace</tt>:: Write a backtrace of the last exceptions to the file '[app_name].log' in the # pid-file directory if the application exits due to an uncaught exception @@ -271,7 +277,8 @@ # <tt>:dir</tt>:: Used in combination with <tt>:dir_mode</tt> (description above) # <tt>:log_dir</tt>:: A specific directory to put the log files into (when not given, resort to the default # location as derived from the :dir_mode and :dir options - # <tt>:log_output</tt>:: When given (i.e. set to true), redirect both STDOUT and STDERR to a logfile named '[app_name].output' in the pid-file directory + # <tt>:log_output</tt>:: When given (i.e. set to true), redirect both $stdout and $stdout to a logfile named '[app_name].output' in the pid-file directory + # <tt>:log_output_syslog</tt>:: When set to true, redirect output into SYSLOG instead of the file. This overrides log_output setting. # ----- # # === Example: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/metadata new/metadata --- old/metadata 2015-06-25 22:24:19.000000000 +0200 +++ new/metadata 2016-08-02 20:22:22.000000000 +0200 @@ -1,15 +1,71 @@ --- !ruby/object:Gem::Specification name: daemons version: !ruby/object:Gem::Version - version: 1.2.3 + version: 1.2.4 platform: ruby authors: - Thomas Uehlinger autorequire: bindir: bin cert_chain: [] -date: 2015-03-08 00:00:00.000000000 Z -dependencies: [] +date: 2016-08-01 00:00:00.000000000 Z +dependencies: +- !ruby/object:Gem::Dependency + name: rake + requirement: !ruby/object:Gem::Requirement + requirements: + - - ~> + - !ruby/object:Gem::Version + version: '0' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - ~> + - !ruby/object:Gem::Version + version: '0' +- !ruby/object:Gem::Dependency + name: rspec + requirement: !ruby/object:Gem::Requirement + requirements: + - - ~> + - !ruby/object:Gem::Version + version: '3.1' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - ~> + - !ruby/object:Gem::Version + version: '3.1' +- !ruby/object:Gem::Dependency + name: simplecov + requirement: !ruby/object:Gem::Requirement + requirements: + - - ~> + - !ruby/object:Gem::Version + version: '0' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - ~> + - !ruby/object:Gem::Version + version: '0' +- !ruby/object:Gem::Dependency + name: pry-byebug + requirement: !ruby/object:Gem::Requirement + requirements: + - - ~> + - !ruby/object:Gem::Version + version: '0' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - ~> + - !ruby/object:Gem::Version + version: '0' description: |2 Daemons provides an easy way to wrap existing ruby scripts (for example a self-written server) to be run as a daemon and to be controlled by simple @@ -68,6 +124,8 @@ - lib/daemons/pid.rb - lib/daemons/pidfile.rb - lib/daemons/pidmem.rb +- lib/daemons/reporter.rb +- lib/daemons/syslogio.rb - lib/daemons/version.rb homepage: https://github.com/thuehlinger/daemons licenses:
