cronitor 4.1.2 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 33e095f9fcce446c592729b13d8de07592c2549bdb4b4f19c5c4a09fe6024415
4
- data.tar.gz: f3d808e0588b6ac2e03dd4b0b79d41320b37f004f4c8858008076a307acfab84
3
+ metadata.gz: 1c33ade0ff17f4941318a1483b1255556d2b5d7b3c89c41fa70ffb9d6bc05a4b
4
+ data.tar.gz: 2e2c69fe75cf72f65964d59994a3dce7e58266449bd21be76428b4c1f32d354a
5
5
  SHA512:
6
- metadata.gz: 87bb2ea79e7d93ca390296964de090e08f7b010e65aa1626154bd7677c131ab01e896065cacece5701374aacfebc9d7e2823186302245a3dd3d45d1f0069db5d
7
- data.tar.gz: 035fa6604dbc17370f36d8b4833c2aa0938671cef3e85d600a82b811ac1df1306583870478a23be54e645f339d4fe4c504a73416d015a6bc35d11d88952f021b
6
+ metadata.gz: 98a47cd2ded8d3661ea8527b4dfd4b457b6b6d92ed101fac6f58e5d43eb791564b7f074dbfed5019036f9b1a01ed3f6f0687d8bbd90c5c19f3a7cf21cbe5d5d0
7
+ data.tar.gz: f69e2de58e9cfa009e4255c6613e5338d68babdac5bd3848e9b1aea8ee4e6411694750b4e933dadaa447a0033b51f4ef120801e5305f704785c7bfedb4ce79ee
data/.rubocop.yml CHANGED
@@ -12,6 +12,9 @@ AllCops:
12
12
  TargetRubyVersion: 2.5
13
13
  Exclude:
14
14
  - 'spec/cronitor_spec.rb'
15
+
16
+ RequireMFA:
17
+ Enabled: false
15
18
 
16
19
  Metrics/AbcSize:
17
20
  Enabled: false
data/README.md CHANGED
@@ -69,7 +69,7 @@ a deployment or build process. For details on all of the attributes that can be
69
69
  require 'cronitor'
70
70
  Cronitor.api_key = 'api_key_123'
71
71
 
72
- # read config file and set credentials (if included).
72
+ # read config file.
73
73
  Cronitor.read_config('./cronitor.yaml')
74
74
 
75
75
  # sync config file's monitors to Cronitor.
@@ -78,6 +78,9 @@ Cronitor.apply_config
78
78
  # send config file's monitors to Cronitor to validate correctness.
79
79
  # monitors will not be saved.
80
80
  Cronitor.validate_config
81
+
82
+ # generate a new config file from the Cronitor API.
83
+ Cronitor.generate_config
81
84
  ```
82
85
 
83
86
  The `cronitor.yaml` file includes three top level keys `jobs`, `checks`, `heartbeats`. You can configure monitors under each key by defining [monitors](https://cronitor.io/docs/monitor-api#attributes).
@@ -178,6 +181,11 @@ require 'cronitor'
178
181
  Cronitor.api_key = 'apiKey123'
179
182
  Cronitor.api_version = '2020-10-01'
180
183
  Cronitor.environment = 'cluster_1_prod'
184
+
185
+ Cronitor.timeout = 20 # defaults to 10 can also be set with ENV['CRONITOR_TIMEOUT']
186
+ Cronitor.logger = nil # defaults to Logger.new($stdout)
187
+ # faster timeout for potentially more time sensitive call
188
+ Cronitor.ping_timeout = 10 # defaults to 5 can also be set with ENV['CRONITOR_PING_TIMEOUT']
181
189
  ```
182
190
 
183
191
  ## Contributing
