neeto-monitor-ruby 1.0.42

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: adb80970d221b0ba7554aefd49426eb7018de773f7148200ba1fe588f4ccbc20
4
+ data.tar.gz: 7b080f2c0979e732dafa40243b63d56c23c4ccf6636f21a14959bf062cd9bb62
5
+ SHA512:
6
+ metadata.gz: a9e3eafe53eb9b3a117926a0c8b1d59e83816a86156888212827adc949f463f0efe35a01496e7a3d98c61a8c93ee86daf6df44ac2318055d63d8d76f40981b00
7
+ data.tar.gz: b07f078fae394db5cad93fde00a8871b24535006dc803ac2404f8584a964be0355d099fb6f9ce586d3b07405c98aa2183630f22ab144fc5f902f00a60ccfdd31
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 BigBinary
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,288 @@
1
+ # neeto-monitor-ruby
2
+
3
+ neetoMonitor - A ruby gem for monitoring application's uptime and performance.
4
+
5
+ Installation:
6
+
7
+ ##### 1. Add the gem
8
+
9
+ ```bash
10
+ gem "neeto-monitor-ruby", git: "https://github.com/bigbinary/neeto-monitor-ruby.git"
11
+ ```
12
+
13
+ ##### 2. Install the gems
14
+
15
+ ```bash
16
+ bundle install
17
+ ```
18
+
19
+ ##### 3. Add configuration
20
+
21
+ The neetoMonitor can be configured at multiple levels. i.e. using
22
+ `env variables`, adding a `config file` or manually passing the configuration
23
+ hash to `NeetoMonitorRuby.init!`.
24
+
25
+ ###### 3.1 Setting the config via `NeetoMonitorRuby.init!`
26
+
27
+ ```ruby
28
+ NeetoMonitorRuby.init!({
29
+ api_key: your_app_api_key,
30
+ environment: production
31
+
32
+ ...
33
+
34
+ })
35
+ ```
36
+
37
+ ###### 3.2 Using a config file
38
+
39
+ ```yaml
40
+ # config/neetomonitor.yml
41
+ ---
42
+ api_key: [API_KEY]
43
+ ping_timeout: 5
44
+ ```
45
+
46
+ Following are the available configuration options with their default values.
47
+
48
+ ```yaml
49
+ base_url: (default: https://neetomonitor.com)
50
+ # The monitor server base URL. In `development` or `staging` we can set this to local/staging URL.
51
+
52
+ api_key: (default: nil)
53
+ # A unique api key for an organization.
54
+
55
+ environment: (default: nil)
56
+ # The monitoring environment name for an application
57
+
58
+ ping_timeout: (default: 8 seconds)
59
+ # The request timeout for ping requests.
60
+
61
+ sidekiq_enabled:
62
+ # Enables sidekiq plugin to report worker/job events.
63
+
64
+ config_path: (default: "config/neetomonitor.yml")
65
+ # The config file path
66
+
67
+ key_prefix_enabled: (default: true)
68
+ # This allows to enable/disable prefix for monitor key.
69
+
70
+ key_prefix: (default: application's name e.g. NeetoKb if integrated in neetoKb)
71
+ # The prefix added to the monitor key. e.g. if the check name is ArticleWorker, the result will be NeetoKb::ArticleWorker.
72
+
73
+ monitors:
74
+ # more on this in next section
75
+ ```
76
+
77
+ ###### 3.3 Using ENV variables:
78
+
79
+ The `ENV` variables must start with `NEETO_MONITOR` e.g.
80
+ `NEETO_MONITOR_API_KEY`.
81
+
82
+ Similarly, other ENV variables can also be set by prefixing with
83
+ `NEETO_MONITOR_`.
84
+
85
+ The precedence of the configuration is as follows:
86
+
87
+ ```
88
+ Options passed to NeetoMonitorRuby.init! > Config file > ENV variables > default values
89
+ ```
90
+
91
+ ##### 4. Configuring monitors
92
+
93
+ The monitors can be added in bulk using a config file. e.g.
94
+
95
+ ```yaml
96
+ api_key: [API_KEY]
97
+ monitors:
98
+ checks:
99
+ - name: "neeto-monitor"
100
+ request_attributes:
101
+ endpoint: "http://app.neetomonitor.test/health_check/"
102
+ kind: "http"
103
+ verb: "get"
104
+ interval: 10
105
+ timeout: 20
106
+ assertions_attributes:
107
+ - kind: "response_code"
108
+ verb: "equal"
109
+ value: 200
110
+ jobs:
111
+ - name: "neeto-job"
112
+ assertions_attributes:
113
+ - kind: max_duration
114
+ verb: less_than
115
+ value: 10
116
+ - name: "hard-job",
117
+ schedule: "* * * * *"
118
+ heartbeats:
119
+ - name: "neeto-heartbeat"
120
+ schedule: "* * * * *"
121
+ ```
122
+
123
+ The above config will create total four monitors i.e. 2 jobs and 1 check and 1
124
+ heartbeat.
125
+
126
+ ###### 4.1 Checks monitors (Checks)
127
+
128
+ The checks are used for monitoring website's uptime. The website requests are made at regular intervals which is configured via `interval` attribute.
129
+
130
+ ```yaml
131
+ name: # The name of check monitor e.g. "neeto-auth"
132
+ request_attributes: # This specifies configuring options for the website request.
133
+ endpoint: # The request URL endpoint
134
+
135
+ kind: # The request protocol
136
+
137
+ verb: # The request verb/method i.e. get/post/head etc.
138
+
139
+ interval: # The request frequency
140
+
141
+ timeout: # The request timeout
142
+
143
+ assertions_attributes: # This specifies the assertion to be made when a request is made.
144
+ kind:# The kind of assertion to be made
145
+ # available options => response_code, response_time, response_body, response_json, response_header, ssl_expiry, min_duration, max_duration
146
+
147
+ verb:# The operation verb for assertion
148
+ # available options => less_than, less_than_equal, equal, not_equal, greater_than, greater_than_equal, contains, not_contains
149
+
150
+ key:# The key from the response body json or headers
151
+ # e.g. if response body = { "success": true }, key can be "success"
152
+
153
+ value: # Any value to be checked for the assertion
154
+ ```
155
+
156
+ ###### 4.2 Heartbeat monitors (Heartbeats)
157
+
158
+ The heartbeats are used for monitoring the website/service uptime. The basic
159
+ difference between `checks` and `heartbeats` is that the heartbeats requests are
160
+ sent from the host application. Where as the checks requests are made from the
161
+ `neetoMonitor` server application.
162
+
163
+ The heartbeats can be added via the config file. When it is mentioned in the
164
+ config, the heartbeats will be created in neetoMonitor upon the app
165
+ initialization.
166
+
167
+ When `schedule` is defined for the heartbeats, the gem will send the heartbeats
168
+ using the schedule frequency and neetoMonitor can send alerts when heartbeats are not received in this frequency.
169
+
170
+ The heartbeats events are sent using the `HeartbeatRunnerJob`. This sends the ping at time intervals based on the schedule. E.g. following heartbeat sends a ping every minute.
171
+
172
+ ```ruby
173
+ monitors:
174
+ heartbeats:
175
+ - name: "neeto-heartbeat"
176
+ schedule: "* * * * *" # heartbeat frequency
177
+ ```
178
+
179
+ **Trigger heartbeats from application manually**
180
+ The heartbeats can be triggered manually using a periodic job. If you are using `sidekiq`, you can use `sidekiq-cron` to trigger heartbeats at desired frequency.
181
+
182
+ Here is an example of how you can configure heartbeats manually.
183
+
184
+ ```ruby
185
+ # Worker for sending heartbeat
186
+ class HeartbeatsWorker < BaseWorker
187
+ sidekiq_options neeto_monitor_disabled: true
188
+
189
+ def perform
190
+ super
191
+
192
+ NeetoMonitor::Monitor.new("test-heartbeat").ping
193
+ end
194
+ end
195
+
196
+ # config/schedule.yml
197
+ heartbeat:
198
+ cron: "* * * * *"
199
+ class: "HeartbeatsWorker"
200
+ ```
201
+ ###### 4.3 Job monitors (Jobs)
202
+
203
+ The `jobs` are used for checking reliability and performance of background
204
+ workers.
205
+
206
+ All the monitors can be added either via the web application or from the
207
+ mentioned config file.
208
+
209
+ The `jobs` can be created by other methods as well i.e. without adding `jobs` to
210
+ config section or web application UI. This is done using `Sidekiq` plugin
211
+ included in the gem. When any new worker starts execution e.g. `ArticleJob`, the
212
+ job monitor's `run` event is sent automatically. The `complete` event is sent
213
+ when the job execution is successfully completed. Similarly, `fail` event is
214
+ sent when job execution fails. This `ArticleJob` monitor is created at
215
+ `neetoMonitor` application if it is not created already. If we want `schedule`
216
+ field i.e. periodic job events to be sent to neetoMonitor application, we must
217
+ add such jobs to a config file. e.g.
218
+
219
+ ```yaml
220
+ monitors:
221
+ jobs:
222
+ - name: "NeetoWorker"
223
+ schedule: "* * * * *" # frequency of periodic jobs
224
+ - name: "neeto-job"
225
+ assertions_attributes:
226
+ - kind:
227
+ # available values => max_duration, min_duration
228
+ verb:
229
+ # available values => less_than_or_equal, less_than, greater_than, greater_than_or_equal, equal
230
+ value:
231
+ # allowed values => integer/float value
232
+ ```
233
+
234
+ The job events are automatically sent from the `sidekiq` plugin when
235
+ `sidekiq_enabled` is set to true. This flag is set to `true` by default. The job
236
+ events are not sent when this plugin is not enabled. The gem currently supports
237
+ only `Sidekiq` for background job monitoring. If we are using any other library
238
+ for background jobs, we can send the events manually. E.g.
239
+
240
+ ```ruby
241
+ class ArticleJob
242
+ ..
243
+
244
+ ...
245
+
246
+ def perform
247
+ job_monitor = NeetoMonitorRuby::Monitor.new("ArticleJob")
248
+ series_stamp = Time.now.utc.to_f
249
+ job_monitor.job_ping(state: "run", series: series_stamp)
250
+
251
+ process_article_job # job business logic
252
+
253
+ job_monitor.job_ping(state: "complete", series: series_stamp)
254
+ rescue StandardError => error
255
+ job_monitor.job_ping(state: "fail", series: series_stamp, message: error.message)
256
+ end
257
+
258
+ private
259
+
260
+ ..
261
+ end
262
+ ```
263
+
264
+ Sometimes we don't want to monitor some `Sidekiq` workers. We have an option to
265
+ disable the monitoring for such workers.
266
+
267
+ ```ruby
268
+ class MonitorDisabledWorker
269
+ include Sidekiq::Worker
270
+ sidekiq_options neeto_monitor_disabled: true
271
+
272
+ ...
273
+
274
+ end
275
+ ```
276
+
277
+ The default `monitor key` for `jobs` are the class name of the `Sidekiq` worker
278
+ itself. We can change the `key` of the monitored job by setting
279
+ `neeto_monitor_key` in `sidekiq_options`.
280
+
281
+ ```ruby
282
+ class CustomMonitorWorker
283
+ include Sidekiq::Worker
284
+ sidekiq_options neeto_monitor_key: "super_worker"
285
+
286
+ ...
287
+ end
288
+ ```
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/setup"
4
+ require "bundler/gem_tasks"
5
+ require "rake/testtask"
6
+
7
+ Rake::TestTask.new(:test) do |t|
8
+ t.libs << "test"
9
+ t.pattern = "test/**/*_test.rb"
10
+ t.verbose = false
11
+ t.warning = false
12
+ end
13
+
14
+ task default: :test
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ if defined?(::Rails::Railtie)
4
+ require "neeto_monitor_ruby/init/rails"
5
+ else
6
+ require "neeto_monitor_ruby/init/ruby"
7
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
4
+
5
+ module NeetoMonitorRuby
6
+ class ConfigurationError < StandardError; end
7
+
8
+ class Configuration
9
+ BASE_URL = "https://neetomonitor.com".freeze
10
+ DEFAULT_PING_TIMEOUT = 8
11
+ DEFAULT_CONFIG_PATH = "config/neetomonitor.yml"
12
+
13
+ class << self
14
+ attr_accessor :config
15
+
16
+ def configure!(options = {}, reset = false)
17
+ return config if !config.nil? && !reset
18
+
19
+ reset! if reset
20
+
21
+ config_options = options.dup
22
+
23
+ config_path = if options[:config_path]
24
+ options[:config_path]
25
+ else
26
+ file_path = ENV.fetch("NEETO_MONITOR_CONFIG_PATH", DEFAULT_CONFIG_PATH)
27
+
28
+ defined?(Rails) && Rails.respond_to?(:root) ? Rails.root.join(file_path) : file_path
29
+ end
30
+
31
+ config_options = load_config(config_path).merge(config_options) if config_path && load_config?(config_path)
32
+
33
+ self.config = Configuration.new(config_options)
34
+ config
35
+ end
36
+
37
+ def reset!
38
+ self.config = Configuration.new
39
+
40
+ config
41
+ end
42
+
43
+ def load_config?(config_path)
44
+ File.exist?(config_path)
45
+ end
46
+
47
+ def load_config(file_path)
48
+ config = YAML.load(ERB.new(File.read(file_path)).result(binding))
49
+
50
+ JSON.parse(JSON[config], symbolize_names: true)
51
+
52
+ rescue Errno::ENOENT
53
+ raise ConfigurationError.new("#{file_path} not found")
54
+ rescue Psych::SyntaxError => e
55
+ raise ConfigurationError.new("#{file_path} is malformed: #{e.message}")
56
+ end
57
+ end
58
+
59
+ attr_accessor :base_url, :api_key, :environment, :ping_timeout, :logger, :config_path, :monitors,
60
+ :sidekiq_enabled, :key_prefix_enabled, :key_prefix
61
+
62
+ attr_reader :options
63
+
64
+ def initialize(options = {})
65
+ @options = options
66
+ @base_url = fetch_or_set_value(:base_url, BASE_URL)
67
+ @api_key = fetch_or_set_value(:api_key)
68
+ @environment = fetch_or_set_value(:environment)
69
+ @ping_timeout = fetch_or_set_value(:ping_timeout, DEFAULT_PING_TIMEOUT)
70
+ @logger = Logger.new($stdout)
71
+ @sidekiq_enabled = fetch_or_set_value(:sidekiq_enabled, true)
72
+ @config_path = fetch_or_set_value(:config_path)
73
+ @monitors = options[:monitors]
74
+ @key_prefix_enabled = fetch_or_set_value(:key_prefix_enabled, true)
75
+ @key_prefix = fetch_or_set_value(:key_prefix, app_key_prefix)
76
+ end
77
+
78
+ private
79
+
80
+ def fetch_or_set_value(key, default_value = nil)
81
+ env_or_default_value = ENV.fetch("NEETO_MONITOR_#{key.to_s.upcase}", default_value)
82
+
83
+ options.fetch(key, env_or_default_value)
84
+ end
85
+
86
+ def app_key_prefix
87
+ if defined?(Rails) && Rails.respond_to?(:application)
88
+ Rails.application.class.to_s.split("::").first
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fugit"
4
+ require "active_job"
5
+
6
+ module NeetoMonitorRuby
7
+ class HeartbeatRunnerJob < ActiveJob::Base
8
+ queue_as :default
9
+
10
+ def perform(heartbeat_name, schedule)
11
+ NeetoMonitorRuby::Monitor.new(heartbeat_name).ping
12
+
13
+ fugit = Fugit.do_parse_cronish(schedule)
14
+ next_time_string = fugit.next_time(Time.now).to_s
15
+ next_time = Time.parse(next_time_string)
16
+
17
+ NeetoMonitorRuby::HeartbeatRunnerJob.set(wait_until: next_time).perform_later(heartbeat_name, schedule)
18
+ rescue Date::Error, ArgumentError => exception
19
+ NeetoMonitor.logger.error "Error while parsing fugit date time: #{error.message}"
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "logger"
4
+ require "json"
5
+ require "httparty"
6
+ require "socket"
7
+ require "time"
8
+ require "yaml"
9
+
10
+ require "neeto_monitor_ruby/version"
11
+ require "neeto_monitor_ruby/monitor_utils"
12
+ require "neeto_monitor_ruby/monitor"
13
+ require "neeto_monitor_ruby/neeto_monitor"
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails"
4
+
5
+ require_relative "common"
6
+
7
+ module NeetoMonitorRuby
8
+ module Init
9
+ module Rails
10
+ class Railtie < ::Rails::Railtie
11
+ config.before_initialize do
12
+ NeetoMonitorRuby.init!(
13
+ {
14
+ environment: ::Rails.env,
15
+ logger: ::Rails.logger,
16
+ config_path: ::Rails.root.join(Configuration::DEFAULT_CONFIG_PATH)
17
+ })
18
+ end
19
+
20
+ config.after_initialize do
21
+ NeetoMonitorRuby.load_plugins!
22
+ NeetoMonitorRuby.load_monitors!
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "common"
4
+
5
+ NeetoMonitorRuby.init!(
6
+ {
7
+ environment: ENV["RUBY_ENV"] || ENV["RACK_ENV"]
8
+ })
9
+
10
+ NeetoMonitorRuby.load_plugins!
@@ -0,0 +1,158 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "httparty"
4
+ require "sidekiq/api"
5
+ require_relative "heartbeat_runner_job"
6
+
7
+ module NeetoMonitorRuby
8
+ class Monitor
9
+ include MonitorUtils
10
+
11
+ REQUEST_HEADERS = {
12
+ 'Content-Type': "application/json",
13
+ 'Accept': "application/json",
14
+ 'User-Agent': "neeto-monitor-ruby"
15
+ }.freeze
16
+
17
+ MAX_RETRY_COUNT = 3
18
+ BULK_CREATE_PATH = "/api/v1/clients/bulk_checks".freeze
19
+
20
+ class << self
21
+ def load_monitors!
22
+ return unless NeetoMonitorRuby.config.api_key
23
+
24
+ config_monitors = NeetoMonitorRuby.config.monitors&.except(:heartbeats)
25
+
26
+ if !config_monitors.blank?
27
+ environment = NeetoMonitorRuby.config.environment
28
+
29
+ all_monitors = config_monitors.each_with_object([]) do |(type, monitors), result|
30
+ monitors.each { |m| result << m.merge(kind: type.to_s.chop, environment:) }
31
+ end
32
+
33
+ make_bulk_create_request({ checks: all_monitors, api_key: NeetoMonitorRuby.config.api_key })
34
+ else
35
+ NeetoMonitorRuby.logger.debug "No monitors found in config"
36
+ end
37
+ end
38
+
39
+ def make_bulk_create_request(check_params)
40
+ bulk_monitors_url = "#{NeetoMonitorRuby.config.base_url}#{BULK_CREATE_PATH}"
41
+
42
+ response = HTTParty.post(
43
+ bulk_monitors_url,
44
+ body: check_params.to_json,
45
+ headers: REQUEST_HEADERS
46
+ )
47
+
48
+ result = response.code >= 200 && response.code < 300
49
+
50
+ NeetoMonitor.logger.error "Bulk create response code: #{response.code}" unless result
51
+
52
+ load_heartbeats! if defined?(ActiveJob::Base)
53
+
54
+ result
55
+ rescue StandardError => exception
56
+ NeetoMonitor.logger.error exception.message
57
+ NeetoMonitor.logger.error exception.backtrace.join("\n")
58
+ end
59
+
60
+ def load_heartbeats!
61
+ NeetoMonitor.logger.debug "Loading heartbeats!!!"
62
+ NeetoMonitor.logger.debug "NeetoMonitor.config.monitors #{NeetoMonitor.config.monitors}"
63
+ heartbeats = NeetoMonitor.config.monitors[:heartbeats]
64
+ prefix = NeetoMonitor.config.key_prefix_enabled ? NeetoMonitor.config.key_prefix : nil
65
+
66
+ heartbeats.each do |heartbeat|
67
+ heartbeat_name = prefix ? [prefix, heartbeat[:name]].join("::") : heartbeat[:name]
68
+
69
+ delete_old_heartbeat_jobs!
70
+
71
+ HeartbeatRunnerJob.perform_later(heartbeat_name, heartbeat[:schedule])
72
+ end
73
+ end
74
+
75
+ def delete_old_heartbeat_jobs!
76
+ if ActiveJob::Base.queue_adapter.respond_to?(:enqueued_jobs)
77
+ ActiveJob::Base.queue_adapter.enqueued_jobs.reject! do |job|
78
+ job["job_class"] == "NeetoMonitorRuby::HeartbeatRunnerJob"
79
+ end
80
+ elsif ActiveJob::Base.queue_adapter.class == ActiveJob::QueueAdapters::SidekiqAdapter
81
+ Sidekiq::ScheduledSet.new.scan("NeetoMonitorRuby::HeartbeatRunnerJob").each do |job|
82
+ job.delete if job.display_class == "NeetoMonitorRuby::HeartbeatRunnerJob"
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ attr_reader :api_key, :environment, :monitor_key
89
+
90
+ def initialize(monitor_key, api_key: nil, environment: nil)
91
+ @monitor_key = monitor_key
92
+ @api_key = api_key || NeetoMonitorRuby.config.api_key
93
+ @environment = environment || NeetoMonitorRuby.config.environment
94
+ end
95
+
96
+ def ping(params = {})
97
+ if api_key.nil?
98
+ log_error "No API key is provided, please pass the api_key or configure."
99
+ return false
100
+ end
101
+
102
+ retry_count = params[:retry_count] || 0
103
+ response = make_ping_request(params)
104
+ response.code >= 200 && response.code < 300
105
+ rescue StandardError => exception
106
+ return false if retry_count >= MAX_RETRY_COUNT
107
+
108
+ retry_ping(params, retry_count)
109
+ end
110
+
111
+ def job_ping(params)
112
+ ping(params.merge(kind: MONITOR_TYPES[:job]))
113
+ end
114
+
115
+ private
116
+
117
+ def make_ping_request(params)
118
+ response = HTTParty.get(
119
+ monitor_ping_url,
120
+ query: sanitize_params(params),
121
+ headers: REQUEST_HEADERS,
122
+ timeout: NeetoMonitorRuby.config.ping_timeout
123
+ )
124
+ end
125
+
126
+ def retry_ping(params, retry_count)
127
+ retry_count += 1
128
+ sleep(retry_count)
129
+ ping(params.merge(retry_count:))
130
+ end
131
+
132
+ def monitor_ping_url
133
+ "#{NeetoMonitorRuby.config.base_url}/tm/#{api_key}/#{CGI.escape(monitor_key)}"
134
+ end
135
+
136
+ def sanitize_params(params)
137
+ {
138
+ state: params.fetch(:state, nil),
139
+ kind: params.fetch(:kind, MONITOR_TYPES[:heartbeat]),
140
+ message: params.fetch(:message, nil),
141
+ series: params.fetch(:series, nil),
142
+ host: params.fetch(:host, Socket.gethostname),
143
+ metrics: params.fetch(:metrics, nil),
144
+ stamp: generate_stamp,
145
+ env: params.fetch(:env, environment)
146
+ }
147
+ end
148
+
149
+ def log_exception(exception)
150
+ log_error exception.message
151
+ log_error exception.backtrace.join("\n")
152
+ end
153
+
154
+ def log_error(text)
155
+ NeetoMonitorRuby.logger.error text
156
+ end
157
+ end
158
+ end