Class: Sensu::Client::Process

Inherits:
Object
  • Object
show all
Includes:
Daemon
Defined in:
lib/sensu/client/process.rb

Constant Summary

Constants included from Utilities

Utilities::EVAL_PREFIX

Instance Attribute Summary collapse

Attributes included from Daemon

#settings, #start_time

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Daemon

#load_extensions, #load_settings, #log_notices, #print_settings!, #setup_logger, #setup_process, #setup_redis, #setup_signal_traps, #setup_spawn, #setup_transport, #validate_settings!

Methods included from Utilities

#attributes_match?, #check_subdued?, #deep_dup, #deep_merge, #determine_check_cron_time, #eval_attribute_value, #find_attribute_value, #in_time_window?, #in_time_windows?, #object_substitute_tokens, #process_cpu_times, #process_eval_string, #random_uuid, #redact_sensitive, #retry_until_true, #substitute_tokens, #system_address, #system_hostname, #testing?

Constructor Details

#initialize(options = {}) ⇒ Process

Override Daemon initialize() to support Sensu client check execution safe mode, checks in progress, and open sockets.

Parameters:

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


29
30
31
32
33
34
# File 'lib/sensu/client/process.rb', line 29

def initialize(options={})
  super
  @safe_mode = @settings[:client][:safe_mode] || false
  @checks_in_progress = []
  @sockets = []
end

Instance Attribute Details

#safe_modeObject

Returns the value of attribute safe_mode.



10
11
12
# File 'lib/sensu/client/process.rb', line 10

def safe_mode
  @safe_mode
end

Class Method Details

.run(options = {}) ⇒ Object

Create an instance of the Sensu client process, start the client within the EventMachine event loop, and set up client process signal traps (for stopping).

Parameters:

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


17
18
19
20
21
22
23
# File 'lib/sensu/client/process.rb', line 17

def self.run(options={})
  client = self.new(options)
  EM::run do
    client.start
    client.setup_signal_traps
  end
end

Instance Method Details

#bootstrapObject

Bootstrap the Sensu client, setting up client keepalives, subscriptions, and standalone check executions. This method sets the process/daemon ‘@state` to `:running`.



582
583
584
585
586
587
# File 'lib/sensu/client/process.rb', line 582

def bootstrap
  setup_keepalives
  setup_subscriptions
  setup_standalone
  @state = :running
end

#calculate_check_execution_splay(check) ⇒ Object

Calculate a check execution splay, taking into account the current time and the execution interval to ensure it’s consistent between process restarts.

Parameters:

  • check (Hash)

    definition.



398
399
400
401
402
403
# File 'lib/sensu/client/process.rb', line 398

def calculate_check_execution_splay(check)
  key = [@settings[:client][:name], check[:name]].join(":")
  splay_hash = Digest::MD5.digest(key).unpack("Q<").first
  current_time = (Time.now.to_f * 1000).to_i
  (splay_hash - current_time) % (check[:interval] * 1000) / 1000.0
end

#check_in_progress_key(check) ⇒ String

Create an in progress key for a check, used to determine if an execution is still in progress. The key is composed of check ‘source` (if set) and `name`, joined by a colon.

Parameters:

  • check (Hash)

Returns:

  • (String)


110
111
112
# File 'lib/sensu/client/process.rb', line 110

def check_in_progress_key(check)
  [check[:source], check[:name]].compact.join(":")
end

#close_socketsObject

Close the Sensu client TCP and UDP sockets. This method iterates through ‘@sockets`, which contains socket server signatures (Fixnum) and connection objects. A signature indicates a TCP socket server that needs to be stopped. A connection object indicates a socket connection that needs to be closed, eg. a UDP datagram socket.



568
569
570
571
572
573
574
575
576
577
# File 'lib/sensu/client/process.rb', line 568

def close_sockets
  @logger.info("closing client sockets")
  @sockets.each do |socket|
    if socket.is_a?(Numeric)
      EM.stop_server(socket)
    else
      socket.close_connection
    end
  end
end

#complete_checks_in_progress { ... } ⇒ Object

Call a callback (Ruby block) when there are no longer check executions in progress. This method is used when stopping the Sensu client. The ‘retry_until_true` helper method is used to check the condition every 0.5 seconds until `true` is returned.

Yields:

  • callback/block called when there are no check

    executions in progress.



