bc-prometheus-ruby 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (28) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +30 -0
  3. data/CODE_OF_CONDUCT.md +49 -0
  4. data/README.md +67 -0
  5. data/bc-prometheus-ruby.gemspec +46 -0
  6. data/lib/bigcommerce/prometheus.rb +62 -0
  7. data/lib/bigcommerce/prometheus/client.rb +80 -0
  8. data/lib/bigcommerce/prometheus/collectors/resque.rb +85 -0
  9. data/lib/bigcommerce/prometheus/configuration.rb +127 -0
  10. data/lib/bigcommerce/prometheus/instrumentors/hutch.rb +72 -0
  11. data/lib/bigcommerce/prometheus/instrumentors/resque.rb +72 -0
  12. data/lib/bigcommerce/prometheus/instrumentors/web.rb +84 -0
  13. data/lib/bigcommerce/prometheus/integrations/puma.rb +55 -0
  14. data/lib/bigcommerce/prometheus/integrations/railtie.rb +31 -0
  15. data/lib/bigcommerce/prometheus/integrations/resque.rb +41 -0
  16. data/lib/bigcommerce/prometheus/loggable.rb +32 -0
  17. data/lib/bigcommerce/prometheus/server.rb +117 -0
  18. data/lib/bigcommerce/prometheus/servers/thin/controllers/base_controller.rb +63 -0
  19. data/lib/bigcommerce/prometheus/servers/thin/controllers/error_controller.rb +36 -0
  20. data/lib/bigcommerce/prometheus/servers/thin/controllers/metrics_controller.rb +87 -0
  21. data/lib/bigcommerce/prometheus/servers/thin/controllers/not_found_controller.rb +36 -0
  22. data/lib/bigcommerce/prometheus/servers/thin/controllers/send_metrics_controller.rb +92 -0
  23. data/lib/bigcommerce/prometheus/servers/thin/rack_app.rb +88 -0
  24. data/lib/bigcommerce/prometheus/servers/thin/server.rb +48 -0
  25. data/lib/bigcommerce/prometheus/servers/thin/server_metrics.rb +98 -0
  26. data/lib/bigcommerce/prometheus/type_collectors/resque.rb +82 -0
  27. data/lib/bigcommerce/prometheus/version.rb +22 -0
  28. metadata +209 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: bc4204f3e256d97a75520de62e6e9861561fc348d2d560f5bb79c2c25e098bb9
