prometheus_exporter 0.8.0 → 0.8.1
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 +4 -4
- data/.github/workflows/ci.yml +1 -1
- data/CHANGELOG +5 -1
- data/README.md +14 -0
- data/bin/prometheus_exporter +14 -4
- data/lib/prometheus_exporter/client.rb +13 -6
- data/lib/prometheus_exporter/instrumentation/active_record.rb +5 -5
- data/lib/prometheus_exporter/instrumentation/process.rb +1 -1
- data/lib/prometheus_exporter/instrumentation/puma.rb +1 -1
- data/lib/prometheus_exporter/instrumentation/resque.rb +1 -1
- data/lib/prometheus_exporter/instrumentation/sidekiq_queue.rb +1 -1
- data/lib/prometheus_exporter/instrumentation/unicorn.rb +1 -1
- data/lib/prometheus_exporter/server/runner.rb +1 -1
- data/lib/prometheus_exporter/server/web_server.rb +6 -8
- data/lib/prometheus_exporter/version.rb +1 -1
- metadata +2 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 47861f365c3db51e840d0c62e30120518dfc64fe208cc639ae6653903d14c578
         | 
| 4 | 
            +
              data.tar.gz: 8e67b542b68012b0bd2cb64122eb2ba987a18eed1397449cab4363eea009ba44
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 1f4ff589012b8f28f81ee3b63f7535c1eb138c232826da36f1b621dc6381398e7fa515aca6b6413423e965630d23b47ad9b505801d418e3c9a625c7d7a0c7030
         | 
| 7 | 
            +
              data.tar.gz: d457d6d2c60c11960b6b241d5f2e0864994f11f808624845b9f28a42968dc3b9da07214321631d9f1644b2fdcad4b5ad443c843c53416ad6326afae68bd4d879
         | 
    
        data/.github/workflows/ci.yml
    CHANGED
    
    
    
        data/CHANGELOG
    CHANGED
    
    | @@ -1,10 +1,14 @@ | |
| 1 | 
            +
            0.8.1 - 04-08-2021
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            - FEATURE: swap from hardcoded STDERR to logger pattern (see README for details)
         | 
| 4 | 
            +
             | 
| 1 5 | 
             
            0.8.0 - 05-07-2021
         | 
| 2 6 |  | 
| 3 7 | 
             
            - FIX: handle ThreadError more gracefully in cases where process shuts down
         | 
| 4 8 | 
             
            - FEATURE: add job_name and queue_name labels to delayed job metrics
         | 
| 5 9 | 
             
            - FEATURE: always scope puma metrics on hostname in collector
         | 
| 6 10 | 
             
            - FEATURE: add customizable labels option to puma collector
         | 
| 7 | 
            -
            - FEATURE: support for  | 
| 11 | 
            +
            - FEATURE: support for Resque
         | 
| 8 12 | 
             
            - DEV: Remove support for EOL ruby 2.5
         | 
| 9 13 | 
             
            - FIX: Add source location to MethodProfiler patches
         | 