529
530
531
532
533
534
535
536
537
# File 'lib/sensu/client/process.rb', line 529

def complete_checks_in_progress
  @logger.info("completing checks in progress", :checks_in_progress => @checks_in_progress)
  retry_until_true do
    if @checks_in_progress.empty?
      yield
      true
    end
  end
end

#create_check_execution_proc(check) ⇒ Object

Create a check execution proc, used to execute standalone checks. Checks are not executed if subdued. The check ‘:issued` timestamp is set here, to mimic check requests issued by a Sensu server. Check definitions are duplicated before processing them, in case they are mutated.

Parameters:

  • check (Hash)

    definition.



363
364
365
366
367
368
369
370
371
372
# File 'lib/sensu/client/process.rb', line 363

def create_check_execution_proc(check)
  Proc.new do
    unless check_subdued?(check)
      check[:issued] = Time.now.to_i
      process_check_request(check.dup)
    else
      @logger.info("check execution was subdued", :check => check)
    end
  end
end

#deregisterObject

Create a check result intended for deregistering a client. Client definitions may contain ‘:deregistration` configuration, containing custom attributes and handler information. By default, the deregistration check result sets the `:handler` to `deregistration`. If the client provides its own `:deregistration` configuration, it’s deep merged with the defaults. The check ‘:name`, `:output`, `:issued`, and `:executed` values are always overridden to guard against an invalid definition.



547
548
549
550
551
552
553
554
555
556
557
558
559
560
# File 'lib/sensu/client/process.rb', line 547

def deregister
  check = {:handler => "deregistration", :status => 1}
  if @settings[:client].has_key?(:deregistration)
    check = deep_merge(check, @settings[:client][:deregistration])
  end
  timestamp = Time.now.to_i
  overrides = {
    :name => "deregistration",
    :output => "client initiated deregistration",
    :issued => timestamp,
    :executed => timestamp
  }
  publish_check_result(check.merge(overrides))
end

#execute_check_command(check) ⇒ Object

Execute a check command, capturing its output (STDOUT/ERR), exit status code, execution duration, timestamp, and publish the result. This method guards against multiple executions for the same check. Check attribute value tokens are substituted with the associated client attribute values, via ‘object_substitute_tokens()`. The original check command and hooks are always published, to guard against publishing sensitive/redacted client attribute values. If there are unmatched check attribute value tokens, the check will not be executed, instead a check result will be published reporting the unmatched tokens.

Parameters:

  • check (Hash)


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
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/sensu/client/process.rb', line 180

def execute_check_command(check)
  @logger.debug("attempting to execute check command", :check => check)
  in_progress_key = check_in_progress_key(check)
  unless @checks_in_progress.include?(in_progress_key)
    @checks_in_progress << in_progress_key
    substituted, unmatched_tokens = object_substitute_tokens(check.dup, @settings[:client])
    check = substituted.merge(:command => check[:command], :hooks => check[:hooks])
    check.delete(:hooks) if check[:hooks].nil?
    started = Time.now.to_f
    check[:executed] = started.to_i
    if unmatched_tokens.empty?
      options = {:timeout => check[:timeout]}
      if check[:stdin]
        options[:data] = Sensu::JSON.dump({
          :client => @settings[:client],
          :check => check
        })
      end
      Spawn.process(substituted[:command], options) do |output, status|
        check[:duration] = ("%.3f" % (Time.now.to_f - started)).to_f
        check[:output] = output
        check[:status] = status
        if check[:hooks] && !check[:hooks].empty?
          execute_check_hook(check) do |check|
            publish_check_result(check)
            @checks_in_progress.delete(in_progress_key)
          end
        else
          publish_check_result(check)
          @checks_in_progress.delete(in_progress_key)
        end
      end
    else
      check[:output] = "Unmatched client token(s): " + unmatched_tokens.join(", ")
      check[:status] = 3
      check[:handle] = false
      publish_check_result(check)
      @checks_in_progress.delete(in_progress_key)
    end
  else
    @logger.warn("previous check command execution in progress", :check => check)
  end
end

#execute_check_hook(check) {|check| ... } ⇒ Object

