gitlab-exporter 14.4.0 → 15.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: e925093b6d87edda1419b3b92a1166f599084a24768cc0082cb3f2d2e662fc37
4
- data.tar.gz: 89a3598b636def73036a3ae4e1f9982a420fb4c04376039ac769b0e38ff6bc68
3
+ metadata.gz: aa3c6ff71709207bbbe1c85dea19eab223c678c721baf437eed2275ad73816b9
4
+ data.tar.gz: f263b55d0e45ece0a7d3124511c684eacbe78532eae81e2f4c11f3ec4279af9b
5
5
  SHA512:
6
- metadata.gz: cfd9e51c7dd85bba95f79e618fdb33a5e5f81cb8626352fb335861aeacfecb80f896e76d124f73ffdf46d9552ef37fb757d6f2a3ddc78fb49b402faf8caecb52
7
- data.tar.gz: a0d0f3d11bb8f09ae1a7a0d5a9f8f4a038a400a616850c5e12d8f48ad05ac74eea5cf4db0c3770905e8e2d1fbab3ab85f43dbc7da8e728b2ff2065077f733ee0
6
+ metadata.gz: 8db3f5dd5db87f02d7a85fb58c13e8a48df40726c5718fd82d5b7ae792675948bd43664da3f94075527e5242c0dcf8bc5e150f8606611097677a812981d73354
7
+ data.tar.gz: 9411698d4c809eba8997bd8fc0f9cc4295dac625daa35a8faf37604909a20fde621afb161534bd82fa912087cf50de45e5e192186627cb95f5c8b5643de1742e
data/.gitlab-ci.yml CHANGED
@@ -50,9 +50,32 @@ rspec_integration:
50
50
  - bundle exec rspec spec -t integration -f d -c
51
51
  before_script: *before_scripts
52
52
  services:
53
- - redis:latest
53
+ - name: redis:${REDIS_VERSION}
54
+ alias: redis-master
55
+ - name: bitnami/redis-sentinel:${REDIS_SENTINEL_VERSION}
56
+ alias: redis-sentinel
57
+ command:
58
+ - /bin/sh
59
+ - -c
60
+ - |
61
+ echo "Starting Redis Sentinel..."
62
+ cat <<EOF > /opt/bitnami/redis-sentinel/etc/sentinel.conf
63
+ user default off
64
+ user ${REDIS_SENTINEL_USERNAME} on >${REDIS_SENTINEL_PASSWORD} +@all
65
+ sentinel monitor mymaster redis-master 6379 2
66
+ sentinel resolve-hostnames yes
67
+ sentinel down-after-milliseconds mymaster 5000
68
+ EOF
69
+ redis-sentinel /opt/bitnami/redis-sentinel/etc/sentinel.conf
70
+
54
71
  variables:
55
72
  REDIS_URL: "redis://redis"
73
+ REDIS_SENTINEL_URL: "redis://mymaster"
74
+ REDIS_SENTINELS: "redis-sentinel:26379"
75
+ REDIS_VERSION: latest
76
+ REDIS_SENTINEL_VERSION: latest
77
+ REDIS_SENTINEL_USERNAME: "my-sentinel-username"
78
+ REDIS_SENTINEL_PASSWORD: "my-sentinel-password"
56
79
  parallel:
57
80
  matrix:
58
81
  - RUBY_VERSION: ["2.7", "3.0", "3.1", "3.2"]
data/Gemfile.lock CHANGED
@@ -1,16 +1,16 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gitlab-exporter (14.4.0)
4
+ gitlab-exporter (15.0.0)
5
5
  connection_pool (= 2.2.5)
6
6
  deep_merge (~> 1.2.2)
7
7
  faraday (>= 1.8.0, <= 2.8.1)
8
8
  pg (= 1.5.3)
9
9
  puma (= 5.6.8)
10
10
  quantile (= 0.2.1)
11
- redis (= 4.4.0)
11
+ redis (= 4.5.0)
12
12
  redis-namespace (= 1.9.0)
