Module: Sensu::Server::Handle

Included in:
Process
Defined in:
lib/sensu/server/handle.rb

Instance Method Summary collapse

Instance Method Details

#handle_event(handler, event_data, event_id) ⇒ Object

Handle an event, providing event data to an event handler. This method logs event data and the handler definition at the debug log level, then calls the ‘handler_type_router()` method.

Parameters:

  • handler (Hash)

    definition.

  • event_data (Object)

    to pass to an event handler.

  • event_id (String)

    event UUID



190
191
192
193
194
195
196
197
198
# File 'lib/sensu/server/handle.rb', line 190

def handle_event(handler, event_data, event_id)
  definition = handler.is_a?(Hash) ? handler : handler.definition
  @logger.debug("handling event", {
    :event_data => event_data,
    :event => { :id => event_id },
    :handler => definition
  })
  handler_type_router(handler, event_data, event_id)
end

#handler_error(handler, event_data, event_id) ⇒ Proc

Create a handler error callback, for logging the error and decrementing the ‘@in_progress` by `1`.

Parameters:

  • handler (Object)
  • event_data (Object)
  • event_id (String)

    event UUID

Returns:

  • (Proc)

    error callback.



13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/sensu/server/handle.rb', line 13

def handler_error(handler, event_data, event_id)
  Proc.new do |error|
    @logger.error("handler error", {
      :handler => handler,
      :event => {
        :id => event_id
      },
      :event_data => event_data,
      :error => error.to_s
    })
    @in_progress[:events] -= 1 if @in_progress
  end
end

#handler_extension(handler, event_data, event_id) ⇒ Object

Run a handler extension, within the Sensu EventMachine reactor (event loop). The extension API ‘safe_run()` method is used to guard against most errors. The `safe_run()` callback is always called, logging the extension run output and status, and decrementing the `@in_progress` by `1`.

Parameters:

  • handler (Hash)

    definition.

  • event_data (Object)

    to pass to the handler extension.

  • event_id (String)

    event UUID



146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/sensu/server/handle.rb', line 146

def handler_extension(handler, event_data, event_id)
  handler.safe_run(event_data) do |output, status|
    log_level = (output.empty? && status.zero?) ? :debug : :info
    @logger.send(log_level, "handler extension output", {
      :extension => handler.definition,
      :event => {
        :id => event_id
      },
      :output => output,
      :status => status
    })
    @in_progress[:events] -= 1 if @in_progress
  end
end

#handler_type_router(handler, event_data, event_id) ⇒ Object

Route the event data to the appropriate handler type method. Routing is done using the handler definition, ‘:type`.

Parameters:

  • handler (Hash)

    definition.

  • event_data (Object)

    to pass to the handler type method.

  • event_id (String)

    event UUID



167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/sensu/server/handle.rb', line 167

def handler_type_router(handler, event_data, event_id)
  case handler[:type]
  when "pipe"
    pipe_handler(handler, event_data, event_id)
  when "tcp"
    tcp_handler(handler, event_data, event_id)
  when "udp"
    udp_handler(handler, event_data, event_id)
  when "transport"
    transport_handler(handler, event_data, event_id)
  when "extension"
    handler_extension(handler, event_data, event_id)
  end
end

#pipe_handler(handler, event_data, event_id) ⇒ Object

Execute a pipe event handler, using the defined handler command to spawn a process, passing it event data via STDIN. Log the handler output lines and decrement the ‘@in_progress` by `1` when the handler executes successfully.

When the spawned process exits with status 0, its output is logged at :info level. Otherwise, its output is logged at :error level.

Parameters:

  • handler (Hash)

    definition.

  • event_data (Object)

    provided to the spawned handler process via STDIN.

  • event_id (String)

    event UUID



41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/sensu/server/handle.rb', line 41

def pipe_handler(handler, event_data, event_id)
  options = {:data => event_data, :timeout => handler[:timeout]}
  Spawn.process(handler[:command], options) do |output, status|
    log_level = status == 0 ? :info : :error
    @logger.send(log_level, "handler output", {
      :handler => handler,
      :event => {
        :id => event_id
      },
      :output => output.split("\n+")
    })
    @in_progress[:events] -= 1 if @in_progress
  end
end

#tcp_handler(handler, event_data, event_id) ⇒ Object

Connect to a TCP socket and transmit event data to it, then close the connection. The ‘Sensu::Server::Socket` connection handler is used for the socket. The socket timeouts are configurable via the handler definition, `:timeout`. The `handler_error()` method is used to create the `on_error` callback for the connection handler. The `on_error` callback is call in the event of any error(s). The `@in_progress` is decremented by `1` when the data is transmitted successfully, `on_success`.

Parameters:

  • handler (Hash)

    definition.

  • event_data (Object)

    to transmit to the TCP socket.

  • event_id (String)

    event UUID



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
# File 'lib/sensu/server/handle.rb', line 69

def tcp_handler(handler, event_data, event_id)
  unless event_data.nil? || event_data.empty?
    on_error = handler_error(handler, event_data, event_id)
    begin
      EM::connect(handler[:socket][:host], handler[:socket][:port], Socket) do |socket|
        socket.on_success = Proc.new do
          @in_progress[:events] -= 1 if @in_progress
        end
        socket.on_error = on_error
        timeout = handler[:timeout] || 10
        socket.set_timeout(timeout)
        socket.send_data(event_data.to_s)
        socket.close_connection_after_writing
      end
    rescue => error
      on_error.call(error)
    end
  else
    @logger.debug("not connecting to tcp socket due to empty event data", {
      :handler => handler,
      :event => {
        :id => event_id
      }
    })
    @in_progress[:events] -= 1 if @in_progress
  end
end

#transport_handler(handler, event_data, event_id) ⇒ Object

Publish event data to a Sensu transport pipe. Event data that is ‘nil` or empty will not be published, to prevent transport errors. The `@in_progress` is decremented by `1`, even if the event data is not published.

Parameters:

  • handler (Hash)

    definition.

  • event_data (Object)

    to publish to the transport pipe.

  • event_id (String)

    event UUID



124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/sensu/server/handle.rb', line 124

def transport_handler(handler, event_data, event_id)
  unless event_data.nil? || event_data.empty?
    pipe = handler[:pipe]
    pipe_options = pipe[:options] || {}
    @transport.publish(pipe[:type].to_sym, pipe[:name], event_data, pipe_options) do |info|
      if info[:error]
        handler_error(handler, event_data, event_id).call(info[:error])
      end
    end
  end
  @in_progress[:events] -= 1 if @in_progress
end

#udp_handler(handler, event_data, event_id) ⇒ Object

Transmit event data to a UDP socket, then close the connection. The ‘@in_progress` is decremented by `1` when the data is assumed to have been transmitted.

Parameters:

  • handler (Hash)

    definition.

  • event_data (Object)

    to transmit to the UDP socket.

  • event_id (String)

    event UUID



104
105
106
107
108
109
110
111
112
113
114
# File 'lib/sensu/server/handle.rb', line 104

def udp_handler(handler, event_data, event_id)
  begin
    EM::open_datagram_socket("0.0.0.0", 0, nil) do |socket|
      socket.send_datagram(event_data.to_s, handler[:socket][:host], handler[:socket][:port])
      socket.close_connection_after_writing
      @in_progress[:events] -= 1 if @in_progress
    end
  rescue => error
    handler_error(handler, event_data, event_id).call(error)
  end
end