@@ -1,33 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Cronitor
4
- TYPE_JOB = 'job'
5
- TYPE_HEARTBEAT = 'heartbeat'
6
- TYPE_CHECK = 'check'
7
- MONITOR_TYPES = [TYPE_JOB, TYPE_HEARTBEAT, TYPE_CHECK].freeze
8
- YAML_KEYS = %w[
9
- api_key
10
- api_version
11
- environment
12
- ] + MONITOR_TYPES.map { |t| "#{t}s" }
4
+ MONITOR_TYPES = [
5
+ TYPE_JOB = 'job',
6
+ TYPE_HEARTBEAT = 'heartbeat',
7
+ TYPE_CHECK = 'check'
8
+ ].freeze
9
+ YAML_KEYS = MONITOR_TYPES.map { |t| "#{t}s" }
13
10
 
14
11
  class << self
15
- attr_accessor :api_key, :api_version, :environment, :logger, :config, :_headers
12
+ attr_accessor :api_key, :api_version, :environment, :logger, :config, :timeout, :ping_timeout
16
13
 
17
14
  def configure(&block)
18
15
  block.call(self)
19
16
  end
20
17
  end
21
18
 
22
- self.api_key = ENV['CRONITOR_API_KEY']
23
- self.api_version = ENV['CRONITOR_API_VERSION']
24
- self.environment = ENV['CRONITOR_ENVIRONMENT']
25
- self.config = ENV['CRONITOR_CONFIG']
19
+ self.api_key = ENV.fetch('CRONITOR_API_KEY', nil)
20
+ self.api_version = ENV.fetch('CRONITOR_API_VERSION', nil)
21
+ self.environment = ENV.fetch('CRONITOR_ENVIRONMENT', nil)
22
+ self.timeout = ENV.fetch('CRONITOR_TIMEOUT', nil) || 10
23
+ self.ping_timeout = ENV.fetch('CRONITOR_PING_TIMEOUT', nil) || 5
24
+ self.config = ENV.fetch('CRONITOR_CONFIG', nil)
26
25
  self.logger = Logger.new($stdout)
27
26
  logger.level = Logger::INFO
28
- self._headers = {
29
- 'Content-Type': 'application/json',
30
- 'User-Agent': 'cronitor-ruby',
31
- 'Cronitor-Version': Cronitor.api_version
32
- }
33
27
  end
@@ -6,56 +6,89 @@ module Cronitor
6
6
 
7
7
  PING_RETRY_THRESHOLD = 5
8
8
 
9
+ module Formats
10
+ ALL = [
11
+ JSON = 'json',
12
+ YAML = 'yaml'
13
+ ].freeze
14
+ end
15
+
16
+ module Headers
17
+ JSON = {
18
+ 'Content-Type': 'application/json',
19
+ 'User-Agent': "cronitor-ruby-#{Cronitor::VERSION}",
20
+ 'Cronitor-Version': Cronitor.api_version
21
+ }.freeze
22
+ YAML = JSON.merge({
23
+ 'Content-Type': 'application/yaml'
24
+ })
25
+ end
26
+
9
27
  def self.put(opts = {})
10
28
  rollback = opts[:rollback] || false
11
29
  opts.delete(:rollback)
12
30
 
13
31
  monitors = opts[:monitors] || [opts]
14
32
 
33
+ if opts[:format] == Cronitor::Monitor::Formats::YAML
34
+ url = "#{Cronitor.monitor_api_url}.yaml"
35
+ monitors['rollback'] = true if rollback
36
+ body = YAML.dump(monitors)
37
+ headers = Cronitor::Monitor::Headers::YAML
38
+ else
39
+ url = Cronitor.monitor_api_url
40
+ body = {
41
+ monitors: monitors,
42
+ rollback: rollback
43
+ }.to_json
44
+ headers = Cronitor::Monitor::Headers::JSON
45
+ end
46
+
15
47
  resp = HTTParty.put(
16
- Cronitor.monitor_api_url,
48
+ url,
17
49
  basic_auth: {
18
50
  username: Cronitor.api_key,
19
51
  password: ''
20
52
  },
21
- body: {
22
- monitors: monitors,
23
- rollback: rollback
24
- }.to_json,
25
- headers: Cronitor._headers,
26
- timeout: opts[:timeout] || 10
53
+ body: body,
54
+ headers: headers,
55
+ timeout: opts[:timeout] || Cronitor.timeout
27
56
  )