Execute a check hook, capturing its output (STDOUT/ERR), exit status code, executed timestamp, and duration. This method determines which hook command to run by inspecting the check execution status. Check hook command tokens are substituted with the associated client attribute values, via ‘substitute_tokens()`. If there are unmatched check attribute value tokens, the check hook will not be executed, instead the hook command output will be set to report the unmatched tokens. Hook commands may expect/read and utilize JSON serialized Sensu client and check data via STDIN, if the hook definition includes `“stdin”: true` (default is `false`). A hook may have a configured execution timeout, e.g. `“timeout”: 30`, if one is not specified, the timeout defaults to 60 seconds.

Parameters:

  • check (Hash)

Yields:

  • (check)

    callback/block called after executing the check hook (if any).



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
# File 'lib/sensu/client/process.rb', line 132

def execute_check_hook(check)
  @logger.debug("attempting to execute check hook", :check => check)
  severity = SEVERITIES[check[:status]] || "unknown"
  hook = check[:hooks][check[:status].to_s.to_sym] || check[:hooks][severity.to_sym]
  if hook.nil? && check[:status] != 0
    hook = check[:hooks]["non-zero".to_sym]
  end
  if hook
    command, unmatched_tokens = substitute_tokens(hook[:command].dup, @settings[:client])
    started = Time.now.to_f
    hook[:executed] = started.to_i
    if unmatched_tokens.empty?
      options = {:timeout => hook.fetch(:timeout, 60)}
      if hook[:stdin]
        options[:data] = Sensu::JSON.dump({
          :client => @settings[:client],
          :check => check
        })
      end
      Spawn.process(command, options) do |output, status|
        hook[:duration] = ("%.3f" % (Time.now.to_f - started)).to_f
        hook[:output] = output
        hook[:status] = status
        yield(check)
      end
    else
      hook[:output] = "Unmatched client token(s): " + unmatched_tokens.join(", ")
      hook[:status] = 3
      yield(check)
    end
  else
    yield(check)
  end
end

#keepalive_payloadHash

Create a Sensu client keepalive payload, to be sent over the transport for processing. A client keepalive is composed of its settings definition, the Sensu version, and a timestamp. Sensitive information is redacted from the keepalive payload.

Returns:

  • (Hash)

    keepalive payload



42
43
44
45
46
47
48
# File 'lib/sensu/client/process.rb', line 42

def keepalive_payload
  payload = @settings[:client].merge({
    :version => VERSION,
    :timestamp => Time.now.to_i
  })
  redact_sensitive(payload, @settings[:client][:redact])
end

#pauseObject

Pause the Sensu client process, unless it is being paused or has already been paused. The process/daemon ‘@state` is first set to `:pausing`, to indicate that it’s in progress. All run timers are cancelled, and the references are cleared. The Sensu client will unsubscribe from all transport subscriptions, then set the process/daemon ‘@state` to `:paused`.



606
607
608
609
610
611
612
613
614
615
616
# File 'lib/sensu/client/process.rb', line 606

def pause
  unless @state == :pausing || @state == :paused
    @state = :pausing
    @timers[:run].each do |timer|
      timer.cancel
    end
    @timers[:run].clear
    @transport.unsubscribe if @transport
    @state = :paused
  end
end

#process_check_request(check) ⇒ Object

Process a check request. If a check request has a check command, it will be executed. A standard check request will be merged with a local check definition, if present. Client safe mode is enforced in this method, requiring a local check definition in order to execute the check command. If a local check definition does not exist when operating with client safe mode, a check result will be published to report the missing check definition. A check request without a command indicates a check extension run. The check request may contain ‘:extension`, the name of the extension to run. If `:extension` is not present, the check name is used for the extension name. If a check extension does not exist for a name, a check result will be published to report the unknown check extension.

Parameters:

  • check (Hash)


281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
# File 'lib/sensu/client/process.rb', line 281

def process_check_request(check)
  @logger.debug("processing check", :check => check)
  if @settings.check_exists?(check[:name]) && !check.has_key?(:proxy_requests)
    check.merge!(@settings[:checks][check[:name]])
  end
  if check.has_key?(:command)
    if @safe_mode && !@settings.check_exists?(check[:name])
      check[:output] = "Check is not locally defined (safe mode)"
      check[:status] = 3
      check[:handle] = false
      check[:executed] = Time.now.to_i
      publish_check_result(check)
    else
      execute_check_command(check)
    end
  else
    extension_name = check[:extension] || check[:name]
    if @extensions.check_exists?(extension_name)
      run_check_extension(check)
    else
      @logger.warn("unknown check extension", :check => check)
    end
  end