13
- sidekiq (= 6.4.0)
13
+ sidekiq (= 6.5.12)
14
14
  sinatra (~> 2.2.0)
15
15
  webrick (~> 1.7)
16
16
 
@@ -41,7 +41,7 @@ GEM
41
41
  rack-protection (2.2.4)
42
42
  rack
43
43
  rainbow (3.0.0)
44
- redis (4.4.0)
44
+ redis (4.5.0)
45
45
  redis-namespace (1.9.0)
46
46
  redis (>= 4)
47
47
  regexp_parser (2.0.3)
@@ -72,10 +72,10 @@ GEM
72
72
  parser (>= 2.7.1.5)
73
73
  ruby-progressbar (1.11.0)
74
74
  ruby2_keywords (0.0.5)
75
- sidekiq (6.4.0)
76
- connection_pool (>= 2.2.2)
75
+ sidekiq (6.5.12)
76
+ connection_pool (>= 2.2.5, < 3)
77
77
  rack (~> 2.0)
78
- redis (>= 4.2.0)
78
+ redis (>= 4.5.0, < 5)
79
79
  sinatra (2.2.4)
80
80
  mustermann (~> 2.0)
81
81
  rack (~> 2.2)
@@ -98,6 +98,14 @@ probes:
98
98
  # redis_username: 'redis-username'
99
99
  # redis_password: 'redis-password'
100
100
  redis_enable_client: true
101
+ # Uncomment if Redis Sentinels are needed
102
+ # redis_sentinels:
103
+ # - host: 'localhost'
104
+ # port: 26380
105
+ # - host: 'localhost'
106
+ # port: 26381
107
+ # redis_sentinel_username: 'redis-sentinel-username'
108
+ # redis_sentinel_password: 'redis-sentinel-password'
101
109
 
102
110
  ruby: &ruby
103
111
  class_name: RubyProber
@@ -28,9 +28,9 @@ Gem::Specification.new do |s|
28
28
  s.add_runtime_dependency "pg", "1.5.3"
29
29
  s.add_runtime_dependency "puma", "5.6.8"
30
30
  s.add_runtime_dependency "quantile", "0.2.1"
31
- s.add_runtime_dependency "redis", "4.4.0"
31
+ s.add_runtime_dependency "redis", "4.5.0"
32
32
  s.add_runtime_dependency "redis-namespace", "1.9.0"
33
- s.add_runtime_dependency "sidekiq", "6.4.0"
33
+ s.add_runtime_dependency "sidekiq", "6.5.12"
34
34
  s.add_runtime_dependency "sinatra", "~> 2.2.0"
35
35
  s.add_runtime_dependency "webrick", "~> 1.7"
36
36
 
@@ -297,12 +297,24 @@ module GitLab
297
297
  @target = File.open(@target, "a") if @target.is_a?(String)
298
298
  end
299
299
 
300
- def options(args)
300
+ def options(args) # rubocop:disable Metrics/MethodLength
301
301
  args.options do |opts|
302
302
  opts.banner = "Usage: #{EXECUTABLE_NAME} #{COMMAND_NAME} [options]"
303
303
  opts.on("--redis-url=\"redis://localhost:6379\"", "Redis URL") do |val|
304
304
  @redis_url = val
305
305
  end
306
+ opts.on("--redis-sentinel-username=\"my-sentinel-username\"", "Redis Sentinel username") do |val|
307
+ @redis_sentinel_username = val
308
+ end
309
+ opts.on("--redis-sentinel-password=\"my-sentinel-password\"", "Redis Sentinel password") do |val|
310
+ @redis_sentinel_password = val
311
+ end
312
+ opts.on("--redis-sentinels=HOST1:PORT1,HOST2:PORT2", Array, "List of Redis Sentinels") do |val|
313
+ @redis_sentinels = val.map { |item|
314
+ host, port = item.split(":")
315
+ { host: host, port: port.to_i }
316
+ }
317
+ end
306
318
  end
