Class: Perus::Pinger::Pinger

Inherits:
Object
  • Object
show all
Defined in:
lib/perus/pinger/pinger.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options_path = DEFAULT_PINGER_OPTIONS_PATH) ⇒ Pinger

Returns a new instance of Pinger.



72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/perus/pinger/pinger.rb', line 72

def initialize(options_path = DEFAULT_PINGER_OPTIONS_PATH)
    Pinger.options.load(options_path, DEFAULT_PINGER_OPTIONS)
    @server_uri  = URI(Pinger.options.server)

    @metrics = []
    @metric_results = {}
    @metric_errors = {}

    @actions = []
    @action_results = {}
    @late_actions = []
end

Class Method Details

.optionsObject



68
69
70
# File 'lib/perus/pinger/pinger.rb', line 68

def self.options
    @options ||= Perus::Options.new
end

Instance Method Details

#add_to_payload(payload, field, results) ⇒ Object


response




184
185
186
187
188
189
190
191
192
193
# File 'lib/perus/pinger/pinger.rb', line 184

def add_to_payload(payload, field, results)
    results.each do |name, val|
        next unless val.instance_of?(File)
        uuid = SecureRandom.uuid
        results[name] = {file: uuid}
        payload[uuid] = val
    end

    payload[field] = JSON.dump(results)
end

#cleanupObject


cleanup




224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/perus/pinger/pinger.rb', line 224

def cleanup
    @metrics.each do |metric|
        begin
            metric.cleanup
        rescue => e
            puts 'Error running metric cleanup'
            puts format_exception(e)
        end
    end

    @actions.each do |action|
        begin
            action.cleanup
        rescue => e
            puts 'Error running action cleanup'
            puts format_exception(e)
        end
    end

    @late_actions.each do |code|
        begin
            code.call
        rescue => e
            puts 'Error running late action'
            puts format_exception(e)
        end
    end
end

#format_exception(e) ⇒ Object


run




144
145
146
147
148
149
150
# File 'lib/perus/pinger/pinger.rb', line 144

def format_exception(e)
    if e.backtrace.empty?
        e.inspect
    else
        "#{e.inspect}\n#{e.backtrace.first}"
    end
end

#load_configObject


configuration




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
# File 'lib/perus/pinger/pinger.rb', line 96

def load_config
    if Pinger.options.system_id.nil?
        config_path = URI("systems/config_for_ip")
    else
        config_path = URI("systems/#{Pinger.options.system_id}/config")
    end

    config_url = (@server_uri + config_path).to_s

    # load the system config by requesting it from the perus server
    json = JSON.parse(RestClient.get(config_url))
    json['metrics'] ||= []
    json['actions'] ||= []
    @system_id = json['id']

    # load metric and command modules based on the config
    json['metrics'].each do |config|
        begin
            if ::Perus::Pinger.const_defined?(config['type'])
                metric = ::Perus::Pinger.const_get(config['type'])
                @metric_errors[metric.name] ||= []
                @metrics << metric.new(config['options'])
            else
                @metric_errors[config['type']] = format_exception(e)
            end
        rescue => e
            @metric_errors[metric.name] << format_exception(e)
        end
    end

    json['actions'].each do |config|
        begin
            command = ::Perus::Pinger.const_get(config['type'])
            @actions << command.new(config['options'], config['id'])
        rescue => e
            if config['id']
                @action_results[config['id']] = format_exception(e)
            else
                puts 'Error - action does not have an associated id'
                p config
            end
        end
    end
end

#runObject



85
86
87
88
89
90
91
# File 'lib/perus/pinger/pinger.rb', line 85

def run
    load_config
    run_actions
    run_metrics
    send_response
    cleanup
end

#run_actionsObject



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/perus/pinger/pinger.rb', line 163

def run_actions
    @actions.each do |action|
        begin
            result = action.run

            if result.instance_of?(Proc)
                @late_actions << result
                result = true
            end

            @action_results[action.id] = result

        rescue => e
            @action_results[action.id] = format_exception(e)
        end
    end
end

#run_metricsObject



152
153
154
155
156
157
158
159
160
161
# File 'lib/perus/pinger/pinger.rb', line 152

def run_metrics
    @metrics.each do |metric|
        begin
            result = metric.run
            @metric_results.merge!(result)
        rescue => e
            @metric_errors[metric.class.name] << format_exception(e)
        end
    end
end

#send_responseObject



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
# File 'lib/perus/pinger/pinger.rb', line 195

def send_response
    # prepare the response and replace file results with a reference
    # to the uploaded file. files are sent as top level parameters in
    # the payload, while metric and action results are sent as a json
    # object with a reference to these files.
    payload = {}
    add_to_payload(payload, 'metrics', @metric_results)
    add_to_payload(payload, 'actions', @action_results)

    # metric_errors is created with a key for each metric type. most
    # metrics should run without any errors, so remove these entries
    # before adding errors to the payload.
    @metric_errors.reject! {|metric, errors| errors.empty?}
    add_to_payload(payload, 'metric_errors', @metric_errors)

    pinger_path = URI("systems/#{@system_id}/ping")
    pinger_url = (@server_uri + pinger_path).to_s

    begin
        RestClient.post(pinger_url, payload)
    rescue => e
        puts 'Ping failed with exception'
        puts format_exception(e)
    end
end