end

#publish_check_result(check) ⇒ Object

Publish a check result to the transport for processing. A check result is composed of a client (name) and a check definition, containing check ‘:output` and `:status`. JSON serialization is used when publishing the check result payload to the transport pipe. The check result is signed with the client signature if configured, for source validation. Transport errors are logged.

Parameters:

  • check (Hash)


86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/sensu/client/process.rb', line 86

def publish_check_result(check)
  check.delete(:source) if check[:source] == ""
  payload = {
    :client => @settings[:client][:name],
    :check => check
  }
  payload[:signature] = @settings[:client][:signature] if @settings[:client][:signature]
  @logger.info("publishing check result", :payload => payload)
  @transport.publish(:direct, "results", Sensu::JSON.dump(payload)) do |info|
    if info[:error]
      @logger.error("failed to publish check result", {
        :payload => payload,
        :error => info[:error].to_s
      })
    end
  end
end

#publish_keepaliveObject

Publish a Sensu client keepalive to the transport for processing. JSON serialization is used for transport messages.



52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/sensu/client/process.rb', line 52

def publish_keepalive
  payload = keepalive_payload
  @logger.debug("publishing keepalive", :payload => payload)
  @transport.publish(:direct, "keepalives", Sensu::JSON.dump(payload)) do |info|
    if info[:error]
      @logger.error("failed to publish keepalive", {
        :payload => payload,
        :error => info[:error].to_s
      })
    end
  end
end

#resumeObject

Resume the Sensu client process if it is currently or will soon be paused. The ‘retry_until_true` helper method is used to determine if the process is paused and if the transport is connected. If the conditions are met, `bootstrap()` will be called and true is returned to stop `retry_until_true`.



623
624
625
626
627
628
629
630
631
632
# File 'lib/sensu/client/process.rb', line 623

def resume
  retry_until_true(1) do
    if @state == :paused
      if @transport.connected?
        bootstrap
        true
      end
    end
  end
end

#run_check_extension(check) ⇒ Object

Run a check extension and publish the result. The Sensu client loads check extensions, checks that run within the Sensu Ruby VM and the EventMachine event loop, using the Sensu Extension API. If a check definition includes ‘:extension`, use it’s value for the extension name, otherwise use the check name. The check definition is passed to the extension ‘safe_run()` method as a parameter, the extension may utilize it. This method guards against multiple executions for the same check extension.

github.com/sensu/sensu-extension

Parameters:

  • check (Hash)


237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/sensu/client/process.rb', line 237

def run_check_extension(check)
  @logger.debug("attempting to run check extension", :check => check)
  in_progress_key = check_in_progress_key(check)
  unless @checks_in_progress.include?(in_progress_key)
    @checks_in_progress << in_progress_key
    started = Time.now.to_f
    check[:executed] = started.to_i
    extension_name = check[:extension] || check[:name]
    extension = @extensions[:checks][extension_name]
    extension.safe_run(check) do |output, status|
      check[:duration] = ("%.3f" % (Time.now.to_f - started)).to_f
      check[:output] = output
      check[:status] = status
      if check[:hooks] && !check[:hooks].empty?
        execute_check_hook(check) do |check|
          publish_check_result(check)
          @checks_in_progress.delete(in_progress_key)
        end
      else
        publish_check_result(check)
        @checks_in_progress.delete(in_progress_key)
      end
    end
  else
    @logger.warn("previous check extension execution in progress", :check => check)
  end
end

#schedule_check_cron_execution(check) ⇒ Object

Schedule a check execution, using the check cron. This method determines the time until the next cron time (in seconds) and creats an EventMachine timer for the execution. This method will be called after every check cron execution for subsequent executions. The timer is stored in the timers hash under ‘:run`, so it can be cancelled etc. The check cron execution timer object is removed from the timer hash after the execution, to stop the timer hash from growing infinitely.

Parameters:

  • check (Hash)

    definition.



384
385
386
387
388
389
390
391
# File 'lib/sensu/client/process.rb', line 384

def schedule_check_cron_execution(check)
  cron_time = determine_check_cron_time(check)
  @timers[:run] << EM::Timer.new(cron_time) do |timer|
    create_check_execution_proc(check).call
    @timers[:run].delete(timer)
    schedule_check_cron_execution(check)
  end
end

#schedule_check_interval_executions(check) ⇒ Object

Schedule check executions, using the check interval. This method using an intial calculated execution splay EventMachine timer and an EventMachine periodic timer for subsequent check executions. The timers are stored in the timers hash under ‘:run`, so they can be cancelled etc.

