prometheus_exporter 0.5.3 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a284b77cbd17e80457e94520d18976dc3dd6fb8c238d8a90cda6513e291f01ad
4
- data.tar.gz: 4464419fc9c67d387edd9d6d5bdfac1411d0864d29c0cd3a6f10d2f02b3d7e24
3
+ metadata.gz: f516c39448418a2216851149f0479f3f9e0f5feadae5a5468e7953fc0551d318
4
+ data.tar.gz: dcc937b79e05d4cd74a64ab2135425c75c4bba1be053bec99e8db0695a3ac998
5
5
  SHA512:
6
- metadata.gz: 84c2e2af95a8839cd9deecca9fbc26bacff590ae5cb3677862f1eb1d476401114406130cc78d2248cec0380e70c1b74b306e1265b3343bbac9c09d8400e692a3
7
- data.tar.gz: 41898546588ef7eafa772252ef5ed1a8c222e4009e64ccec35d463217336597a94f1c844f3e2174e030c19a7c1b90d1028e5729cc393cf797654362f5d66b7f2
6
+ metadata.gz: 5664f24c1c4a1520bafe789e5df8a9f1c40b118933cab9b73baa953f633ec6e81c3a11bbc9fc63097a2a2acdd2390daeade9449e6451cc83207fc2162575b359
7
+ data.tar.gz: ca4aeedbc6e211818569257e8a3e9fde93be363a2da246abae45749bc9cc232052ac52f0850cd54d0f600904bed193a10db1f76e4fc9567b837b20a78264158b
@@ -0,0 +1,36 @@
1
+ name: Test Exporter
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+ schedule:
7
+ - cron: '0 0 * * 0' # weekly
8
+
9
+ jobs:
10
+ build:
11
+ runs-on: ubuntu-latest
12
+ name: Ruby ${{ matrix.ruby }}
13
+ strategy:
14
+ matrix:
15
+ ruby: ["2.7", "2.6", "2.5", "2.4"]
16
+ steps:
17
+ - uses: actions/checkout@master
18
+ with:
19
+ fetch-depth: 1
20
+ - uses: actions/setup-ruby@v1
21
+ with:
22
+ ruby-version: ${{ matrix.ruby }}
23
+ - uses: actions/cache@v2
24
+ with:
25
+ path: vendor/bundle
26
+ key: ${{ runner.os }}-${{ matrix.ruby }}-gems-${{ hashFiles('**/Gemfile.lock') }}
27
+ restore-keys: |
28
+ ${{ runner.os }}-${{ matrix.ruby }}-gems-
29
+ - name: Setup gems
30
+ run: |
31
+ bundle config path vendor/bundle
32
+ bundle install --jobs 4
33
+ - name: Rubocop
34
+ run: bundle exec rubocop
35
+ - name: Run tests
36
+ run: bundle exec rake
data/CHANGELOG CHANGED
@@ -1,3 +1,7 @@
1
+ 0.6.0 - 10-11-2020
2
+
3
+ - FEATURE: add support for basic-auth in the prometheus_exporter web server
4
+
1
5
  0.5.3 - 29-07-2020
2
6
 
3
7
  - FEATURE: added #remove to all metric types so users can remove specific labels if needed
data/README.md CHANGED
@@ -200,12 +200,27 @@ $ bundle exec prometheus_exporter
200
200
  | Summary | `http_sql_duration_seconds`² | Time spent in HTTP reqs in SQL in seconds |
201
201
  | Summary | `http_queue_duration_seconds`³ | Time spent queueing the request in load balancer in seconds |
202
202
 
203
- All metrics have a `controller` and an `action` label.
204
- `http_requests_total` additionally has a (HTTP response) `status` label.
203
+ All metrics have a `controller` and an `action` label.
204
+ `http_requests_total` additionally has a (HTTP response) `status` label.
205
205
 