307
319
  end
308
320
 
@@ -313,13 +325,19 @@ module GitLab
313
325
  def run
314
326
  validate!
315
327
 
316
- ::GitLab::Exporter::SidekiqProber.new(redis_url: @redis_url)
317
- .probe_stats
318
- .probe_queues
319
- .probe_jobs_limit
320
- .probe_workers
321
- .probe_retries
322
- .write_to(@target)
328
+ prober = ::GitLab::Exporter::SidekiqProber.new(redis_url: @redis_url,
329
+ redis_sentinels: @redis_sentinels,
330
+ redis_sentinel_username: @redis_sentinel_username,
331
+ redis_sentinel_password: @redis_sentinel_password,
332
+ logger: Logger.new(STDERR))
333
+
334
+ prober
335
+ .probe_stats
336
+ .probe_queues
337
+ .probe_jobs_limit
338
+ .probe_workers
339
+ .probe_retries
340
+ .write_to(@target)
323
341
  end
324
342
 
325
343
  private
@@ -62,6 +62,10 @@ module GitLab
62
62
  conn.reset
63
63
  raise e
64
64
  end
65
+ rescue PG::ConnectionBad => e
66
+ @logger.error "Bad connection to the database, resetting pool: #{e}" if @logger
67
+ connection_pool.reload(&:close)
68
+ raise e
65
69
  rescue PG::Error => e
66
70
  @logger.error "Error connecting to the database: #{e}" if @logger
67
71
  raise e
@@ -7,7 +7,7 @@ module GitLab
7
7
  # A prober for Sidekiq queues
8
8
  #
9
9
  # It takes the Redis URL Sidekiq is connected to
10
- class SidekiqProber
10
+ class SidekiqProber # rubocop:disable Metrics/ClassLength
11
11
  # The maximum depth (from the head) of each queue to probe. Probing the
12
12
  # entirety of a very large queue will take longer and run the risk of
13
13
  # timing out. But when we have a very large queue, we are most in need of
@@ -195,6 +195,7 @@ module GitLab
195
195
  def redis_options
196
196
  options = {
197
197
  url: @opts[:redis_url],
198
+ sentinels: redis_sentinel_options,
198
199
  connect_timeout: 1,
199
200
  reconnect_attempts: 0
200
201
  }
@@ -207,6 +208,19 @@ module GitLab
207
208
  options
208
209
  end
209
210
 
211
+ def redis_sentinel_options
212
+ sentinels = @opts[:redis_sentinels]
213
+
214
+ return sentinels unless sentinels.is_a?(Array)
215
+
216
+ sentinels.each do |sentinel_config|
217
+ sentinel_config[:username] = @opts[:redis_sentinel_username] if @opts.key?(:redis_sentinel_username)
218
+ sentinel_config[:password] = @opts[:redis_sentinel_password] if @opts.key?(:redis_sentinel_password)
219
+ end
220
+
221
+ sentinels
222
+ end
223
+
210
224
  def redis_enable_client?
211
225
  return true if @opts[:redis_enable_client].nil?
212
226
 
@@ -221,6 +235,8 @@ module GitLab
221
235
  end
222
236
  rescue Redis::BaseConnectionError => e
223
237
  @logger&.error "Error connecting to the Redis: #{e}"
238
+ pool = self.class.connection_pool[redis_options]
239
+ pool.reload(&:close)
224
240
  @connected = false
225
241
  end
226
242
  end
@@ -1,5 +1,5 @@
1
1
  module GitLab
2
2
  module Exporter
3
- VERSION = "14.4.0".freeze
3
+ VERSION = "15.0.0".freeze
4
4
  end
5
5
  end
@@ -290,6 +290,22 @@ describe GitLab::Exporter::Database do
290
290
  expect(output).to match(/^ci_stale_builds 0.0$/m)
291
291
  end
292
292
  end
