Module: Sensu::Server::Filter

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

Instance Method Summary collapse

Instance Method Details

#action_subdued?(condition) ⇒ TrueClass, FalseClass

Determine if an action is subdued and if there is an exception. This method makes use of ‘subdue_time?()`, `subdue_days?()`, and subdue_exception?().

Parameters:

  • condition (Hash)

Returns:

  • (TrueClass, FalseClass)


74
75
76
77
# File 'lib/sensu/server/filter.rb', line 74

def action_subdued?(condition)
  subdued = subdue_time?(condition) || subdue_days?(condition)
  subdued && !subdue_exception?(condition)
end

#check_request_subdued?(check) ⇒ TrueClass, FalseClass

Determine if a check request is subdued, by conditions set in the check definition. If any of the conditions are true, without an exception, the check request is subdued.

Parameters:

  • check (Hash)

    definition.

Returns:

  • (TrueClass, FalseClass)


106
107
108
109
110
111
112
# File 'lib/sensu/server/filter.rb', line 106

def check_request_subdued?(check)
  if check[:subdue] && check[:subdue][:at] == "publisher"
    action_subdued?(check[:subdue])
  else
    false
  end
end

#eval_attribute_value(raw_eval_string, value) ⇒ TrueClass, FalseClass

Ruby eval() a string containing an expression, within the scope/context of a sandbox. This method is for filter attribute values starting with “eval:”, with the Ruby expression following the colon. A single variable is provided to the expression, ‘value`, equal to the corresponding event attribute value. The expression is expected to return a boolean value.

Parameters:

  • raw_eval_string (String)

    containing the Ruby expression to be evaluated.

  • value (Object)

    of the corresponding event attribute.

Returns:

  • (TrueClass, FalseClass)


180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/sensu/server/filter.rb', line 180

def eval_attribute_value(raw_eval_string, value)
  begin
    eval_string = raw_eval_string.gsub(/^eval:(\s+)?/, "")
    !!Sandbox.eval(eval_string, value)
  rescue => error
    @logger.error("filter attribute eval error", {
      :raw_eval_string => raw_eval_string,
      :value => value,
      :error => error.to_s
    })
    false
  end
end

#event_filter(filter_name, event, &callback) ⇒ Object

Determine if an event is filtered by an event filter, standard or extension. This method first checks for the existence of a standard filter, then checks for an extension if a standard filter is not defined. The provided callback is called with a single parameter, indicating if the event was filtered by a filter. If a filter does not exist for the provided name, the event is not filtered.

Parameters:

  • filter_name (String)
  • event (Hash)
  • callback (Proc)


232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/sensu/server/filter.rb', line 232

def event_filter(filter_name, event, &callback)
  case
  when @settings.filter_exists?(filter_name)
    filter = @settings[:filters][filter_name]
    matched = filter_attributes_match?(filter[:attributes], event)
    callback.call(filter[:negate] ? matched : !matched)
  when @extensions.filter_exists?(filter_name)
    extension = @extensions[:filters][filter_name]
    extension.safe_run(event) do |output, status|
      callback.call(status == 0)
    end
  else
    @logger.error("unknown filter", :filter_name => filter_name)
    callback.call(false)
  end
end

#event_filtered?(handler, event, &callback) ⇒ Boolean

