public
Fork of mojombo/god
Description: Ruby process monitor
Homepage: http://god.rubyforge.org
Clone URL: git://github.com/kevinclark/god.git
Search Repo:
Bertg (author)
Sat Mar 01 06:59:55 -0800 2008
commit  15f0ceeef36e49eb51d6efcc7ed4df7b6a03d14f
tree    5f7e59f04922d49e431b30d21c74aaf572776315
parent  f43bb13ed51dad95d6ba51de9fe80979d81df0b4
god / lib / god / cli / run.rb
100644 176 lines (143 sloc) 4.601 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
module God
  module CLI
    
    class Run
      def initialize(options)
        @options = options
        
        dispatch
      end
      
      def dispatch
        # have at_exit start god
        $run = true
        
        # run
        if @options[:daemonize]
          run_daemonized
        else
          run_in_front
        end
      end
      
      def attach
        process = System::Process.new(@options[:attach])
        Thread.new do
          loop do
            unless process.exists?
              applog(nil, :info, "Going down because attached process #{@options[:attach]} exited")
              exit!
            end
            sleep 5
          end
        end
      end
      
      def default_run
        # start attached pid watcher if necessary
        if @options[:attach]
          self.attach
        end
        
        if @options[:port]
          God.port = @options[:port]
        end
        
        if @options[:events]
          God::EventHandler.load
        end
        
        # set log level, defaults to WARN
        if @options[:log_level]
          God.log_level = @options[:log_level]
        else
          God.log_level = @options[:daemonize] ? :warn : :info
        end
        
        if @options[:config]
          unless File.exist?(@options[:config])
            abort "File not found: #{@options[:config]}"
          end
          
          # start the event handler
          God::EventHandler.start if God::EventHandler.loaded?
          
          load_config @options[:config]
        end
      end
      
      def run_in_front
        require 'god'
        
        if @options[:bleakhouse]
          BleakHouseDiagnostic.install
        end
        
        default_run
        
        if @options[:log]
          log_file = File.expand_path(@options[:log])
          puts "Sending output to log file: #{log_file}"
          
          # reset file descriptors
          STDIN.reopen "/dev/null"
          STDOUT.reopen(log_file, "a")
          STDERR.reopen STDOUT
          STDOUT.sync = true
        end
      end
      
      def run_daemonized
        # trap and ignore SIGHUP
        Signal.trap('HUP') {}
        
        pid = fork do
          begin
            require 'god'
            
            log_file = @options[:log] || "/dev/null"
            
            # reset file descriptors
            STDIN.reopen "/dev/null"
            STDOUT.reopen(log_file, "a")
            STDERR.reopen STDOUT
            STDOUT.sync = true
            
            # set pid if requested
            if @options[:pid] # and as deamon
              God.pid = @options[:pid]
            end
            
            unless @options[:syslog]
              Logger.syslog = false
            end
            
            default_run
            
            unless God::EventHandler.loaded?
              puts
              puts "***********************************************************************"
              puts "*"
              puts "* Event conditions are not available for your installation of god."
              puts "* You may still use and write custom conditions using the poll system"
              puts "*"
              puts "***********************************************************************"
              puts
            end
            
          rescue => e
            puts e.message
            puts e.backtrace.join("\n")
            abort "There was a fatal system error while starting god (see above)"
          end
        end
        
        if @options[:pid]
          File.open(@options[:pid], 'w') { |f| f.write pid }
        end
        
        ::Process.detach pid
        
        exit
      end
      
      def load_config(config)
        if File.directory? config
          files_loaded = false
          Dir[File.expand_path('**/*.god', config)].each do |god_file|
            files_loaded ||= load_god_file(File.expand_path(god_file))
          end
          unless files_loaded
            abort "No files could be loaded"
          end
        else
          unless load_god_file(File.expand_path(config))
            abort "File could not be loaded"
          end
        end
      end
      
      def load_god_file(god_file)
        load File.expand_path(god_file)
      rescue Exception => e
        if e.instance_of?(SystemExit)
          raise
        else
          puts "There was an error in #{god_file}"
          puts "\t" + e.message
          puts "\t" + e.backtrace.join("\n\t")
          return false
        end
      end
      
    end # Run
    
  end
end