Module: Sensu::Daemon

Includes:
Utilities
Included in:
API::Process, Client::Process, Server::Process
Defined in:
lib/sensu/daemon.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Utilities

#deep_merge, #random_uuid, #redact_sensitive, #retry_until_true, #testing?

Instance Attribute Details

#start_timeObject (readonly)

Returns the value of attribute start_time.



34
35
36
# File 'lib/sensu/daemon.rb', line 34

def start_time
  @start_time
end

Instance Method Details

#initialize(options = {}) ⇒ Object

Initialize the Sensu process. Set the start time, initial service state, set up the logger, load settings, load extensions, and optionally daemonize the process and/or create a PID file. A subclass may override this method.

Parameters:

  • options (Hash) (defaults to: {})


42
43
44
45
46
47
48
49
50
# File 'lib/sensu/daemon.rb', line 42

def initialize(options={})
  @start_time = Time.now.to_i
  @state = :initializing
  @timers = {:run => []}
  setup_logger(options)
  load_settings(options)
  load_extensions(options)
  setup_process(options)
end

#load_extensions(options = {}) ⇒ Object

Load Sensu extensions and log any concerns. Set the logger and settings for each extension instance. This method creates the extensions instance variable: ‘@extensions`.

github.com/sensu/sensu-extensions github.com/sensu/sensu-extension

Parameters:

  • options (Hash) (defaults to: {})


104
105
106
107
108
109
110
111
112
# File 'lib/sensu/daemon.rb', line 104

def load_extensions(options={})
  @extensions = Extensions.get(options)
  log_concerns(@extensions.warnings)
  extension_settings = @settings.to_hash.dup
  @extensions.all.each do |extension|
    extension.logger = @logger
    extension.settings = extension_settings
  end
end

#load_settings(options = {}) ⇒ Object

Load Sensu settings and validate them. If there are validation failures, log them (concerns), then cause the Sensu process to exit (2). This method creates the settings instance variable: ‘@settings`.

github.com/sensu/sensu-settings

Parameters:

  • options (Hash) (defaults to: {})


84
85
86
87
88
89
90
91
92
93
94
# File 'lib/sensu/daemon.rb', line 84

def load_settings(options={})
  @settings = Settings.get(options)
  log_concerns(@settings.warnings)
  failures = @settings.validate
  unless failures.empty?
    @logger.fatal("invalid settings")
    log_concerns(failures, :fatal)
    @logger.fatal("SENSU NOT RUNNING!")
    exit 2
  end
end

#log_concerns(concerns = [], level = :warn) ⇒ Object

Log setting or extension loading concerns, sensitive information is redacted.

Parameters:

  • concerns (Array) (defaults to: [])

    to be logged.

  • level (Symbol) (defaults to: :warn)

    to log the concerns at.



69
70
71
72
73
74
# File 'lib/sensu/daemon.rb', line 69

def log_concerns(concerns=[], level=:warn)
  concerns.each do |concern|
    message = concern.delete(:message)
    @logger.send(level, message, redact_sensitive(concern))
  end
end

#pauseObject

Pause the Sensu service and set the service state to ‘:paused`. This method will likely be overridden by a subclass.



131
132
133
# File 'lib/sensu/daemon.rb', line 131

def pause
  @state = :paused
end

#resumeObject

Resume the paused Sensu service and set the service state to ‘:running`. This method will likely be overridden by a subclass.



137
138
139
# File 'lib/sensu/daemon.rb', line 137

def resume
  @state = :running
end

#setup_logger(options = {}) ⇒ Object

Set up the Sensu logger and its process signal traps for log rotation and debug log level toggling. This method creates the logger instance variable: ‘@logger`.

github.com/sensu/sensu-logger

Parameters:

  • options (Hash) (defaults to: {})


59
60
61
62
# File 'lib/sensu/daemon.rb', line 59

def setup_logger(options={})
  @logger = Logger.get(options)
  @logger.setup_signal_traps
end

#setup_process(options) ⇒ Object

Manage the current process, optionally daemonize and/or write the current process ID to a PID file.

Parameters:

  • options (Hash)


118
119
120
121
# File 'lib/sensu/daemon.rb', line 118

def setup_process(options)
  daemonize if options[:daemonize]
  write_pid(options[:pid_file]) if options[:pid_file]
end

#setup_redisObject

Set up the Redis connection. Sensu uses Redis as a data store, to store the client registry, current events, etc. The Sensu service will stop gracefully in the event of a Redis error, and pause/resume in the event of connectivity issues. This method creates the Redis instance variable: ‘@redis`.



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/sensu/daemon.rb', line 213

def setup_redis
  @logger.debug("connecting to redis", :settings => @settings[:redis])
  @redis = Redis.connect(@settings[:redis])
  @redis.on_error do |error|
    @logger.fatal("redis connection error", :error => error.to_s)
    stop
  end
  @redis.before_reconnect do
    unless testing?
      @logger.warn("reconnecting to redis")
      pause
    end
  end
  @redis.after_reconnect do
    @logger.info("reconnected to redis")
    resume
  end
end

#setup_signal_trapsObject

Set up process signal traps. This method uses the ‘STOP_SIGNALS` constant to determine which process signals will result in a graceful service stop. A periodic timer must be used to poll for received signals, as Mutex#lock cannot be used within the context of `trap()`.



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/sensu/daemon.rb', line 155

def setup_signal_traps
  @signals = []
  STOP_SIGNALS.each do |signal|
    Signal.trap(signal) do
      @signals << signal
    end
  end
  EM::PeriodicTimer.new(1) do
    signal = @signals.shift
    if STOP_SIGNALS.include?(signal)
      @logger.warn("received signal", :signal => signal)
      stop
    end
  end
end

#setup_transportObject

Set up the Sensu transport connection. Sensu uses a transport API, allowing it to use various message brokers. By default, Sensu will use the built-in “rabbitmq” transport. The Sensu service will stop gracefully in the event of a transport error, and pause/resume in the event of connectivity issues. This method creates the transport instance variable: ‘@transport`.

github.com/sensu/sensu-transport



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/sensu/daemon.rb', line 179

def setup_transport
  transport_name = @settings[:transport][:name]
  transport_settings = @settings[transport_name]
  @logger.debug("connecting to transport", {
    :name => transport_name,
    :settings => transport_settings
  })
  Transport.logger = @logger
  @transport = Transport.connect(transport_name, transport_settings)
  @transport.on_error do |error|
    @logger.fatal("transport connection error", :error => error.to_s)
    if @settings[:transport][:reconnect_on_error]
      @transport.reconnect
    else
      stop
    end
  end
  @transport.before_reconnect do
    unless testing?
      @logger.warn("reconnecting to transport")
      pause
    end
  end
  @transport.after_reconnect do
    @logger.info("reconnected to transport")
    resume
  end
end

#startObject

Start the Sensu service and set the service state to ‘:running`. This method will likely be overridden by a subclass.



125
126
127
# File 'lib/sensu/daemon.rb', line 125

def start
  @state = :running
end

#stopObject

Stop the Sensu service and set the service state to ‘:stopped`. This method will likely be overridden by a subclass. This method should stop the EventMachine event loop.



144
145
146
147
148
# File 'lib/sensu/daemon.rb', line 144

def stop
  @state = :stopped
  @logger.warn("stopping reactor")
  EM::stop_event_loop
end