Determine if an event is filtered for a handler. If a handler specifies one or more filters, via ‘:filters` or `:filter`, the `event_filter()` method is called for each of them. If any of the filters return `true`, the event is filtered for the handler. If no filters are defined in the handler definition, the event is not filtered.

Parameters:

  • handler (Hash)

    definition.

  • event (Hash)
  • callback (Proc)

Returns:

  • (Boolean)


259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
# File 'lib/sensu/server/filter.rb', line 259

def event_filtered?(handler, event, &callback)
  if handler.has_key?(:filters) || handler.has_key?(:filter)
    filter_list = Array(handler[:filters] || handler[:filter])
    filter_results = EM::Iterator.new(filter_list)
    run_filters = Proc.new do |filter_name, iterator|
      event_filter(filter_name, event) do |filtered|
        iterator.return(filtered)
      end
    end
    filtered = Proc.new do |results|
      callback.call(results.any?)
    end
    filter_results.map(run_filters, filtered)
  else
    callback.call(false)
  end
end

#filter_attributes_match?(hash_one, hash_two) ⇒ TrueClass, FalseClass

Determine if all filter attribute values match those of the corresponding event attributes. Attributes match if the value objects are equivalent, are both hashes with matching key/value pairs (recursive), have equal string values, or evaluate to true (Ruby eval).

Parameters:

  • hash_one (Hash)
  • hash_two (Hash)

Returns:

  • (TrueClass, FalseClass)


203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/sensu/server/filter.rb', line 203

def filter_attributes_match?(hash_one, hash_two)
  hash_one.all? do |key, value_one|
    value_two = hash_two[key]
    case
    when value_one == value_two
      true
    when value_one.is_a?(Hash) && value_two.is_a?(Hash)
      filter_attributes_match?(value_one, value_two)
    when hash_one[key].to_s == hash_two[key].to_s
      true
    when value_one.is_a?(String) && value_one.start_with?("eval:")
      eval_attribute_value(value_one, value_two)
    else
      false
    end
  end
end

#filter_event(handler, event, &callback) ⇒ Object

Attempt to filter an event for a handler. This method will check to see if handling is disabled, if the event action is handled, if the event check severity is handled, if the handler is sbuded, and if the event is filtered by any of the filters specified in the handler definition.

Parameters:

  • handler (Hash)

    definition.

  • event (Hash)
  • callback (Proc)


286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
# File 'lib/sensu/server/filter.rb', line 286

def filter_event(handler, event, &callback)
  details = {:handler => handler, :event => event}
  filter_message = case
  when handling_disabled?(event)
    "event handling disabled for event"
  when !handle_action?(handler, event)
    "handler does not handle action"
  when !handle_severity?(handler, event)
    "handler does not handle event severity"
  when handler_subdued?(handler, event)
    "handler is subdued"
  end
  if filter_message
    @logger.info(filter_message, details)
    @handling_event_count -= 1 if @handling_event_count
  else
    event_filtered?(handler, event) do |filtered|
      unless filtered
        callback.call(event)
      else
        @logger.info("event was filtered", details)
        @handling_event_count -= 1 if @handling_event_count
      end
    end
  end
end

#handle_action?(handler, event) ⇒ TrueClass, FalseClass

Determine if an event with an action should be handled. An event action of ‘:flapping` indicates that the event state is flapping, and the event should not be handled unless its handler has `:handle_flapping` set to `true`.

Parameters:

  • handler (Hash)

    definition.

  • event (Hash)

Returns:

  • (TrueClass, FalseClass)


132
133
134
135
# File 'lib/sensu/server/filter.rb', line 132

def handle_action?(handler, event)
  event[:action] != :flapping ||
    (event[:action] == :flapping && !!handler[:handle_flapping])
end

#handle_severity?(handler, event) ⇒ TrueClass, FalseClass