| 10 14 | 
             
            - FEATURE: Improve Active Record instrumentation
         | 
    
        data/README.md
    CHANGED
    
    | @@ -28,6 +28,7 @@ To learn more see [Instrumenting Rails with Prometheus](https://samsaffron.com/a | |
| 28 28 | 
             
              * [Client default host](#client-default-host)
         | 
| 29 29 | 
             
            * [Transport concerns](#transport-concerns)
         | 
| 30 30 | 
             
            * [JSON generation and parsing](#json-generation-and-parsing)
         | 
| 31 | 
            +
            * [Logging](#logging)
         | 
| 31 32 | 
             
            * [Contributing](#contributing)
         | 
| 32 33 | 
             
            * [License](#license)
         | 
| 33 34 | 
             
            * [Code of Conduct](#code-of-conduct)
         | 
| @@ -850,6 +851,19 @@ The `PrometheusExporter::Client` class has the method `#send-json`. This method, | |
| 850 851 |  | 
| 851 852 | 
             
            When `PrometheusExporter::Server::Collector` parses your JSON, by default it will use the faster Oj deserializer if available. This happens cause it only expects a simple Hash out of the box. You can opt in for the default JSON deserializer with `json_serializer: :json`.
         | 
| 852 853 |  | 
| 854 | 
            +
            ## Logging
         | 
| 855 | 
            +
             | 
| 856 | 
            +
            `PrometheusExporter::Client.default` will export to `STDERR`. To change this, you can pass your own logger:
         | 
| 857 | 
            +
            ```ruby
         | 
| 858 | 
            +
            PrometheusExporter::Client.new(logger: Rails.logger)
         | 
| 859 | 
            +
            PrometheusExporter::Client.new(logger: Logger.new(STDOUT))
         | 
| 860 | 
            +
            ```
         | 
| 861 | 
            +
             | 
| 862 | 
            +
            You can also pass a log level (default is [`Logger::WARN`](https://ruby-doc.org/stdlib-3.0.1/libdoc/logger/rdoc/Logger.html)):
         | 
| 863 | 
            +
            ```ruby
         | 
| 864 | 
            +
            PrometheusExporter::Client.new(log_level: Logger::DEBUG)
         | 
| 865 | 
            +
            ```
         | 
| 866 | 
            +
             | 
| 853 867 | 
             
            ## Contributing
         | 
| 854 868 |  | 
| 855 869 | 
             
            Bug reports and pull requests are welcome on GitHub at https://github.com/discourse/prometheus_exporter. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
         | 
    
        data/bin/prometheus_exporter
    CHANGED
    
    | @@ -3,12 +3,15 @@ | |
| 3 3 |  | 
| 4 4 | 
             
            require 'optparse'
         | 
| 5 5 | 
             
            require 'json'
         | 
| 6 | 
            +
            require 'logger'
         | 
| 6 7 |  | 
| 7 8 | 
             
            require_relative "./../lib/prometheus_exporter"
         | 
| 8 9 | 
             
            require_relative "./../lib/prometheus_exporter/server"
         | 
| 9 10 |  | 
| 10 11 | 
             
            def run
         | 
| 11 | 
            -
              options = { | 
| 12 | 
            +
              options = {
         | 
| 13 | 
            +
                logger_path: STDERR
         | 
| 14 | 
            +
              }
         | 
| 12 15 | 
             
              custom_collector_filename = nil
         | 
| 13 16 | 
             
              custom_type_collectors_filenames = []
         | 
| 14 17 |  | 
| @@ -61,15 +64,22 @@ def run | |
| 61 64 | 
             
                opt.on('--unicorn-master PID_FILE', String, '(optional) PID file of unicorn master process to monitor unicorn') do |o|
         | 
| 62 65 | 
             
                  options[:unicorn_pid_file] = o
         | 
| 63 66 | 
             
                end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                opt.on('--logger-path PATH', String, '(optional) Path to file for logger output. Defaults to STDERR') do |o|
         | 
| 69 | 
            +
                  options[:logger_path] = o
         | 
| 70 | 
            +
                end
         | 
| 64 71 | 
             
              end.parse!
         | 
| 65 72 |  | 
| 73 | 
            +
              logger = Logger.new(options[:logger_path])
         | 
| 74 | 
            +
              logger.level = Logger::WARN
         | 
| 75 | 
            +
             | 
| 66 76 | 
             
              if options.has_key?(:realm) && !options.has_key?(:auth)
         | 
| 67 | 
            -
                 | 
| 77 | 
            +
                logger.warn "Providing REALM without AUTH has no effect"
         | 
| 68 78 | 
             
              end
         | 
| 69 79 |  | 
| 70 80 | 
             
              if options.has_key?(:auth)
         | 
| 71 81 | 
             
                unless File.exist?(options[:auth]) && File.readable?(options[:auth])
         | 
| 72 | 
            -
                   | 
| 82 | 
            +
                  logger.fatal "The AUTH file either doesn't exist or we don't have access to it"
         | 
| 73 83 | 
             
                  exit 1
         | 
| 74 84 | 
             
                end
         | 
| 75 85 | 
             
              end
         | 
| @@ -88,7 +98,7 @@ def run | |
| 88 98 | 
             
                end
         | 
| 89 99 |  | 
| 90 100 | 
             
                if !found
         | 
| 91 | 
            -
                   | 
| 101 | 
            +
                  logger.fatal "Can not find a class inheriting off PrometheusExporter::Server::CollectorBase"
         | 
| 92 102 | 
             
                  exit 1
         | 
| 93 103 | 
             
                end
         | 
| 94 104 | 
             
              end
         | 
| @@ -2,6 +2,7 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            require 'socket'
         | 
| 4 4 | 
             
            require 'thread'
         | 
| 5 | 
            +
            require 'logger'
         | 
| 5 6 |  | 
| 6 7 | 
             
            module PrometheusExporter
         | 
| 7 8 | 
             
              class Client
         | 
| @@ -53,14 +54,20 @@ module PrometheusExporter | |
| 53 54 | 
             
                MAX_SOCKET_AGE = 25
         | 
| 54 55 | 
             
                MAX_QUEUE_SIZE = 10_000
         | 
| 55 56 |  | 
| 57 | 
            +
                attr_reader :logger
         | 
| 58 | 
            +
             | 
| 56 59 | 
             
                def initialize(
         | 
| 57 60 | 
             
                  host: ENV.fetch('PROMETHEUS_EXPORTER_HOST', 'localhost'),
         | 
| 58 61 | 
             
                  port: ENV.fetch('PROMETHEUS_EXPORTER_PORT', PrometheusExporter::DEFAULT_PORT),
         | 
| 59 62 | 
             
                  max_queue_size: nil,
         | 
| 60 63 | 
             
                  thread_sleep: 0.5,
         | 
| 61 64 | 
             
                  json_serializer: nil,
         | 
| 62 | 
            -
                  custom_labels: nil
         | 
| 65 | 
            +
                  custom_labels: nil,
         | 
| 66 | 
            +
                  logger: Logger.new(STDERR),
         | 
| 67 | 
            +
                  log_level: Logger::WARN
         | 
| 63 68 | 
             
                )
         | 
| 69 | 
            +
                  @logger = logger
         | 
| 70 | 
            +
                  @logger.level = log_level
         | 
| 64 71 | 
             
                  @metrics = []
         | 
| 65 72 |  | 
| 66 73 | 
             
                  @queue = Queue.new
         | 
| @@ -72,7 +79,7 @@ module PrometheusExporter | |
| 72 79 | 
             
                  max_queue_size ||= MAX_QUEUE_SIZE
         | 
| 73 80 | 
             
                  max_queue_size = max_queue_size.to_i
         | 
| 74 81 |  | 
| 75 | 
            -
                  if max_queue_size | 
| 82 | 
            +
                  if max_queue_size <= 0
         | 
| 76 83 | 
             
                    raise ArgumentError, "max_queue_size must be larger than 0"
         | 
| 77 84 | 
             
                  end
         | 
| 78 85 |  | 
| @@ -125,7 +132,7 @@ module PrometheusExporter | |
| 125 132 | 
             
                def send(str)
         | 
| 126 133 | 
             
                  @queue << str
         | 
| 127 134 | 
             
                  if @queue.length > @max_queue_size
         | 
| 128 | 
            -
                     | 
| 135 | 
            +
                    logger.warn "Prometheus Exporter client is dropping message cause queue is full"
         | 
| 129 136 | 
             
                    @queue.pop
         | 
| 130 137 | 
             
                  end
         | 
| 131 138 |  | 
| @@ -143,7 +150,7 @@ module PrometheusExporter | |
| 143 150 | 
             
                      @socket.write(message)
         | 
| 144 151 | 
             
                      @socket.write("\r\n")
         | 
| 145 152 | 
             
                    rescue => e
         | 
| 146 | 
            -
                       | 
| 153 | 
            +
                      logger.warn "Prometheus Exporter is dropping a message: #{e}"
         | 
| 147 154 | 
             
                      @socket = nil
         | 
| 148 155 | 
             
                      raise
         | 
| 149 156 | 
             
                    end
         | 
| @@ -168,7 +175,7 @@ module PrometheusExporter | |
| 168 175 | 
             
                  close_socket_if_old!
         | 
| 169 176 | 
             
                  process_queue
         | 
| 170 177 | 
             
                rescue => e
         | 
| 171 | 
            -
                   | 
| 178 | 
            +
                  logger.error "Prometheus Exporter, failed to send message #{e}"
         | 
| 172 179 | 
             
                end
         | 
| 173 180 |  | 
| 174 181 | 
             
                def ensure_worker_thread!
         | 
| @@ -186,7 +193,7 @@ module PrometheusExporter | |
| 186 193 | 
             
                  end
         | 
| 187 194 | 
             
                rescue ThreadError => e
         | 
| 188 195 | 
             
                  raise unless e.message =~ /can't alloc thread/
         | 
| 189 | 
            -
                   | 
| 196 | 
            +
                  logger.error "Prometheus Exporter, failed to send message ThreadError #{e}"
         | 
| 190 197 | 
             
                end
         | 
| 191 198 |  | 
| 192 199 | 
             
                def close_socket!
         | 
| @@ -7,9 +7,11 @@ module PrometheusExporter::Instrumentation | |
| 7 7 |  | 
| 8 8 | 
             
                def self.start(client: nil, frequency: 30, custom_labels: {}, config_labels: [])
         | 
| 9 9 |  | 
| 10 | 
            -
                   | 
| 10 | 
            +
                  client ||= PrometheusExporter::Client.default
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  # Not all rails versions support connection pool stats
         | 
| 11 13 | 
             
                  unless ::ActiveRecord::Base.connection_pool.respond_to?(:stat)
         | 
| 12 | 
            -
                     | 
| 14 | 
            +
                    client.logger.error("ActiveRecord connection pool stats not supported in your rails version")
         | 
| 13 15 | 
             
                    return
         | 
| 14 16 | 
             
                  end
         | 
| 15 17 |  | 
| @@ -18,8 +20,6 @@ module PrometheusExporter::Instrumentation | |
| 18 20 |  | 
| 19 21 | 
             
                  active_record_collector = new(custom_labels, config_labels)
         | 
| 20 22 |  | 
| 21 | 
            -
                  client ||= PrometheusExporter::Client.default
         | 
| 22 | 
            -
             | 
| 23 23 | 
             
                  stop if @thread
         | 
| 24 24 |  | 
| 25 25 | 
             
                  @thread = Thread.new do
         | 
| @@ -28,7 +28,7 @@ module PrometheusExporter::Instrumentation | |
| 28 28 | 
             
                        metrics = active_record_collector.collect
         | 
| 29 29 | 
             
                        metrics.each { |metric| client.send_json metric }
         | 
| 30 30 | 
             
                      rescue => e
         | 
| 31 | 
            -
                         | 
| 31 | 
            +
                        client.logger.error("Prometheus Exporter Failed To Collect Process Stats #{e}")
         | 
| 32 32 | 
             
                      ensure
         | 
| 33 33 | 
             
                        sleep frequency
         | 
| 34 34 | 
             
                      end
         | 
| @@ -27,7 +27,7 @@ module PrometheusExporter::Instrumentation | |
| 27 27 | 
             
                        metric = process_collector.collect
         | 
| 28 28 | 
             
                        client.send_json metric
         | 
| 29 29 | 
             
                      rescue => e
         | 
| 30 | 
            -
                         | 
| 30 | 
            +
                        client.logger.error("Prometheus Exporter Failed To Collect Process Stats #{e}")
         | 
| 31 31 | 
             
                      ensure
         | 
| 32 32 | 
             
                        sleep frequency
         | 
| 33 33 | 
             
                      end
         | 
| @@ -14,7 +14,7 @@ module PrometheusExporter::Instrumentation | |
| 14 14 | 
             
                        metric = puma_collector.collect
         | 
| 15 15 | 
             
                        client.send_json metric
         | 
| 16 16 | 
             
                      rescue => e
         | 
| 17 | 
            -
                         | 
| 17 | 
            +
                        client.logger.error("Prometheus Exporter Failed To Collect Puma Stats #{e}")
         | 
| 18 18 | 
             
                      ensure
         | 
| 19 19 | 
             
                        sleep frequency
         | 
| 20 20 | 
             
                      end
         | 
| @@ -11,7 +11,7 @@ module PrometheusExporter::Instrumentation | |
| 11 11 | 
             
                      begin
         | 
| 12 12 | 
             
                        client.send_json(resque_collector.collect)
         | 
| 13 13 | 
             
                      rescue => e
         | 
| 14 | 
            -
                         | 
| 14 | 
            +
                        client.logger.error("Prometheus Exporter Failed To Collect Resque Stats #{e}")
         | 
| 15 15 | 
             
                      ensure
         | 
| 16 16 | 
             
                        sleep frequency
         | 
| 17 17 | 
             
                      end
         | 
| @@ -11,7 +11,7 @@ module PrometheusExporter::Instrumentation | |
| 11 11 | 
             
                      begin
         | 
| 12 12 | 
             
                        client.send_json(sidekiq_queue_collector.collect)
         | 
| 13 13 | 
             
                      rescue StandardError => e
         | 
| 14 | 
            -
                         | 
| 14 | 
            +
                        client.logger.error("Prometheus Exporter Failed To Collect Sidekiq Queue metrics #{e}")
         | 
| 15 15 | 
             
                      ensure
         | 
| 16 16 | 
             
                        sleep frequency
         | 
| 17 17 | 
             
                      end
         | 
| @@ -18,7 +18,7 @@ module PrometheusExporter::Instrumentation | |
| 18 18 | 
             
                        metric = unicorn_collector.collect
         | 
| 19 19 | 
             
                        client.send_json metric
         | 
| 20 20 | 
             
                      rescue StandardError => e
         | 
| 21 | 
            -
                         | 
| 21 | 
            +
                        client.logger.error("Prometheus Exporter Failed To Collect Unicorn Stats #{e}")
         | 
| 22 22 | 
             
                      ensure
         | 
| 23 23 | 
             
                        sleep frequency
         | 
| 24 24 | 
             
                      end
         | 
| @@ -29,16 +29,17 @@ module PrometheusExporter::Server | |
| 29 29 | 
             
                  @bad_metrics_total.observe(0)
         | 
| 30 30 |  | 
| 31 31 | 
             
                  @access_log, @logger = nil
         | 
| 32 | 
            +
                  log_target = opts[:log_target]
         | 
| 32 33 |  | 
| 33 34 | 
             
                  if @verbose
         | 
| 34 35 | 
             
                    @access_log = [
         | 
| 35 36 | 
             
                      [$stderr, WEBrick::AccessLog::COMMON_LOG_FORMAT],
         | 
| 36 37 | 
             
                      [$stderr, WEBrick::AccessLog::REFERER_LOG_FORMAT],
         | 
| 37 38 | 
             
                    ]
         | 
| 38 | 
            -
                    @logger = WEBrick::Log.new($stderr)
         | 
| 39 | 
            +
                    @logger = WEBrick::Log.new(log_target || $stderr)
         | 
| 39 40 | 
             
                  else
         | 
| 40 41 | 
             
                    @access_log = []
         | 
| 41 | 
            -
                    @logger = WEBrick::Log.new("/dev/null")
         | 
| 42 | 
            +
                    @logger = WEBrick::Log.new(log_target || "/dev/null")
         | 
| 42 43 | 
             
                  end
         | 
| 43 44 |  | 
| 44 45 | 
             
                  @logger.info "Using Basic Authentication via #{@auth}" if @verbose && @auth
         | 
| @@ -87,10 +88,7 @@ module PrometheusExporter::Server | |
| 87 88 | 
             
                      @collector.process(block)
         | 
| 88 89 | 
             
                    rescue => e
         | 
| 89 90 | 
             
                      if @verbose
         | 
| 90 | 
            -
                         | 
| 91 | 
            -
                        STDERR.puts e.inspect
         | 
| 92 | 
            -
                        STDERR.puts e.backtrace
         | 
| 93 | 
            -
                        STDERR.puts
         | 
| 91 | 
            +
                        logger.error "\n\n#{e.inspect}\n#{e.backtrace}\n\n"
         | 
| 94 92 | 
             
                      end
         | 
| 95 93 | 
             
                      @bad_metrics_total.observe
         | 
| 96 94 | 
             
                      res.body = "Bad Metrics #{e}"
         | 
| @@ -108,7 +106,7 @@ module PrometheusExporter::Server | |
| 108 106 | 
             
                    begin
         | 
| 109 107 | 
             
                      @server.start
         | 
| 110 108 | 
             
                    rescue => e
         | 
| 111 | 
            -
                       | 
| 109 | 
            +
                      logger.error "Failed to start prometheus collector web on port #{@port}: #{e}"
         | 
| 112 110 | 
             
                    end
         | 
| 113 111 | 
             
                  end
         | 
| 114 112 | 
             
                end
         | 
| @@ -125,7 +123,7 @@ module PrometheusExporter::Server | |
| 125 123 | 
             
                    end
         | 
| 126 124 | 
             
                  rescue Timeout::Error
         | 
| 127 125 | 
             
                    # we timed out ... bummer
         | 
| 128 | 
            -
                     | 
| 126 | 
            +
                    logger.error "Generating Prometheus metrics text timed out"
         | 
| 129 127 | 
             
                  end
         | 
| 130 128 |  | 
| 131 129 | 
             
                  metrics = []
         | 
    
        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.8. | 
| 4 | 
            +
              version: 0.8.1
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Sam Saffron
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2021- | 
| 11 | 
            +
            date: 2021-08-04 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: webrick
         |