206
- ¹) Only available when Redis is used.
207
- ²) Only available when Mysql or PostgreSQL are used.
208
- ³) Only available when [Instrumenting Request Queueing Time](#instrumenting-request-queueing-time) is set up.
206
+ To add your own labels to the default metrics, create a subclass of `PrometheusExporter::Middleware`, override `custom_labels`, and use it in your initializer.
207
+ ```ruby
208
+ class MyMiddleware < PrometheusExporter::Middleware
209
+ def custom_labels(env)
210
+ labels = {}
211
+
212
+ if env['HTTP_X_PLATFORM']
213
+ labels['platform'] = env['HTTP_X_PLATFORM']
214
+ end
215
+
216
+ labels
217
+ end
218
+ end
219
+ ```
220
+
221
+ ¹) Only available when Redis is used.
222
+ ²) Only available when Mysql or PostgreSQL are used.
223
+ ³) Only available when [Instrumenting Request Queueing Time](#instrumenting-request-queueing-time) is set up.
209
224
 
210
225
  #### Activerecord Connection Pool Metrics
211
226
 
@@ -365,19 +380,19 @@ Sometimes the Sidekiq server shuts down before it can send metrics, that were ge
365
380
  **PrometheusExporter::Instrumentation::Sidekiq**
366
381
  | Type | Name | Description |
367
382
  | --- | --- | --- |
368
- | Counter | `sidekiq_job_duration_seconds` | Total time spent in sidekiq jobs |
383
+ | Summary | `sidekiq_job_duration_seconds` | Time spent in sidekiq jobs |
369
384
  | Counter | `sidekiq_jobs_total` | Total number of sidekiq jobs executed |
370
385
  | Counter | `sidekiq_restarted_jobs_total` | Total number of sidekiq jobs that we restarted because of a sidekiq shutdown |
371
386
  | Counter | `sidekiq_failed_jobs_total` | Total number of failed sidekiq jobs |
372
387
 
373
- All metrics have a `job_name` label.
388
+ All metrics have a `job_name` label and a `queue` label.
374
389
 
375
390
  **PrometheusExporter::Instrumentation::Sidekiq.death_handler**
376
391
  | Type | Name | Description |
377
392
  | --- | --- | --- |
378
393
  | Counter | `sidekiq_dead_jobs_total` | Total number of dead sidekiq jobs |
379
394
 
380
- This metric also has a `job_name` label.
395
+ This metric has a `job_name` label and a `queue` label.
381
396
 
382
397
  **PrometheusExporter::Instrumentation::SidekiqQueue**
383
398
  | Type | Name | Description |
@@ -387,7 +402,7 @@ This metric also has a `job_name` label.
387
402
 
388
403
  Both metrics will have a `queue` label with the name of the queue.
389
404
 
390
- _See [Metrics collected by Process Instrumentation](#metrics-collected-by-process-instrumentation) for a list of metrics the Process instrumentation will produce._
405
+ _See [Metrics collected by Process Instrumentation](#metrics-collected-by-process-instrumentation) for a list of metrics the Process instrumentation will produce._
391
406
 
392
407
  #### Shoryuken metrics
393
408
 
@@ -411,7 +426,7 @@ end
411
426
  | Counter | `shoryuken_restarted_jobs_total` | Total number of shoryuken jobs that we restarted because of a shoryuken shutdown |
412
427
  | Counter | `shoryuken_failed_jobs_total` | Total number of failed shoryuken jobs |
413
428
 
414
- All metrics have labels for `job_name` and `queue_name`.
429
+ All metrics have labels for `job_name` and `queue_name`.
415
430
 
416
431
  #### Delayed Job plugin
417
432
 
@@ -456,7 +471,7 @@ end
456
471
  | Counter | `hutch_jobs_total` | Total number of hutch jobs executed |
457
472
  | Counter | `hutch_failed_jobs_total` | Total number failed hutch jobs executed |
458
473
 
459
- All metrics have a `job_name` label.
474
+ All metrics have a `job_name` label.
460
475
 
461
476
  #### Instrumenting Request Queueing Time
462
477
 
@@ -494,7 +509,7 @@ end
494
509
  | Gauge | `puma_thread_pool_capacity_total` | Number of puma threads available at current scale |
495
510
  | Gauge | `puma_max_threads_total` | Number of puma threads at available at max scale |
496
511
 
497
- All metrics may have a `phase` label.
512
+ All metrics may have a `phase` label.
498
513
 
499
514
  ### Unicorn process metrics
500
515
 
@@ -577,8 +592,8 @@ Then you can collect the metrics you need on demand:
577
592
 
578
593
  ```ruby
579
594
  def metrics
580
- user_count_gague = PrometheusExporter::Metric::Gauge.new('user_count', 'number of users in the app')
581
- user_count_gague.observe User.count
595
+ user_count_gauge = PrometheusExporter::Metric::Gauge.new('user_count', 'number of users in the app')
596
+ user_count_gauge.observe User.count
582
597
  [user_count_gauge]
583
598
  end
584
599
  ```
@@ -692,6 +707,25 @@ ruby_web_requests{hostname="app-server-01"} 1
692
707
  When running the process for `prometheus_exporter` using `bin/prometheus_exporter`, there are several configurations that
693
708
  can be passed in:
694
709
 
710
+ ```
711
+ Usage: prometheus_exporter [options]
712
+ -p, --port INTEGER Port exporter should listen on (default: 9394)
713
+ -b, --bind STRING IP address exporter should listen on (default: localhost)
714
+ -t, --timeout INTEGER Timeout in seconds for metrics endpoint (default: 2)
715
+ --prefix METRIC_PREFIX Prefix to apply to all metrics (default: ruby_)
716
+ --label METRIC_LABEL Label to apply to all metrics (default: {})
717
+ -c, --collector FILE (optional) Custom collector to run
718
+ -a, --type-collector FILE (optional) Custom type collectors to run in main collector
719
+ -v, --verbose
720
+ --auth FILE (optional) enable basic authentication using a htpasswd FILE
721
+ --realm REALM (optional) Use REALM for basic authentication (default: "Prometheus Exporter")
722
+ --unicorn-listen-address ADDRESS
723
+ (optional) Address where unicorn listens on (unix or TCP address)
724
+ --unicorn-master PID_FILE (optional) PID file of unicorn master process to monitor unicorn
725
+ ```
726
+
727
+ #### Example
728
+
695
729
  The following will run the process at
696
730
  - Port `8080` (default `9394`)
697
731
  - Bind to `0.0.0.0` (default `localhost`)
@@ -707,6 +741,29 @@ prometheus_exporter -p 8080 \
707
741
  --prefix 'foo_'
708
742
  ```
709
743
 
744
+ #### Enabling Basic Authentication
745
+
746
+ If you desire authentication on your `/metrics` route, you can enable basic authentication with the `--auth` option.
747
+
748
+ ```
749
+ $ prometheus_exporter --auth my-htpasswd-file
750
+ ```
751
+
752
+ Additionally, the `--realm` option may be used to provide a customized realm for the challenge request.
753
+
754
+ Notes:
755
+
756
+ * You will need to create a `htpasswd` formatted file before hand which contains one or more user:password entries
757
+ * Only the basic `crypt` encryption is currently supported
758
+
759
+ A simple `htpasswd` file can be created with the Apache `htpasswd` utility; e.g:
760
+
761
+ ```
762
+ $ htpasswd -cdb my-htpasswd-file my-user my-unencrypted-password
763
+ ```
764
+
765
+ This will create a file named `my-htpasswd-file` which is suitable for use the `--auth` option.
766
+
710
767
  ### Client default labels
711
768
 
712
769
  You can specify a default label for instrumentation metrics sent by a specific client. For example:
@@ -47,6 +47,12 @@ def run
47
47
  opt.on('-v', '--verbose') do |o|
48
48
  options[:verbose] = true
49
49
  end
50
+ opt.on('--auth FILE', String, "(optional) enable basic authentication using a htpasswd FILE") do |o|
51
+ options[:auth] = o
52
+ end
53
+ opt.on('--realm REALM', String, "(optional) Use REALM for basic authentication (default: \"#{PrometheusExporter::DEFAULT_REALM}\")") do |o|
54
+ options[:realm] = o
55
+ end
50
56
 
51
57
  opt.on('--unicorn-listen-address ADDRESS', String, '(optional) Address where unicorn listens on (unix or TCP address)') do |o|
52
58
  options[:unicorn_listen_address] = o
@@ -57,6 +63,17 @@ def run
57
63
  end
58
64
  end.parse!
59
65
 
66
+ if options.has_key?(:realm) && !options.has_key?(:auth)
67
+ STDERR.puts "[Warn] Providing REALM without AUTH has no effect"
68
+ end
69
+
70
+ if options.has_key?(:auth)
71
+ unless File.exist?(options[:auth]) && File.readable?(options[:auth])
72
+ STDERR.puts "[Error] The AUTH file either doesn't exist or we don't have access to it"
73
+ exit 1
74
+ end
75
+ end
76
+
60
77
  if custom_collector_filename
61
78
  eval File.read(custom_collector_filename), nil, File.expand_path(custom_collector_filename)
62
79
  found = false
@@ -11,6 +11,7 @@ module PrometheusExporter
11
11
  DEFAULT_PREFIX = 'ruby_'
12
12
  DEFAULT_LABEL = {}
13
13
  DEFAULT_TIMEOUT = 2
14
+ DEFAULT_REALM = 'Prometheus Exporter'
14
15
 
15
16
  class OjCompat
16
17
  def self.parse(obj)
@@ -64,8 +64,10 @@ module PrometheusExporter
64
64
  @metrics = []
65
65
 
66
66
  @queue = Queue.new
67
+
67
68
  @socket = nil
68
69
  @socket_started = nil
70
+ @socket_pid = nil
69
71
 
70
72
  max_queue_size ||= MAX_QUEUE_SIZE
71
73
  max_queue_size = max_queue_size.to_i
@@ -107,7 +109,16 @@ module PrometheusExporter
107
109
  end
108
110
 
109
111
  def send_json(obj)
110
- payload = @custom_labels.nil? ? obj : obj.merge(custom_labels: @custom_labels)
112
+ payload =
113
+ if @custom_labels
114
+ if obj[:custom_labels]
115
+ obj.merge(custom_labels: @custom_labels.merge(obj[:custom_labels]))
116
+ else
117
+ obj.merge(custom_labels: @custom_labels)
118
+ end
119
+ else
120
+ obj
121
+ end
111
122
  send(@json_serializer.dump(payload))
112
123
  end
113
124
 
@@ -191,12 +202,20 @@ module PrometheusExporter
191
202
  end
192
203
 
193
204
  def close_socket_if_old!
194
- if @socket && ((@socket_started + MAX_SOCKET_AGE) < Time.now.to_f)
205
+ if @socket_pid == Process.pid && @socket && @socket_started && ((@socket_started + MAX_SOCKET_AGE) < Time.now.to_f)
195
206
  close_socket!
196
207
  end
197
208
  end
198
209
 
199
210
  def ensure_socket!
211
+ # if process was forked socket may be owned by parent
212
+ # leave it alone and reset
213
+ if @socket_pid != Process.pid
214
+ @socket = nil
215
+ @socket_started = nil
216
+ @socket_pid = nil
217
+ end
218
+
200
219
  close_socket_if_old!
201
220
  if !@socket
202
221
  @socket = TCPSocket.new @host, @port
@@ -207,12 +226,14 @@ module PrometheusExporter
207
226
  @socket.write("Content-Type: application/octet-stream\r\n")
208
227
  @socket.write("\r\n")
209
228
  @socket_started = Time.now.to_f
229
+ @socket_pid = Process.pid
210
230
  end
211
231
 
212
232
  nil
213
233
  rescue
214
234
  @socket = nil
215
235
  @socket_started = nil
236
+ @socket_pid = nil
216
237
  raise
217
238
  end
218
239
 
@@ -69,7 +69,7 @@ module PrometheusExporter::Instrumentation
69
69
 
70
70
  labels_from_config = pool.spec.config
71
71
  .select { |k, v| @config_labels.include? k }
72
- .map { |k, v| [k.to_s.prepend("dbconfig_"), v] }
72
+ .map { |k, v| [k.to_s.dup.prepend("dbconfig_"), v] }
73
73
 
74
74
  labels = @metric_labels.merge(pool_name: pool.spec.name).merge(Hash[labels_from_config])
75
75
 
@@ -1,6 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'yaml'
4
+
3
5
  module PrometheusExporter::Instrumentation
6
+ JOB_WRAPPER_CLASS_NAME = 'ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper'
7
+ DELAYED_CLASS_NAMES = [
8
+ 'Sidekiq::Extensions::DelayedClass',
9
+ 'Sidekiq::Extensions::DelayedModel',
10
+ 'Sidekiq::Extensions::DelayedMailer',
11
+ ]
12
+
4
13
  class Sidekiq
5
14
  def self.death_handler
6
15
  -> (job, ex) do
@@ -32,15 +41,47 @@ module PrometheusExporter::Instrumentation
32
41
  raise e
33
42
  ensure
34
43
  duration = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC) - start
35
- class_name = worker.class.to_s == 'ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper' ?
36
- msg['wrapped'] : worker.class.to_s
37
44
  @client.send_json(
38
45
  type: "sidekiq",
39
- name: class_name,
46
+ name: get_name(worker, msg),
47
+ queue: queue,
40
48
  success: success,
41
49
  shutdown: shutdown,
42
50
  duration: duration
43
51
  )
44
52
  end
53
+
54
+ private
55
+
56
+ def get_name(worker, msg)
57
+ class_name = worker.class.to_s
58
+ if class_name == JOB_WRAPPER_CLASS_NAME
59
+ get_job_wrapper_name(msg)
60
+ elsif DELAYED_CLASS_NAMES.include?(class_name)
61
+ get_delayed_name(msg, class_name)
62
+ else
63
+ class_name
64
+ end
65
+ end
66
+
67
+ def get_job_wrapper_name(msg)
68
+ msg['wrapped']
69
+ end
70
+
71
+ def get_delayed_name(msg, class_name)
72
+ # fallback to class_name since we're relying on the internal implementation
73
+ # of the delayed extensions
74
+ # https://github.com/mperham/sidekiq/blob/master/lib/sidekiq/extensions/class_methods.rb
75
+ begin
76
+ (target, method_name, _args) = YAML.load(msg['args'].first)
77
+ if target.class == Class
78
+ "#{target.name}##{method_name}"
79
+ else
80
+ "#{target.class.name}##{method_name}"
81
+ end
82
+ rescue
83
+ class_name
84
+ end
85
+ end
45
86
  end
46
87
  end
@@ -27,13 +27,24 @@ module PrometheusExporter::Instrumentation
27
27
  end
28
28
 
29
29
  def collect_queue_stats
30
+ hostname = Socket.gethostname
31
+ pid = ::Process.pid
32
+ ps = ::Sidekiq::ProcessSet.new
33
+
34
+ process = ps.find do |sp|
35
+ sp['hostname'] == hostname && sp['pid'] == pid
36
+ end
37
+
38
+ queues = process.nil? ? [] : process['queues']
39
+
30
40
  ::Sidekiq::Queue.all.map do |queue|
41
+ next unless queues.include? queue.name
31
42
  {
32
43
  backlog_total: queue.size,
33
44
  latency_seconds: queue.latency.to_i,
34
45
  labels: { queue: queue.name }
35
46
  }
36
- end
47
+ end.compact
37
48
  end
38
49
  end
39
50
  end
@@ -44,14 +44,25 @@ class PrometheusExporter::Middleware
44
44
  controller = params["controller"]
45
45
  end
46
46
 
47
- @client.send_json(
47
+ obj = {
48
48
  type: "web",
49
49
  timings: info,
50
50
  queue_time: queue_time,
51
51
  action: action,
52
52
  controller: controller,
53
53
  status: status
54
- )
54
+ }
55
+ labels = custom_labels(env)
56
+ if labels
57
+ obj = obj.merge(custom_labels: labels)
58
+ end
59
+
60
+ @client.send_json(obj)
61
+ end
62
+
63
+ # allows subclasses to add custom labels based on env
64
+ def custom_labels(env)
65
+ nil
55
66
  end
56
67
 
57
68
  private
@@ -15,6 +15,8 @@ module PrometheusExporter::Server
15
15
  @collector_class = nil
16
16
  @type_collectors = nil
17
17
  @prefix = nil
18
+ @auth = nil
19
+ @realm = nil
18
20
 
19
21
  options.each do |k, v|
20
22
  send("#{k}=", v) if self.class.method_defined?("#{k}=")
@@ -40,12 +42,20 @@ module PrometheusExporter::Server
40
42
  )
41
43
  end
42
44
 
43
- server = server_class.new port: port, bind: bind, collector: collector, timeout: timeout, verbose: verbose
45
+ server = server_class.new(port: port, bind: bind, collector: collector, timeout: timeout, verbose: verbose, auth: auth, realm: realm)
44
46
  server.start
45
47
  end
46
48
 
47
49
  attr_accessor :unicorn_listen_address, :unicorn_pid_file
48
- attr_writer :prefix, :port, :bind, :collector_class, :type_collectors, :timeout, :verbose, :server_class, :label
50
+ attr_writer :prefix, :port, :bind, :collector_class, :type_collectors, :timeout, :verbose, :server_class, :label, :auth, :realm
51
+
52
+ def auth
53
+ @auth || nil
54
+ end
55
+
56
+ def realm
57
+ @realm || PrometheusExporter::DEFAULT_REALM
58
+ end
49
59
 
50
60
  def prefix
51
61
  @prefix || PrometheusExporter::DEFAULT_PREFIX
@@ -17,7 +17,7 @@ module PrometheusExporter::Server
17
17
  end
18
18
 
19
19
  def collect(obj)
20
- default_labels = { job_name: obj['name'] }
20
+ default_labels = { job_name: obj['name'], queue: obj['queue'] }
21
21
  custom_labels = obj['custom_labels']
22
22
  labels = custom_labels.nil? ? default_labels : default_labels.merge(custom_labels)
23
23
 
@@ -52,7 +52,7 @@ module PrometheusExporter::Server
52
52
  if !@sidekiq_jobs_total
53
53
 
54
54
  @sidekiq_job_duration_seconds =
55
- PrometheusExporter::Metric::Counter.new(
55
+ PrometheusExporter::Metric::Summary.new(
56
56
  "sidekiq_job_duration_seconds", "Total time spent in sidekiq jobs.")
57
57
 
58
58
  @sidekiq_jobs_total =
@@ -9,9 +9,14 @@ module PrometheusExporter::Server
9
9
  class WebServer
10
10
  attr_reader :collector
11
11
 
12
- def initialize(port: , bind: nil, collector: nil, timeout: PrometheusExporter::DEFAULT_TIMEOUT, verbose: false)
13
-
14
- @verbose = verbose
12
+ def initialize(opts)
13
+ @port = opts[:port] || PrometheusExporter::DEFAULT_PORT
14
+ @bind = opts[:bind] || PrometheusExporter::DEFAULT_BIND_ADDRESS
15
+ @collector = opts[:collector] || Collector.new
16
+ @timeout = opts[:timeout] || PrometheusExporter::DEFAULT_TIMEOUT
17
+ @verbose = opts[:verbose] || false
18
+ @auth = opts[:auth]
19
+ @realm = opts[:realm] || PrometheusExporter::DEFAULT_REALM
15
20
 
16
21
  @metrics_total = PrometheusExporter::Metric::Counter.new("collector_metrics_total", "Total metrics processed by exporter web.")
17
22
 
@@ -23,33 +28,33 @@ module PrometheusExporter::Server
23
28
  @sessions_total.observe(0)
24
29
  @bad_metrics_total.observe(0)
25
30
 
26
- access_log, logger = nil
31
+ @access_log, @logger = nil
27
32
 
28
- if verbose
29
- access_log = [
33
+ if @verbose
34
+ @access_log = [
30
35
  [$stderr, WEBrick::AccessLog::COMMON_LOG_FORMAT],
31
36
  [$stderr, WEBrick::AccessLog::REFERER_LOG_FORMAT],
32
37
  ]
33
- logger = WEBrick::Log.new($stderr)
38
+ @logger = WEBrick::Log.new($stderr)
34
39
  else
35
- access_log = []
36
- logger = WEBrick::Log.new("/dev/null")
40
+ @access_log = []
41
+ @logger = WEBrick::Log.new("/dev/null")
37
42
  end
38
43
 
44
+ @logger.info "Using Basic Authentication via #{@auth}" if @verbose && @auth
45
+
39
46
  @server = WEBrick::HTTPServer.new(
40
- Port: port,
41
- BindAddress: bind,
42
- Logger: logger,
43
- AccessLog: access_log,
47
+ Port: @port,
48
+ BindAddress: @bind,
49
+ Logger: @logger,
50
+ AccessLog: @access_log,
44
51
  )
45
52
 
46
- @collector = collector || Collector.new
47
- @port = port
48
- @timeout = timeout
49
-
50
53
  @server.mount_proc '/' do |req, res|
51
54
  res['Content-Type'] = 'text/plain; charset=utf-8'
52
55
  if req.path == '/metrics'
56
+ authenticate(req, res) if @auth
57
+
53
58
  res.status = 200
54
59
  if req.header["accept-encoding"].to_s.include?("gzip")
55
60
  sio = StringIO.new
@@ -159,5 +164,12 @@ module PrometheusExporter::Server
159
164
  gauge
160
165
  end
161
166
 
167
+ def authenticate(req, res)
168
+ htpasswd = WEBrick::HTTPAuth::Htpasswd.new(@auth)
169
+ basic_auth = WEBrick::HTTPAuth::BasicAuth.new({ Realm: @realm, UserDB: htpasswd, Logger: @logger })
170
+
171
+ basic_auth.authenticate(req, res)
172
+ end
173
+
162
174
  end
163
175
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PrometheusExporter
4
- VERSION = '0.5.3'
4
+ VERSION = '0.6.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prometheus_exporter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-29 00:00:00.000000000 Z
11
+ date: 2020-11-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubocop
@@ -172,9 +172,9 @@ executables:
172
172
  extensions: []
173
173
  extra_rdoc_files: []
174
174
  files:
175
+ - ".github/workflows/ci.yml"
175
176
  - ".gitignore"
176
177
  - ".rubocop.yml"
177
- - ".travis.yml"
178
178
  - CHANGELOG
179
179
  - CODE_OF_CONDUCT.md
180
180
  - Gemfile
@@ -1,12 +0,0 @@
1
- sudo: required
2
- language: ruby
3
- dist: trusty
4
- rvm:
5
- - 2.3
6
- - 2.4
7
- - 2.5
8
- - 2.6
9
- before_install: gem install bundler -v 1.16.1
10
- before_script: sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6'
11
-
12
- script: bundle exec rubocop && bundle exec rake