4
+ data.tar.gz: bc6ecb116fc1d36cd0199f8a0b7549d8c6c2077beb891bc6055f3c0143298bee
5
+ SHA512:
6
+ metadata.gz: 6bda9f2a9613145633bd5c7eb74f6426aad79842017c9be4b97b30303ab52a6dae61544e5774450f33bdbd98082671d2fa254e1b1d968c38463f9d6e90500da7
7
+ data.tar.gz: a9ee4863cca42c2a90ee9db303530f6f6eeaf47e893a7747db64183afd92e794894467409e247362e4ffdeee113a5277dc8bfb0ebe71a3f7d18e6fd5fff6833b
@@ -0,0 +1,30 @@
1
+ Changelog for the bc-prometheus-ruby gem.
2
+
3
+ h3. Pending Release
4
+
5
+ h3. 0.1.0
6
+
7
+ - Replace WEBrick server from PrometheusExporter with Thin server implementation to reduce memory leakage
8
+ - Utilize NET::HTTP instead of direct sockets to prevent bad socket errors
9
+
10
+ h3. 0.0.5
11
+
12
+ - Add resque instrumentation
13
+
14
+ h3. 0.0.4
15
+
16
+ - Properly handle SIGINT/SIGTERM to shutdown prometheus exporter
17
+ - Add process names to log output for easier debugging
18
+
19
+ h3. 0.0.3
20
+
21
+ - Add hutch instrumentor for hutch / rmq support
22
+
23
+ h3. 0.0.2
24
+
25
+ - Better support for older Rails / Puma versions
26
+ - Adds basic support for non-Rails applications
27
+
28
+ h3. 0.0.1
29
+
30
+ - Initial public release
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at splittingred@gmail.com. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
@@ -0,0 +1,67 @@
1
+ # bc-prometheus-ruby - Drop-in Prometheus metrics
2
+
3
+ [![CircleCI](https://circleci.com/gh/bigcommerce/bc-prometheus-ruby.svg?style=svg&circle-token=fc3e2c4405a1f53a31e298f0ef981c2d0dfdee90)](https://circleci.com/gh/bigcommerce/bc-prometheus-ruby)
4
+
5
+ ## Installation
6
+
7
+ ```ruby
8
+ gem 'bc-prometheus-ruby'
9
+ ```
10
+
11
+ Then in your `application.rb`, prior to extending `Rails::Application` or any initializers:
12
+
13
+ ```ruby
14
+ require 'bigcommerce/prometheus'
15
+ ```
16
+
17
+ You can then view your metrics at: http://0.0.0.0:9394/metrics
18
+
19
+ ## Puma
20
+
21
+ For extra Puma metrics, add this to `config/puma.rb`:
22
+
23
+ ```ruby
24
+ after_worker_fork do
25
+ Rails.application.config.after_fork_callbacks.each(&:call)
26
+ end
27
+ ```
28
+
29
+ ## Resque
30
+
31
+ In your `task 'resque:setup'` rake task, do:
32
+
33
+ ```ruby
34
+ require 'bigcommerce/prometheus'
35
+ Bigcommerce::Prometheus::Instrumentors::Resque.new(app: Rails.application).start
36
+ ```
37
+
38
+ ## Configuration
39
+
40
+ After requiring the main file, you can further configure with:
41
+
42
+ | Option | Description | Default |
43
+ | ------ | ----------- | ------- |
44
+ | client_custom_labels | A hash of custom labels to send with each client request | `{}` |
45
+ | client_max_queue_size | The max amount of metrics to send before flushing | 10000 |
46
+ | client_thread_sleep | How often to sleep the worker thread that manages the client buffer (seconds) | 0.5 |
47
+ | puma_collection_frequency | How often to poll puma collection metrics (seconds) | 30 |
48
+ | server_host | The host to run the exporter on | 0.0.0.0 |
49
+ | server_port | The port to run the exporter on | 9394 |
50
+ | process_name | What the current process name is. Used in logging. | `ENV['PROCESS']` |
51
+
52
+ ## License
53
+
54
+ Copyright (c) 2019-present, BigCommerce Pty. Ltd. All rights reserved
55
+
56
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
57
+ documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
58
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
59
+ persons to whom the Software is furnished to do so, subject to the following conditions:
60
+
61
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
62
+ Software.
63
+
64
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
65
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
66
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
67
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2019-present, BigCommerce Pty. Ltd. All rights reserved
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
6
+ # documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
7
+ # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
8
+ # persons to whom the Software is furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
11
+ # Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
14
+ # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
15
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16
+ # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
17
+ #
18
+ $:.push File.expand_path('../lib', __FILE__)
19
+ require 'bigcommerce/prometheus/version'
20
+
21
+ Gem::Specification.new do |spec|
22
+ spec.name = 'bc-prometheus-ruby'
23
+ spec.version = Bigcommerce::Prometheus::VERSION
24
+ spec.authors = ['Shaun McCormick']
25
+ spec.email = ['shaun.mccormick@bigcommerce.com']
26
+
27
+ spec.summary = 'Simple integration of ruby and puma servers with prometheus'
28
+ spec.description = spec.summary
29
+ spec.homepage = 'https://github.com/bigcommerce/bc-prometheus-ruby'
30
+ spec.license = 'MIT'
31
+
32
+ spec.files = Dir['README.md', 'CHANGELOG.md', 'CODE_OF_CONDUCT.md', 'lib/**/*', 'bc-prometheus-ruby.gemspec']
33
+ spec.require_paths = ['lib']
34
+
35
+ spec.add_development_dependency 'rake', '>= 10.0'
36
+ spec.add_development_dependency 'rspec', '>= 3.8'
37
+ spec.add_development_dependency 'rspec_junit_formatter', '>= 0.4'
38
+ spec.add_development_dependency 'bundler-audit', '>= 0.6'
39
+ spec.add_development_dependency 'null-logger', '>= 0.1'
40
+ spec.add_development_dependency 'pry', '>= 0.12'
41
+ spec.add_development_dependency 'rubocop', '>= 0.74'
42
+ spec.add_development_dependency 'simplecov', '>= 0.16'
43
+
44
+ spec.add_runtime_dependency 'prometheus_exporter', '~> 0.4'
45
+ spec.add_runtime_dependency 'thin', '~> 1.7'
46
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2019-present, BigCommerce Pty. Ltd. All rights reserved
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
6
+ # documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
7
+ # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
8
+ # persons to whom the Software is furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
11
+ # Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
14
+ # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
15
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16
+ # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
17
+ #
18
+ require 'net/http'
19
+ require 'prometheus_exporter'
20
+ require 'prometheus_exporter/server'
21
+ require 'prometheus_exporter/client'
22
+ require 'prometheus_exporter/middleware'
23
+ require 'prometheus_exporter/instrumentation'
24
+ require 'thin'
25
+
26
+ require_relative 'prometheus/version'
27
+ require_relative 'prometheus/loggable'
28
+ require_relative 'prometheus/configuration'
29
+ require_relative 'prometheus/server'
30
+ require_relative 'prometheus/client'
31
+
32
+ require_relative 'prometheus/collectors/resque'
33
+ require_relative 'prometheus/type_collectors/resque'
34
+
35
+ require_relative 'prometheus/instrumentors/web'
36
+ require_relative 'prometheus/instrumentors/hutch'
37
+ require_relative 'prometheus/instrumentors/resque'
38
+ require_relative 'prometheus/integrations/railtie' if defined?(Rails)
39
+ require_relative 'prometheus/integrations/puma'
40
+ require_relative 'prometheus/integrations/resque'
41
+
42
+ require_relative 'prometheus/servers/thin/server'
43
+ require_relative 'prometheus/servers/thin/rack_app'
44
+ require_relative 'prometheus/servers/thin/server_metrics'
45
+ require_relative 'prometheus/servers/thin/controllers/base_controller'
46
+ require_relative 'prometheus/servers/thin/controllers/error_controller'
47
+ require_relative 'prometheus/servers/thin/controllers/metrics_controller'
48
+ require_relative 'prometheus/servers/thin/controllers/not_found_controller'
49
+ require_relative 'prometheus/servers/thin/controllers/send_metrics_controller'
50
+
51
+ module Bigcommerce
52
+ ##
53
+ # Base top-level prometheus module
54
+ #
55
+ module Prometheus
56
+ extend Configuration
57
+
58
+ def self.client
59
+ Client.instance
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2019-present, BigCommerce Pty. Ltd. All rights reserved
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
6
+ # documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
7
+ # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
8
+ # persons to whom the Software is furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
11
+ # Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
14
+ # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
15
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16
+ # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
17
+ #
18
+ module Bigcommerce
19
+ module Prometheus
20
+ ##
21
+ # Client implementation for Prometheus
22
+ #
23
+ class Client < ::PrometheusExporter::Client
24
+ include Singleton
25
+ include Loggable
26
+
27
+ def initialize
28
+ super(
29
+ host: Bigcommerce::Prometheus.server_host,
30
+ port: Bigcommerce::Prometheus.server_port,
31
+ max_queue_size: Bigcommerce::Prometheus.client_max_queue_size,
32
+ thread_sleep: Bigcommerce::Prometheus.client_thread_sleep,
33
+ custom_labels: Bigcommerce::Prometheus.client_custom_labels
34
+ )
35
+ PrometheusExporter::Client.default = self
36
+ @process_name = ::Bigcommerce::Prometheus.process_name
37
+ end
38
+
39
+ ##
40
+ # Patch the worker loop to make it more resilient
41
+ #
42
+ def worker_loop
43
+ close_socket_if_old!
44
+ process_queue
45
+ rescue StandardError => e
46
+ logger.warn "[bigcommerce-prometheus][#{@process_name}] Prometheus client failed to send message to #{@host}:#{@port} #{e} - #{e.backtrace[0..5].join("\n")}"
47
+ end
48
+
49
+ ##
50
+ # Patch the close socket command to handle when @socket_started is nil
51
+ #
52
+ def close_socket_if_old!
53
+ close_socket! if @socket && ((@socket_started.to_i + MAX_SOCKET_AGE) < Time.now.to_f)
54
+ end
55
+
56
+ ##
57
+ # @param [String] path
58
+ # @return [URI]
59
+ #
60
+ def uri_path(path)
61
+ URI("http://#{@host}:#{@port}#{path}")
62
+ end
63
+
64
+ ##
65
+ # Process the current queue and flush to the collector
66
+ #
67
+ def process_queue
68
+ while @queue.length.to_i.positive?
69
+ begin
70
+ message = @queue.pop
71
+ Net::HTTP.post(uri_path('/send-metrics'), message)
72
+ rescue StandardError => e
73
+ logger.warn "[bigcommerce-prometheus][#{@process_name}] Prometheus Exporter is dropping a message tp #{uri_path('/send-metrics')}: #{e}"
74
+ raise
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2019-present, BigCommerce Pty. Ltd. All rights reserved
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
6
+ # documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
7
+ # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
8
+ # persons to whom the Software is furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
11
+ # Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
14
+ # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
15
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16
+ # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
17
+ #
18
+ module Bigcommerce
19
+ module Prometheus
20
+ module Collectors
21
+ ##
22
+ # Collect metrics to push to the server type collector
23
+ #
24
+ class Resque
25
+ include Bigcommerce::Prometheus::Loggable
26
+
27
+ ##
28
+ # @param [Bigcommerce::Prometheus::Client] client
29
+ # @param [Integer] frequency
30
+ #
31
+ def initialize(client:, frequency: nil)
32
+ @client = client || Bigcommerce::Prometheus.client
33
+ @frequency = frequency || 15
34
+ end
35
+
36
+ ##
37
+ # Start the collector
38
+ #
39
+ def self.start(client: nil, frequency: nil)
40
+ collector = new(client: client, frequency: frequency)
41
+ Thread.new do
42
+ loop do
43
+ collector.run
44
+ end
45
+ end
46
+ end
47
+
48
+ def run
49
+ metric = collect
50
+ logger.debug "[bigcommerce-prometheus] Pushing resque metrics to type collector: #{metric.inspect}"
51
+ @client.send_json metric
52
+ rescue StandardError => e
53
+ logger.error "[bigcommerce-prometheus] Failed to collect resque prometheus stats: #{e.message}"
54
+ ensure
55
+ sleep @frequency
56
+ end
57
+
58
+ private
59
+
60
+ def collect
61
+ info = ::Resque.info
62
+
63
+ metric = {}
64
+ metric[:type] = 'resque'
65
+ metric[:environment] = info[:environment].to_s
66
+ metric[:workers_total] = info[:workers].to_i
67
+ metric[:jobs_failed_total] = info[:failed].to_i
68
+ metric[:jobs_pending_total] = info[:pending].to_i
69
+ metric[:jobs_processed_total] = info[:processed].to_i
70
+ metric[:queues_total] = info[:queues].to_i
71
+ metric[:queues] = queue_sizes
72
+ metric
73
+ end
74
+
75
+ def queue_sizes
76
+ queues = {}
77
+ ::Resque.queues.each do |queue|
78
+ queues[queue.to_sym] = ::Resque.size(queue)
79
+ end
80
+ queues
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2019-present, BigCommerce Pty. Ltd. All rights reserved
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
6
+ # documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
7
+ # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
8
+ # persons to whom the Software is furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
11
+ # Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
14
+ # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
15
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16
+ # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
17
+ #
18
+ module Bigcommerce
19
+ module Prometheus
20
+ ##
21
+ # General configuration for prometheus integration
22
+ #
23
+ module Configuration
24
+ VALID_CONFIG_KEYS = {
25
+ logger: nil,
26
+ client_custom_labels: nil,
27
+ client_max_queue_size: 10_000,
28
+ client_thread_sleep: 0.5,
29
+ enabled: true,
30
+ puma_collection_frequency: 30,
31
+ puma_process_label: 'web',
32
+ resque_collection_frequency: 30,
33
+ resque_process_label: 'resque',
34
+ server_host: '0.0.0.0',
35
+ server_port: PrometheusExporter::DEFAULT_PORT,
36
+ server_timeout: PrometheusExporter::DEFAULT_TIMEOUT,
37
+ server_prefix: PrometheusExporter::DEFAULT_PREFIX
38
+ }.freeze
39
+
40
+ attr_accessor *VALID_CONFIG_KEYS.keys
41
+
42
+ ##
43
+ # Whenever this is extended into a class, setup the defaults
44
+ #
45
+ def self.extended(base)
46
+ if defined?(Rails)
47
+ Bigcommerce::Prometheus::Integrations::Railtie.config.before_initialize { base.reset }
48
+ else
49
+ base.reset
50
+ end
51
+ end
52
+
53
+ ##
54
+ # Yield self for ruby-style initialization
55
+ #
56
+ # @yields [Bigcommerce::Prometheus::Configuration]
57
+ # @return [Bigcommerce::Prometheus::Configuration]
58
+ #
59
+ def configure
60
+ reset unless @configured
61
+ yield self
62
+ @configured = true
63
+ end
64
+
65
+ ##
66
+ # Return the current configuration options as a Hash
67
+ #
68
+ # @return [Hash]
69
+ #
70
+ def options
71
+ opts = {}
72
+ VALID_CONFIG_KEYS.each_key do |k|
73
+ opts.merge!(k => send(k))
74
+ end
75
+ opts
76
+ end
77
+
78
+ ##
79
+ # Set the default configuration onto the extended class
80
+ #
81
+ def reset
82
+ VALID_CONFIG_KEYS.each do |k, v|
83
+ send("#{k}=".to_sym, v)
84
+ end
85
+ determine_logger
86
+ self.enabled = ENV.fetch('PROMETHEUS_ENABLED', 1).to_i.positive?
87
+ self.server_host = ENV.fetch('PROMETHEUS_SERVER_HOST', '0.0.0.0').to_s
88
+ self.server_port = ENV.fetch('PROMETHEUS_SERVER_PORT', PrometheusExporter::DEFAULT_PORT).to_i
89
+
90
+ self.puma_process_label = ENV.fetch('PROMETHEUS_PUMA_PROCESS_LABEL', 'web').to_s
91
+ self.puma_collection_frequency = ENV.fetch('PROMETHEUS_PUMA_COLLECTION_FREQUENCY', 30).to_i
92
+ end
93
+
94
+ ##
95
+ # @return [String]
96
+ def process_name
97
+ @process_name ||= ENV.fetch('PROCESS', 'unknown')
98
+ end
99
+
100
+ private
101
+
102
+ def determine_logger
103
+ if defined?(Rails) && Rails.logger
104
+ self.logger = Rails.logger
105
+ elsif defined?(Application) && Application.respond_to?(:logger)
106
+ self.logger = Application.logger
107
+ else
108
+ require 'logger'
109
+ self.logger = ::Logger.new(STDOUT)
110
+ end
111
+ end
112
+
113
+ ##
114
+ # Automatically determine environment
115
+ #
116
+ # @return [String] The current Ruby environment
117
+ #
118
+ def environment
119
+ if defined?(Rails)
120
+ Rails.env.to_s
121
+ else
122
+ (ENV['RACK_ENV'] || ENV['RAILS_ENV'] || 'development').to_s
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end