28
57
 
29
58
  case resp.code
30
59
  when 200
31
- out = []
32
- data = JSON.parse(resp.body)
33
-
34
- (data['monitors'] || []).each do |md|
35
- m = Monitor.new(md['key'])
36
- m.data = Cronitor.symbolize_keys(md)
37
- out << m
60
+ if opts[:format] == Cronitor::Monitor::Formats::YAML
61
+ YAML.safe_load(resp.body)
62
+ else
63
+ out = []
64
+ data = JSON.parse(resp.body)
65
+
66
+ (data['monitors'] || []).each do |md|
67
+ m = Monitor.new(md['key'])
68
+ m.data = Cronitor.symbolize_keys(md)
69
+ out << m
70
+ end
71
+ out.length == 1 ? out[0] : out
38
72
  end
39
- out.length == 1 ? out[0] : out
40
73
  when 400
41
74
  raise ValidationError.new(resp.body)
42
75
  else
43
- raise Error.new("Error connecting to Cronitor: #{resp.code}")
76
+ raise Error.new("Error connecting to Cronitor: #{resp.code}\n #{resp.body}")
44
77
  end
45
78
  end
46
79
 
47
80
  def self.delete(key)
48
81
  resp = HTTParty.delete(
49
82
  "#{Cronitor.monitor_api_url}/#{key}",
50
- timeout: 10,
83
+ timeout: Cronitor.timeout,
51
84
  basic_auth: {
52
85
  username: Cronitor.api_key,
53
86
  password: ''
54
87
  },
55
- headers: Cronitor._headers
88
+ headers: Cronitor::Monitor::Headers::JSON
56
89
  )
57
90
  if resp.code != 204
58
- Cronitor.logger.error("Error deleting monitor: #{key}")
91
+ Cronitor.logger&.error("Error deleting monitor: #{key}")
59
92
  return false
60
93
  end
61
94
  true
@@ -81,7 +114,7 @@ module Cronitor
81
114
  def ping(params = {})
82
115
  retry_count = params[:retry_count] || 0
83
116
  if api_key.nil?
84
- Cronitor.logger.error('No API key detected. Set Cronitor.api_key or initialize Monitor with an api_key:')
117
+ Cronitor.logger&.error('No API key detected. Set Cronitor.api_key or initialize Monitor with an api_key:')
85
118
  return false
86
119
  end
87
120
 
@@ -92,8 +125,8 @@ module Cronitor
92
125
  response = HTTParty.get(
93
126
  ping_url,
94
127
  query: clean_params(params),
95
- timeout: 5,
96
- headers: Cronitor._headers,
128
+ timeout: Cronitor.ping_timeout,
129
+ headers: Cronitor::Monitor::Headers::JSON,
97
130
  query_string_normalizer: lambda do |query|
98
131
  query.compact!
99
132
  metrics = query[:metric]
@@ -106,13 +139,13 @@ module Cronitor
106
139
  )
107
140
 
108
141
  if response.code != 200
109
- Cronitor.logger.error("Cronitor Telemetry Error: #{response.code}")
142
+ Cronitor.logger&.error("Cronitor Telemetry Error: #{response.code}")
110
143
  return false
111
144
  end
112
145
  true
113
146
  rescue StandardError => e
114
147
  # rescue instances of StandardError i.e. Timeout::Error, SocketError, etc
115
- Cronitor.logger.error("Cronitor Telemetry Error: #{e}")
148
+ Cronitor.logger&.error("Cronitor Telemetry Error: #{e}")
116
149
  return false if retry_count >= Monitor::PING_RETRY_THRESHOLD
117
150
 
118
151
  # apply a backoff before sending the next ping
@@ -131,8 +164,8 @@ module Cronitor
131
164
 