293
+
294
+ context "when PG connection shuts down" do
295
+ before do
296
+ allow(connection).to receive(:exec).and_raise(PG::ConnectionBad)
297
+ end
298
+
299
+ it "responds with Prometheus metrics" do
300
+ expect(connection_pool).to receive(:reload)
301
+
302
+ prober.probe_db
303
+ prober.write_to(writer)
304
+ output = writer.string
305
+
306
+ expect(output).to be_empty
307
+ end
308
+ end
293
309
  end
294
310
 
295
311
  context "when executed on EE" do
@@ -6,6 +6,13 @@ module GitLab
6
6
  module CLI
7
7
  describe SidekiqRunner, :integration do
8
8
  let(:redis_url) { ENV.fetch("REDIS_URL", "redis://localhost:6379") }
9
+ let(:redis_sentinel_url) { ENV.fetch("REDIS_SENTINEL_URL", "redis://mymaster:6379") }
10
+ let(:redis_sentinel_username) { ENV.fetch("REDIS_SENTINEL_USERNAME", "my-sentinel-user") }
11
+ let(:redis_sentinel_password) { ENV.fetch("REDIS_SENTINEL_PASSWORD", "my-sentinel-password") }
12
+ let(:redis_sentinels) do
13
+ sentinels = ENV.fetch("REDIS_SENTINELS", "localhost:26379")
14
+ sentinels.split(" ")
15
+ end
9
16
  let(:io) { StringIO.new }
10
17
 
11
18
  it "can properly reach out to redis" do
@@ -14,6 +21,16 @@ module GitLab
14
21
 
15
22
  expect { runner.run }.not_to raise_error
16
23
  end
24
+
25
+ it "can properly reach out to redis-sentinel" do
26
+ args = CLIArgs.new([io], options: { /^--redis-url/ => redis_sentinel_url,
27
+ /^--redis-sentinel-username/ => redis_sentinel_username,
28
+ /^--redis-sentinel-password/ => redis_sentinel_password,
29
+ /^--redis-sentinels/ => redis_sentinels })
30
+ runner = SidekiqRunner.new(args)
31
+
32
+ expect { runner.run }.not_to raise_error
33
+ end
17
34
  end
18
35
  end
19
36
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitlab-exporter
3
3
  version: !ruby/object:Gem::Version
4
- version: 14.4.0
4
+ version: 15.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pablo Carranza
@@ -106,14 +106,14 @@ dependencies:
106
106
  requirements:
107
107
  - - '='
108
108
  - !ruby/object:Gem::Version
109
- version: 4.4.0
109
+ version: 4.5.0
110
110
  type: :runtime
111
111
  prerelease: false
112
112
  version_requirements: !ruby/object:Gem::Requirement
113
113
  requirements:
114
114
  - - '='
115
115
  - !ruby/object:Gem::Version
116
- version: 4.4.0
116
+ version: 4.5.0
117
117
  - !ruby/object:Gem::Dependency
118
118
  name: redis-namespace
119
119
  requirement: !ruby/object:Gem::Requirement
@@ -134,14 +134,14 @@ dependencies:
134
134
  requirements:
135
135
  - - '='
136
136
  - !ruby/object:Gem::Version
137
- version: 6.4.0
137
+ version: 6.5.12
138
138
  type: :runtime
139
139
  prerelease: false
140
140
  version_requirements: !ruby/object:Gem::Requirement
141
141
  requirements:
142
142
  - - '='
143
143
  - !ruby/object:Gem::Version
144
- version: 6.4.0
144
+ version: 6.5.12
145
145
  - !ruby/object:Gem::Dependency
146
146
  name: sinatra
147
147
  requirement: !ruby/object:Gem::Requirement
@@ -278,7 +278,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
278
278
  - !ruby/object:Gem::Version
279
279
  version: '0'
280
280
  requirements: []
281
- rubygems_version: 3.3.26
281
+ rubygems_version: 3.3.27
282
282
  signing_key:
283
283
  specification_version: 4
284
284
  summary: GitLab metrics exporter