summaryrefslogtreecommitdiff
blob: 3d560b91eaa5fff3ec1789210273d3d11623ca94 (plain)
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
require 'singleton'
require 'json'
require 'date'

# Defining state constants
module State
  UP=1
  DOWN=2
  WARNING=3
  NA=0
end

module HelperMethods
  # Checks if all hosts are up
  def all_hosts_up?(hosts)
    hosts.each do |host|
      return false unless
          status_data['hosts'].has_key?(host) and
              status_data['hosts'][host]['current_state'] == 0
    end

    true
  end

  def host_up?(host)
    status_data['hosts'].has_key?(host) and
        status_data['hosts'][host]['current_state'] == 0
  end

  def host_flapping?(host)
    status_data['hosts'].has_key?(host) and
        status_data['hosts'][host]['is_flapping'] != 0
  end

  # Checks if the service is up
  def service_up?(host, service)
    status_data['services'].has_key?(host) and
        status_data['services'][host].has_key?(service) and
        status_data['services'][host][service]['current_state'] == 0
  end

  def service_flapping?(host, service)
    status_data['services'].has_key?(host) and
        status_data['services'][host].has_key?(service) and
        status_data['services'][host][service]['is_flapping'] != 0
  end

  def has_service?(host, service)
    status_data['services'][host].has_key?(service)
  end

  def default(host, service = nil)
    if service == nil
      if host_flapping? host
        State::WARNING
      elsif host_up? host
        State::UP
      else
        State::DOWN
      end
    else
      return State::NA unless has_service? host, service

      if service_flapping? host, service
        State::WARNING
      elsif service_up? host, service
        State::UP
      else
        State::DOWN
      end
    end
  end
end

class ServiceRegistry
  CACHE_SECONDS = 600
  StatusSource = File.join(File.dirname(__FILE__), '..', 'data', 'status.json')

  include Singleton
  include HelperMethods
  attr_reader :load_date

  def initialize
    @cache_locked = false
    @next_name = nil
  end

  def name(n)
    @next_name = n
  end

  def service(name, &block)
    @services[name] = {}
    @services[name][:name] = @next_name || name

    begin
      @services[name][:status] = block.call
    rescue Exception => e
      @services[name][:status] = State::NA
      $stderr.puts e
    end

    @next_name = nil
  end

  def services
    update?
    @services
  end

  def status_data
    update?
    @status_data
  end

  def update!
    @cache_locked = true
    @services = {}
    @status_data = JSON.parse(File.read(StatusSource))
    load(File.join(File.dirname(__FILE__), '..', 'data', 'services.rb'))
    @load_date = DateTime.now
    @cache_locked = false
  rescue Exception => e
    $stderr.puts e
    @services = {}
    @load_date = DateTime.new(2000, 1, 1)
    @cache_locked = false
  end

  private
  def update?
    if not @load_date.nil? and not @cache_locked and ((DateTime.now - @load_date) * 60 * 60 * 24).to_i > CACHE_SECONDS
      update!
    end
  end
end

def Services(&block)
  ServiceRegistry.instance.instance_eval(&block)
end