132
165
  resp = HTTParty.get(
133
166
  pause_url,
134
- timeout: 5,
135
- headers: Cronitor._headers,
167
+ timeout: Cronitor.timeout,
168
+ headers: Cronitor::Monitor::Headers::JSON,
136
169
  basic_auth: {
137
170
  username: api_key,
138
171
  password: ''
@@ -162,13 +195,13 @@ module Cronitor
162
195
 
163
196
  def fetch
164
197
  unless api_key
165
- Cronitor.logger.error(
198
+ Cronitor.logger&.error(
166
199
  'No API key detected. Set Cronitor.api_key or initialize Monitor with the api_key kwarg'
167
200
  )
168
201
  return
169
202
  end
170
203
 
171
- HTTParty.get(monitor_api_url, timeout: 10, headers: Cronitor._headers, format: :json)
204
+ HTTParty.get(monitor_api_url, timeout: Cronitor.timeout, headers: Cronitor::Monitor::Headers::JSON, format: :json)
172
205
  end
173
206
 
174
207
  def clean_params(params)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Cronitor
4
- VERSION = '4.1.2'
4
+ VERSION = '5.0.0'
5
5
  end
data/lib/cronitor.rb CHANGED
@@ -13,7 +13,7 @@ require 'cronitor/version'
13
13
  require 'cronitor/monitor'
14
14
 
15
15
  module Cronitor
16
- def self.read_config(path = nil, output: false)
16
+ def self.read_config(path = nil)
17
17
  Cronitor.config = path || Cronitor.config
18
18
  unless Cronitor.config
19
19
  raise ConfigurationError.new(
@@ -26,40 +26,23 @@ module Cronitor
26
26
  conf.each do |k, _v|
27
27
  raise ConfigurationError.new("Invalid configuration variable: #{k}") unless Cronitor::YAML_KEYS.include?(k)
28
28
  end
29
-
30
- Cronitor.api_key = conf[:api_key] if conf[:api_key]
31
- Cronitor.api_version = conf[:api_version] if conf[:api_version]
32
- Cronitor.environment = conf[:environment] if conf[:environment]
33
-
34
- return unless output
35
-
36
- monitors = []
37
- Cronitor::MONITOR_TYPES.each do |t|
38
- plural_t = "#{t}s"
39
- to_parse = conf[t] || conf[plural_t] || nil
40
- next unless to_parse
41
-
42
- unless to_parse.is_a?(Hash)
43
- raise ConfigurationError.new('A Hash with keys corresponding to monitor keys is expected.')
44
- end
45
-
46
- to_parse.each do |key, m|
47
- m['key'] = key
48
- m['type'] = t
49
- monitors << m
50
- end
51
- end
52
- conf['monitors'] = monitors
53
29
  conf
54
30
  end
55
31
 
56
32
  def self.apply_config(rollback: false)
57
- conf = read_config(output: true)
58
- # allow a significantly longer timeout on requests that are sending full yaml config
59
- monitors = Monitor.put(monitors: conf.fetch('monitors', []), rollback: rollback, timeout: 30)
60
- puts("#{monitors.length} monitors #{rollback ? 'validated' : 'synced to Cronitor'}.")
33
+ conf = read_config
34
+ # allow a significantly longer timeout on requests that are sending full yaml config. min 30 seconds.
35
+ timeout = Cronitor.timeout < 30 ? 30 : Cronitor.timeout
36
+ monitors = Monitor.put(monitors: conf, format: Cronitor::Monitor::Formats::YAML, rollback: rollback,
37
+ timeout: timeout)
38
+ count = 0
39
+ # step through the different monitor types and count up all the returned configurations
40
+ Cronitor::YAML_KEYS.each do |k|
41
+ count += (monitors[k]&.count || 0)
42
+ end
43
+ puts("#{count} monitors #{rollback ? 'validated' : 'synced to Cronitor'}.")
61
44
  rescue ValidationError => e
62
- Cronitor.logger.error(e)
45
+ Cronitor.logger&.error(e)
63
46
  end
64
47
 
65
48
  def self.validate_config
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cronitor
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.2
4
+ version: 5.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Byrnes
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2021-07-13 00:00:00.000000000 Z
12
+ date: 2022-05-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: httparty