Determine if an event with a check severity will be handled. Event handlers can specify the check severities they will handle, using the definition attribute ‘:severities`. The possible severities are “ok”, “warning”, “critical”, and “unknown”. Handler severity filtering is bypassed when the event `:action` is `:resolve`, if the check history contains one of the specified severities since the last OK result.

Parameters:

  • handler (Hash)

    definition.

  • event (Hash)

Returns:

  • (TrueClass, FalseClass)


148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/sensu/server/filter.rb', line 148

def handle_severity?(handler, event)
  if handler.has_key?(:severities)
    case event[:action]
    when :resolve
      event[:check][:history].reverse[1..-1].any? do |status|
        if status.to_i == 0
          break false
        end
        severity = SEVERITIES[status.to_i] || "unknown"
        handler[:severities].include?(severity)
      end
    else
      severity = SEVERITIES[event[:check][:status]] || "unknown"
      handler[:severities].include?(severity)
    end
  else
    true
  end
end

#handler_subdued?(handler, event) ⇒ TrueClass, FalseClass

Determine if an event handler is subdued, by conditions set in the check and/or the handler definition. If any of the conditions are true, without an exception, the handler is subdued.

Parameters:

  • handler (Hash)

    definition.

  • event (Hash)

    data possibly containing subdue conditions.

Returns:

  • (TrueClass, FalseClass)


88
89
90
91
92
93
94
95
96
97
98
# File 'lib/sensu/server/filter.rb', line 88

def handler_subdued?(handler, event)
  subdued = []
  if handler[:subdue]
    subdued << action_subdued?(handler[:subdue])
  end
  check = event[:check]
  if check[:subdue] && check[:subdue][:at] != "publisher"
    subdued << action_subdued?(check[:subdue])
  end
  subdued.any?
end

#handling_disabled?(event) ⇒ TrueClass, FalseClass

Determine if handling is disabled for an event. Check definitions can disable event handling with an attribute, ‘:handle`, by setting it to `false`.

Parameters:

  • event (Hash)

Returns:

  • (TrueClass, FalseClass)


120
121
122
# File 'lib/sensu/server/filter.rb', line 120

def handling_disabled?(event)
  event[:check][:handle] == false
end

#subdue_days?(condition) ⇒ TrueClass, FalseClass

Determine if the current day is subdued. The provided condition must have a list of ‘:days`, or false will be returned.

Parameters:

  • condition (Hash)

Options Hash (condition):

  • :days (Array)

    of the week to subdue.

Returns:

  • (TrueClass, FalseClass)


38
39
40
41
42
43
44
45
# File 'lib/sensu/server/filter.rb', line 38

def subdue_days?(condition)
  if condition.has_key?(:days)
    days = condition[:days].map(&:downcase)
    days.include?(Time.now.strftime("%A").downcase)
  else
    false
  end
end

#subdue_exception?(condition) ⇒ TrueClass, FalseClass

Determine if there is an exception a period of time (window) that is subdued. The provided condition must have an ‘:exception`, containing one or more `:begin` and `:end` times, eg. “11:30:00 PM”, or `false` will be returned. If there are any exceptions to a subdued period of time, `true` will be returned.

Parameters:

  • condition (Hash)

Options Hash (condition):

  • :exceptions (Hash)

    array of ‘:begin` and `:end` times.

Returns:

  • (TrueClass, FalseClass)


58
59
60
61
62
63
64
65
66
# File 'lib/sensu/server/filter.rb', line 58

def subdue_exception?(condition)
  if condition.has_key?(:exceptions)
    condition[:exceptions].any? do |exception|
      Time.now >= Time.parse(exception[:begin]) && Time.now <= Time.parse(exception[:end])
    end
  else
    false
  end
end

#subdue_time?(condition) ⇒ TrueClass, FalseClass

Determine if a period of time (window) is subdued. The provided condition must have a ‘:begin` and `:end` time, eg. “11:30:00 PM”, or `false` will be returned.

Parameters:

  • condition (Hash)

Options Hash (condition):

  • :begin (String)

    time.

  • :end (String)

    time.

Returns:

  • (TrueClass, FalseClass)


14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/sensu/server/filter.rb', line 14

def subdue_time?(condition)
  if condition.has_key?(:begin) && condition.has_key?(:end)
    begin_time = Time.parse(condition[:begin])
    end_time = Time.parse(condition[:end])
    if end_time < begin_time
      if Time.now < end_time
        begin_time = Time.parse("12:00:00 AM")
      else
        end_time = Time.parse("11:59:59 PM")
      end
    end
    Time.now >= begin_time && Time.now <= end_time
  else
    false
  end
end