Parameters:

  • check (Hash)

    definition.



412
413
414
415
416
417
418
419
420
# File 'lib/sensu/client/process.rb', line 412

def schedule_check_interval_executions(check)
  execution_splay = testing? ? 0 : calculate_check_execution_splay(check)
  interval = testing? ? 0.5 : check[:interval]
  @timers[:run] << EM::Timer.new(execution_splay) do
    execute_check = create_check_execution_proc(check)
    execute_check.call
    @timers[:run] << EM::PeriodicTimer.new(interval, &execute_check)
  end
end

#schedule_checks(checks) ⇒ Object

Schedule check executions. This method iterates through defined checks and uses the appropriate method of check execution scheduling, either with the cron syntax or a numeric interval.

Parameters:

  • checks (Array)

    of definitions.



427
428
429
430
431
432
433
434
435
# File 'lib/sensu/client/process.rb', line 427

def schedule_checks(checks)
  checks.each do |check|
    if check[:cron]
      schedule_check_cron_execution(check)
    else
      schedule_check_interval_executions(check)
    end
  end
end

#setup_http_socketObject

Setup the Sensu client HTTP socket, for external check result input and informational queries. By default, the client HTTP socket is bound to localhost on TCP port 3031. The socket can be configured via the client definition, ‘:http_socket` with `:bind` and `:port`. Users can opt-out of using the HTTP socket by setting `:enabled` to `false. The current instance of the Sensu logger, settings, and transport are passed to the HTTP socket handler, `Sensu::Client::HTTPSocket`. The HTTP socket server signature (Fixnum) is stored in `@sockets`, so that it can be managed elsewhere, eg. `close_sockets()`.



498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
# File 'lib/sensu/client/process.rb', line 498

def setup_http_socket
  options = @settings[:client][:http_socket] || Hash.new
  options[:bind] ||= "127.0.0.1"
  options[:port] ||= 3031
  unless options[:enabled] == false
    @logger.debug("binding client http socket", :options => options)
    @sockets << EM::start_server(options[:bind], options[:port], HTTPSocket) do |socket|
      socket.logger = @logger
      socket.settings = @settings
      socket.transport = @transport
    end
  else
    @logger.info("client http socket disabled per configuration")
  end
end

#setup_json_socketObject

Setup the Sensu client JSON socket, for external check result input. By default, the client socket is bound to localhost on TCP & UDP port 3030. The socket can be configured via the client definition, ‘:socket` with `:bind` and `:port`. Users can opt-out of using the TCP and UDP socket by setting `:enabled` to `false`. The current instance of the Sensu logger, settings, and transport are passed to the socket handler, `Sensu::Client::Socket`. The TCP socket server signature (Fixnum) and UDP connection object are stored in `@sockets`, so that they can be managed elsewhere, eg. `close_sockets()`.



466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
# File 'lib/sensu/client/process.rb', line 466

def setup_json_socket
  options = @settings[:client][:socket] || Hash.new
  options[:bind] ||= "127.0.0.1"
  options[:port] ||= 3030
  unless options[:enabled] == false
    @logger.debug("binding client tcp and udp sockets", :options => options)
    @sockets << EM::start_server(options[:bind], options[:port], Socket) do |socket|
      socket.logger = @logger
      socket.settings = @settings
      socket.transport = @transport
    end
    @sockets << EM::open_datagram_socket(options[:bind], options[:port], Socket) do |socket|
      socket.logger = @logger
      socket.settings = @settings
      socket.transport = @transport
      socket.protocol = :udp
    end
  else
    @logger.info("client tcp/udp socket disabled per configuration")
  end
end

#setup_keepalivesObject

Schedule Sensu client keepalives. Immediately publish a keepalive to register the client, then publish a keepalive every 20 seconds. Sensu client keepalives are used to determine client (& machine) health.



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

def setup_keepalives
  @logger.debug("scheduling keepalives")
  publish_keepalive
  @timers[:run] << EM::PeriodicTimer.new(20) do
    publish_keepalive
  end
end

#setup_socketsObject

Setup the Sensu client sockets, JSON TCP & UDP, and HTTP. Users can opt-out of using the HTTP socket via configuration.



516
517
518
519
# File 'lib/sensu/client/process.rb', line 516

def setup_sockets
  setup_json_socket
  setup_http_socket
end

#setup_standaloneObject

Setup standalone check executions, scheduling standard check definition and check extension executions. Check definitions and extensions with ‘:standalone` set to `true`, do not have `:publish` set to `false`, and have a integer `:interval` or a string `cron` will be scheduled by the Sensu client for execution.



443
444
445
446
447
448
449
450
451
452
453
454
# File 'lib/sensu/client/process.rb', line 443

def setup_standalone
  @logger.debug("scheduling standalone checks")
  standard_checks = @settings.checks.select do |check|
    check[:standalone] && check[:publish] != false &&
      (check[:interval].is_a?(Integer) || check[:cron].is_a?(String))
  end
  extension_checks = @extensions.checks.select do |check|
    check[:standalone] && check[:publish] != false &&
      (check[:interval].is_a?(Integer) || check[:cron].is_a?(String))
  end
  schedule_checks(standard_checks + extension_checks)
end

#setup_subscriptionsObject

Set up Sensu client subscriptions. Subscriptions determine the kinds of check requests the client will receive. The Sensu client will receive JSON serialized check requests from its subscriptions, that get parsed and processed.



336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
# File 'lib/sensu/client/process.rb', line 336

def setup_subscriptions
  @logger.debug("subscribing to client subscriptions")
  @settings[:client][:subscriptions].each do |subscription|
    @logger.debug("subscribing to a subscription", :subscription => subscription)
    options = transport_subscribe_options(subscription)
    @transport.subscribe(*options) do |message_info, message|
      begin
        check = Sensu::JSON.load(message)
        @logger.info("received check request", :check => check)
        process_check_request(check)
      rescue Sensu::JSON::ParseError => error
        @logger.error("failed to parse the check request payload", {
          :message => message,
          :error => error.to_s
        })
      end
    end
  end
end

#startObject

Start the Sensu client process, setting up the client transport connection, the sockets, and calling the ‘bootstrap()` method.



592
593
594
595
596
597
# File 'lib/sensu/client/process.rb', line 592

def start
  setup_transport do
    setup_sockets
    bootstrap
  end
end

#stopObject

Stop the Sensu client process, pausing it, completing check executions in progress, closing the transport connection, and exiting the process (exit 0). After pausing the process, the process/daemon ‘@state` is set to `:stopping`. Also sends deregistration check result if configured to do so.



639
640
641
642
643
644
645
646
647
648
649
650
651
652
# File 'lib/sensu/client/process.rb', line 639

def stop
  @logger.warn("stopping")
  last_state = @state
  pause
  if @settings[:client][:deregister] == true && last_state != :initializing
    deregister
  end
  @state = :stopping
  complete_checks_in_progress do
    close_sockets
    @transport.close if @transport
    super
  end
end

#transport_subscribe_options(subscription) ⇒ Array

Determine the Sensu transport subscribe options for a subscription. If a subscription begins with a transport pipe type, either “direct:” or “roundrobin:”, the subscription uses a direct transport pipe, and the subscription name is used for both the pipe and the funnel names. If a subscription does not specify a transport pipe type, a fanout transport pipe is used, the subscription name is used for the pipe, and a unique funnel is created for the Sensu client. The unique funnel name for the Sensu client is created using a combination of the client name, the Sensu version, and the process start time (epoch).

Parameters:

  • subscription (String)

Returns:

  • (Array)

    containing the transport subscribe options: the transport pipe type, pipe, and funnel.



321
322
323
324
325
326
327
328
329
330
# File 'lib/sensu/client/process.rb', line 321

def transport_subscribe_options(subscription)
  _, raw_type = subscription.split(":", 2).reverse
  case raw_type
  when "direct", "roundrobin"
    [:direct, subscription, subscription]
  else
    funnel = [@settings[:client][:name], VERSION, start_time].join("-")
    [:fanout, subscription, funnel]
  end
end