prometheus_exporter 0.1.6 → 0.1.7

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: f983fdbff857366a4b30252ff817544e08993b15181812b597ebb281ded2fb30
4
- data.tar.gz: 4d9c9bae239d2bfefa6633646806095edd69b81af6d2c59f18cbe36c91313525
3
+ metadata.gz: 6957162d157420b2b8fb6d2a4b9e08483ce846497fe6bb21f1695b0e70460dc8
4
+ data.tar.gz: 9a74c21c97efad9ef3720df426d14a5e1d879eb34bebcafc625de8d45f3b232b
5
5
  SHA512:
6
- metadata.gz: 0d614ff763d234e0a738e9388b8d38f6e96832a0757c2ee02b0ddb7f67f4875904d624dc49b0257126a2fe255f47738c98299571ccfb694317af3c8ee63ad479
7
- data.tar.gz: c810eefd3a240548cd4d4cde7374541cb940388907d1cac422f57feea224997114904a09f7037e921652012038f65f5ec929bb69a239d67feb10c54145f55df8
6
+ metadata.gz: 695472a08f8f9ede18d6f0fdaa8722d2e4efb01b20bf23269d26afae580cb559da4f409bb3499da7a80dcd5d47e6156a6e8c7e54f01c770485212e21369fb61d
7
+ data.tar.gz: af55f7e9d025a925f0add89a61628d236691df0a613d82d8c4e622fc9b83b7651187d9e78121113de872632459e95015772ed9af43a12b85ce4a1f820be9b7fc
data/README.md CHANGED
@@ -61,20 +61,20 @@ In some cases, for example unicorn or puma clusters you may want to aggregate me
61
61
 
62
62
  Simplest way to acheive this is use the built-in collector.
63
63
 
64
- First, run an exporter on your desired port:
64
+ First, run an exporter on your desired port, we use the default port of 9394:
65
65
 
66
66
  ```
67
- # prometheus_exporter 12345
67
+ # prometheus_exporter
68
68
  ```
69
69
 
70
- At this point an exporter is running on port 12345
70
+ At this point an exporter is running on port 9394
71
71
 
72
72
  In your application:
73
73
 
74
74
  ```ruby
75
75
  require 'prometheus_exporter/client'
76
76
 
77
- client = PrometheusExporter::Client.new(host: 'localhost', port: 12345)
77
+ client = PrometheusExporter::Client.default
78
78
  gauge = client.register(:gauge, "awesome", "amount of awesome")
79
79
 
80
80
  gauge.observe(10)
@@ -85,7 +85,7 @@ gauge.observe(99, day: "friday")
85
85
  Then you will get the metrics:
86
86
 
87
87
  ```bash
88
- % curl localhost:12345/metrics
88
+ % curl localhost:9394/metrics
89
89
  # HELP collector_working Is the master process collector able to collect metrics
90
90
  # TYPE collector_working gauge
91
91
  collector_working 1
@@ -97,6 +97,50 @@ awesome 10
97
97
 
98
98
  ```
99
99
 
100
+ ### Easy integration into Rails
101
+
102
+ You can easily integrate into any Rack application:
103
+
104
+ In your Gemfile:
105
+
106
+ ```
107
+ gem 'prometheus_exporter'
108
+ ```
109
+
110
+
111
+ ```
112
+ # in an initializer
113
+
114
+ unless Rails.env == "test"
115
+ require 'prometheus_exporter/middleware'
116
+ # insert in position 1
117
+ # instrument means method profiler will be injected in Redis and PG
118
+ Rails.application.middleware.unshift PrometheusExporter::Middleware
119
+ end
120
+ ```
121
+
122
+ You may also be interested in per-process stats, this collects memory and GC stats
123
+
124
+ ```
125
+ # in an initializer
126
+ unless Rails.env == "test"
127
+ require 'prometheus_exporter/instrumentation'
128
+ PrometheusExporter::Instrumentation::Process.start(type: "master")
129
+ end
130
+
131
+ after_fork do
132
+ require 'prometheus_exporter/instrumentation'
133
+ PrometheusExporter::Instrumentation::Process.start(type:"web")
134
+ end
135
+
136
+ ```
137
+
138
+ Ensure you run the exporter via
139
+
140
+ ```
141
+ % bundle exec prometheus_exporter
142
+ ```
143
+
100
144
  ### Multi process mode with custom collector
101
145
 
102
146
  You can opt for custom collector logic in a multi process environment.
@@ -108,7 +152,7 @@ The standard collector ships "help", "type" and "name" for every metric, in some
108
152
  First, define a custom collector, it is critical you inherit off `PrometheusExporter::Server::Collector`, also it is critical you have custom implementations for #process and #prometheus_metrics_text
109
153
 
110
154
  ```ruby
111
- class MyCustomCollector < PrometheusExporter::Server::Collector
155
+ class MyCustomCollector < PrometheusExporter::Server::CollectorBase
112
156
  def initialize
113
157
  @gauge1 = PrometheusExporter::Metric::Gauge.new("thing1", "I am thing 1")
114
158
  @gauge2 = PrometheusExporter::Metric::Gauge.new("thing2", "I am thing 2")
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+
5
+ require_relative "./../lib/prometheus_exporter"
6
+ require_relative "./../lib/prometheus_exporter/server"
7
+
8
+ def run
9
+ port = PrometheusExporter::DEFAULT_PORT
10
+ prefix = "ruby_"
11
+ collector = nil
12
+ verbose = false
13
+
14
+ OptionParser.new do |opt|
15
+ opt.on('-p',
16
+ '--port INTEGER',
17
+ Integer,
18
+ "Port exporter should listen on (default: #{port})") do |o|
19
+ port = o.to_i
20
+ end
21
+ opt.on('--prefix METRIC_PREFIX', String, "Prefix to apply to all metrics (default: #{prefix})") do |o|
22
+ prefix = o.to_s
23
+ end
24
+ opt.on('-c', '--collector CUSTOM_COLLECTOR', String, "(optional) Custom collector to run") do |o|
25
+ collector = o.to_s
26
+ end
27
+ opt.on('-v', '--verbose') do |o|
28
+ verbose = true
29
+ end
30
+
31
+ end.parse!
32
+
33
+ PrometheusExporter::Metric::Base.default_prefix = prefix
34
+
35
+ if collector
36
+ eval File.read(collector)
37
+
38
+ ObjectSpace.each_object(Class) do |klass|
39
+ if klass < PrometheusExporter::Server::CollectorBase
40
+ collector = klass
41
+ end
42
+ end
43
+
44
+ if !collector
45
+ STDERR.puts "Can not find a class inheriting off PrometheusExporter::Server::Collector"
46
+ usage
47
+ exit 1
48
+ end
49
+ end
50
+
51
+ puts "#{Time.now} Starting prometheus exporter on port #{port}"
52
+ server = PrometheusExporter::Server::WebServer.new port: port, collector: collector&.new, verbose: verbose
53
+ server.start
54
+ sleep
55
+
56
+ end
57
+
58
+ run
@@ -3,4 +3,6 @@ require "json"
3
3
  require "thread"
4
4
 
5
5
  module PrometheusExporter
6
+ # per: https://github.com/prometheus/prometheus/wiki/Default-port-allocations
7
+ DEFAULT_PORT = 9394
6
8
  end
@@ -24,10 +24,18 @@ class PrometheusExporter::Client
24
24
  end
25
25
  end
26
26
 
27
+ def self.default
28
+ @default ||= new
29
+ end
30
+
31
+ def self.default=(client)
32
+ @default = client
33
+ end
34
+
27
35
  MAX_SOCKET_AGE = 25
28
36
  MAX_QUEUE_SIZE = 10_000
29
37
 
30
- def initialize(host: 'localhost', port:, max_queue_size: nil, thread_sleep: 0.5)
38
+ def initialize(host: 'localhost', port: PrometheusExporter::DEFAULT_PORT, max_queue_size: nil, thread_sleep: 0.5)
31
39
  @metrics = []
32
40
 
33
41
  @queue = Queue.new
@@ -0,0 +1,2 @@
1
+ require_relative "instrumentation/process"
2
+ require_relative "instrumentation/method_profiler"
@@ -0,0 +1,55 @@
1
+ # see https://samsaffron.com/archive/2017/10/18/fastest-way-to-profile-a-method-in-ruby
2
+ module PrometheusExporter::Instrumentation; end
3
+
4
+ class PrometheusExporter::Instrumentation::MethodProfiler
5
+ def self.patch(klass, methods, name)
6
+ patches = methods.map do |method_name|
7
+ <<~RUBY
8
+ unless defined?(#{method_name}__mp_unpatched)
9
+ alias_method :#{method_name}__mp_unpatched, :#{method_name}
10
+ def #{method_name}(*args, &blk)
11
+ unless prof = Thread.current[:_method_profiler]
12
+ return #{method_name}__mp_unpatched(*args, &blk)
13
+ end
14
+ begin
15
+ start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
16
+ #{method_name}__mp_unpatched(*args, &blk)
17
+ ensure
18
+ data = (prof[:#{name}] ||= {duration: 0.0, calls: 0})
19
+ data[:duration] += Process.clock_gettime(Process::CLOCK_MONOTONIC) - start
20
+ data[:calls] += 1
21
+ end
22
+ end
23
+ end
24
+ RUBY
25
+ end.join("\n")
26
+
27
+ klass.class_eval patches
28
+ end
29
+
30
+ def self.transfer
31
+ result = Thread.current[:_method_profiler]
32
+ Thread.current[:_method_profiler] = nil
33
+ result
34
+ end
35
+
36
+ def self.start(transfer = nil)
37
+ Thread.current[:_method_profiler] = transfer || {
38
+ __start: Process.clock_gettime(Process::CLOCK_MONOTONIC)
39
+ }
40
+ end
41
+
42
+ def self.clear
43
+ Thread.current[:_method_profiler] = nil
44
+ end
45
+
46
+ def self.stop
47
+ finish = Process.clock_gettime(Process::CLOCK_MONOTONIC)
48
+ if data = Thread.current[:_method_profiler]
49
+ Thread.current[:_method_profiler] = nil
50
+ start = data.delete(:__start)
51
+ data[:total_duration] = finish - start
52
+ end
53
+ data
54
+ end
55
+ end
@@ -0,0 +1,77 @@
1
+ # collects stats from currently running process
2
+ module PrometheusExporter::Instrumentation
3
+ class Process
4
+ def self.start(client: nil, type: "ruby", frequency: 30)
5
+ process_collector = new(type)
6
+ client ||= PrometheusExporter::Client.default
7
+ Thread.new do
8
+ while true
9
+ begin
10
+ metric = process_collector.collect
11
+ client.send_json metric
12
+ rescue => e
13
+ STDERR.puts("Prometheus Discoruse Failed To Collect Process Stats #{e}")
14
+ ensure
15
+ sleep frequency
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ def initialize(type)
22
+ @type = type
23
+ end
24
+
25
+ def collect
26
+ metric = {}
27
+ metric[:type] = "process"
28
+ metric[:process_type] = @type
29
+ collect_gc_stats(metric)
30
+ collect_v8_stats(metric)
31
+ collect_process_stats(metric)
32
+ metric
33
+ end
34
+
35
+ def pid
36
+ @pid = ::Process.pid
37
+ end
38
+
39
+ def rss
40
+ @pagesize ||= `getconf PAGESIZE`.to_i rescue 4096
41
+ File.read("/proc/#{pid}/statm").split(' ')[1].to_i * @pagesize rescue 0
42
+ end
43
+
44
+ def collect_process_stats(metric)
45
+ metric[:pid] = pid
46
+ metric[:rss] = rss
47
+
48
+ end
49
+
50
+ def collect_gc_stats(metric)
51
+ stat = GC.stat
52
+ metric[:heap_live_slots] = stat[:heap_live_slots]
53
+ metric[:heap_free_slots] = stat[:heap_free_slots]
54
+ metric[:major_gc_count] = stat[:major_gc_count]
55
+ metric[:minor_gc_count] = stat[:minor_gc_count]
56
+ metric[:total_allocated_objects] = stat[:total_allocated_objects]
57
+ end
58
+
59
+ def collect_v8_stats(metric)
60
+ return if !defined? MiniRacer
61
+
62
+ metric[:v8_heap_count] = metric[:v8_heap_size] = 0
63
+ metric[:v8_heap_size] = metric[:v8_physical_size] = 0
64
+ metric[:v8_used_heap_size] = 0
65
+
66
+ ObjectSpace.each_object(MiniRacer::Context) do |context|
67
+ stats = context.heap_stats
68
+ if stats
69
+ metric[:v8_heap_count] += 1
70
+ metric[:v8_heap_size] += stats[:total_heap_size].to_i
71
+ metric[:v8_used_heap_size] += stats[:used_heap_size].to_i
72
+ metric[:v8_physical_size] += stats[:total_physical_size].to_i
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'prometheus_exporter/instrumentation/method_profiler'
4
+ require 'prometheus_exporter/client'
5
+
6
+ class PrometheusExporter::Middleware
7
+ MethodProfiler = PrometheusExporter::Instrumentation::MethodProfiler
8
+
9
+ def initialize(app, config = { instrument: true, client: nil })
10
+ @app = app
11
+ @client = config[:client] || PrometheusExporter::Client.default
12
+
13
+ if config[:instrument]
14
+ if defined? Redis::Client
15
+ MethodProfiler.patch(Redis::Client, [:call, :call_pipeline], :redis)
16
+ end
17
+ if defined? PG::Connection
18
+ MethodProfiler.patch(PG::Connection, [
19
+ :exec, :async_exec, :exec_prepared, :send_query_prepared, :query
20
+ ], :sql)
21
+ end
22
+ end
23
+ end
24
+
25
+ def call(env)
26
+ MethodProfiler.start
27
+ result = @app.call(env)
28
+ info = MethodProfiler.stop
29
+ result
30
+ ensure
31
+ status = (result && result[0]) || -1
32
+ params = env["action_dispatch.request.parameters"]
33
+ action, controller = nil
34
+ if params
35
+ action = params["action"]
36
+ controller = params["controller"]
37
+ end
38
+
39
+ @client.send_json(
40
+ type: "web",
41
+ timings: info,
42
+ action: action,
43
+ controller: controller,
44
+ status: status
45
+ )
46
+ end
47
+ end
@@ -1,3 +1,4 @@
1
+ require_relative "server/collector_base"
1
2
  require_relative "server/collector"
2
3
  require_relative "server/web_server"
3
4
  require_relative "metric"
@@ -2,9 +2,26 @@
2
2
 
3
3
  module PrometheusExporter::Server
4
4
 
5
- class Collector
5
+ class Collector < CollectorBase
6
+ MAX_PROCESS_METRIC_AGE = 60
7
+ PROCESS_GAUGES = {
8
+ heap_free_slots: "Free ruby heap slots",
9
+ heap_live_slots: "Used ruby heap slots",
10
+ v8_heap_size: "Total JavaScript V8 heap size (bytes)",
11
+ v8_used_heap_size: "Total used JavaScript V8 heap size (bytes)",
12
+ v8_physical_size: "Physical size consumed by V8 heaps",
13
+ v8_heap_count: "Number of V8 contexts running",
14
+ rss: "Total RSS used by process",
15
+ }
16
+
17
+ PROCESS_COUNTERS = {
18
+ major_gc_count: "Major GC operations by process",
19
+ minor_gc_count: "Minor GC operations by process",
20
+ total_allocated_objects: "Total number of allocateds objects by process",
21
+ }
6
22
 
7
23
  def initialize
24
+ @process_metrics = []
8
25
  @metrics = {}
9
26
  @buffer = []
10
27
  @mutex = Mutex.new
@@ -13,27 +30,120 @@ module PrometheusExporter::Server
13
30
  def process(str)
14
31
  obj = JSON.parse(str)
15
32
  @mutex.synchronize do
16
- metric = @metrics[obj["name"]]
17
- if !metric
18
- metric = register_metric_unsafe(obj)
33
+ if obj["type"] == "web"
34
+ observe_web(obj)
35
+ elsif obj["type"] == "process"
36
+ observe_process(obj)
37
+ else
38
+ metric = @metrics[obj["name"]]
39
+ if !metric
40
+ metric = register_metric_unsafe(obj)
41
+ end
42
+ metric.observe(obj["value"], obj["keys"])
19
43
  end
20
- metric.observe(obj["value"], obj["keys"])
21
44
  end
22
45
  end
23
46
 
24
47
  def prometheus_metrics_text
25
48
  @mutex.synchronize do
26
- @metrics.values.map(&:to_prometheus_text).join("\n")
49
+ val = @metrics.values.map(&:to_prometheus_text).join("\n")
50
+
51
+ metrics = {}
52
+
53
+ if @process_metrics.length > 0
54
+ val << "\n"
55
+
56
+ @process_metrics.map do |m|
57
+ metric_key = { pid: m["pid"], type: m["process_type"] }
58
+
59
+ PROCESS_GAUGES.map do |k, help|
60
+ k = k.to_s
61
+ if v = m[k]
62
+ g = metrics[k] ||= PrometheusExporter::Metric::Gauge.new(k, help)
63
+ g.observe(v, metric_key)
64
+ end
65
+ end
66
+
67
+ PROCESS_COUNTERS.map do |k, help|
68
+ k = k.to_s
69
+ if v = m[k]
70
+ c = metrics[k] ||= PrometheusExporter::Metric::Counter.new(k, help)
71
+ c.observe(v, metric_key)
72
+ end
73
+ end
74
+
75
+ end
76
+
77
+ val << metrics.values.map(&:to_prometheus_text).join("\n")
78
+ end
79
+
80
+ val
27
81
  end
28
82
  end
29
83
 
84
+ protected
85
+
30
86
  def register_metric(metric)
31
87
  @mutex.synchronize do
32
88
  @metrics << metric
33
89
  end
34
90
  end
35
91
 
36
- protected
92
+ def ensure_web_metrics
93
+ unless @http_requests
94
+ @metrics["http_requests"] = @http_requests = PrometheusExporter::Metric::Counter.new(
95
+ "http_requests",
96
+ "Total HTTP requests from web app"
97
+ )
98
+
99
+ @metrics["http_duration_seconds"] = @http_duration_seconds = PrometheusExporter::Metric::Summary.new(
100
+ "http_duration_seconds",
101
+ "Time spent in HTTP reqs in seconds"
102
+ )
103
+
104
+ @metrics["http_redis_duration_seconds"] = @http_redis_duration_seconds = PrometheusExporter::Metric::Summary.new(
105
+ "http_redis_duration_seconds",
106
+ "Time spent in HTTP reqs in redis seconds"
107
+ )
108
+
109
+ @metrics["http_sql_duration_seconds"] = @http_sql_duration_seconds = PrometheusExporter::Metric::Summary.new(
110
+ "http_sql_duration_seconds",
111
+ "Time spent in HTTP reqs in SQL in seconds"
112
+ )
113
+ end
114
+ end
115
+
116
+ def observe_web(obj)
117
+ ensure_web_metrics
118
+
119
+ labels = {
120
+ controller: obj["controller"] || "other",
121
+ action: obj["action"] || "other"
122
+ }
123
+
124
+ @http_requests.observe(1, labels.merge(status: obj["status"]))
125
+
126
+ if timings = obj["timings"]
127
+ @http_duration_seconds.observe(timings["total_duration"], labels)
128
+ if redis = timings["redis"]
129
+ @http_redis_duration_seconds.observe(redis["duration"], labels)
130
+ end
131
+ if sql = timings["sql"]
132
+ @http_sql_duration_seconds.observe(sql["duration"], labels)
133
+ end
134
+ end
135
+ end
136
+
137
+ def observe_process(obj)
138
+ now = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
139
+
140
+ obj["created_at"] = now
141
+
142
+ @process_metrics.delete_if do |current|
143
+ obj["pid"] == current["pid"] || (current["created_at"] + MAX_PROCESS_METRIC_AGE < now)
144
+ end
145
+ @process_metrics << obj
146
+ end
37
147
 
38
148
  def register_metric_unsafe(obj)
39
149
  name = obj["name"]
@@ -0,0 +1,14 @@
1
+ module PrometheusExporter::Server
2
+
3
+ # minimal interface to implement a customer collector
4
+ class CollectorBase
5
+
6
+ # called each time a string is delivered from the web
7
+ def process(str)
8
+ end
9
+
10
+ # a string denoting the metrics
11
+ def prometheus_metrics_text(str)
12
+ end
13
+ end
14
+ end
@@ -9,7 +9,9 @@ module PrometheusExporter::Server
9
9
  class WebServer
10
10
  attr_reader :collector
11
11
 
12
- def initialize(port: , collector: nil)
12
+ def initialize(port: , collector: nil, verbose: false)
13
+
14
+ @verbose = verbose
13
15
 
14
16
  @total_metrics = PrometheusExporter::Metric::Counter.new("total_collector_metrics", "total metrics processed by exporter web")
15
17
 
@@ -21,10 +23,19 @@ module PrometheusExporter::Server
21
23
  @total_sessions.observe(0)
22
24
  @total_bad_metrics.observe(0)
23
25
 
26
+ access_log = []
27
+ if verbose
28
+ access_log = [
29
+ [$stderr, WEBrick::AccessLog::COMMON_LOG_FORMAT],
30
+ [$stderr, WEBrick::AccessLog::REFERER_LOG_FORMAT],
31
+ ]
32
+ logger = WEBrick::Log.new($stderr)
33
+ end
34
+
24
35
  @server = WEBrick::HTTPServer.new(
25
36
  Port: port,
26
- AccessLog: [],
27
- Logger: WEBrick::Log.new("/dev/null")
37
+ Logger: logger,
38
+ AccessLog: access_log
28
39
  )
29
40
 
30
41
  @collector = collector || Collector.new
@@ -52,7 +63,7 @@ module PrometheusExporter::Server
52
63
  handle_metrics(req, res)
53
64
  else
54
65
  res.status = 404
55
- res.body = "Not Found! The Prometheus Discourse plugin only listens on /metrics and /send-metrics"
66
+ res.body = "Not Found! The Prometheus Ruby Exporter only listens on /metrics and /send-metrics"
56
67
  end
57
68
  end
58
69
  end
@@ -64,6 +75,12 @@ module PrometheusExporter::Server
64
75
  @total_metrics.observe
65
76
  @collector.process(block)
66
77
  rescue => e
78
+ if @verbose
79
+ STDERR.puts
80
+ STDERR.puts e.inspect
81
+ STDERR.puts e.backtrace
82
+ STDERR.puts
83
+ end
67
84
  @total_bad_metrics.observe
68
85
  res.body = "Bad Metrics #{e}"
69
86
  res.status = e.respond_to?(:status_code) ? e.status_code : 500
@@ -1,3 +1,3 @@
1
1
  module PrometheusExporter
2
- VERSION = "0.1.6"
2
+ VERSION = "0.1.7"
3
3
  end
@@ -18,12 +18,13 @@ Gem::Specification.new do |spec|
18
18
  f.match(%r{^(test|spec|features|bin)/})
19
19
  end
20
20
  spec.bindir = "bin"
21
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
21
+ spec.executables = ["prometheus_exporter"]
22
22
  spec.require_paths = ["lib"]
23
23
 
24
24
  spec.add_development_dependency "bundler", "~> 1.16"
25
25
  spec.add_development_dependency "rake", "~> 10.0"
26
26
  spec.add_development_dependency "minitest", "~> 5.0"
27
27
  spec.add_development_dependency "guard", "~> 2.0"
28
+ spec.add_development_dependency "mini_racer", "~> 0.1"
28
29
  spec.add_development_dependency "guard-minitest", "~> 2.0"
29
30
  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.1.6
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-14 00:00:00.000000000 Z
11
+ date: 2018-01-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '2.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: mini_racer
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.1'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.1'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: guard-minitest
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -83,7 +97,8 @@ dependencies:
83
97
  description: Prometheus metric collector and exporter for Ruby
84
98
  email:
85
99
  - sam.saffron@gmail.com
86
- executables: []
100
+ executables:
101
+ - prometheus_exporter
87
102
  extensions: []
88
103
  extra_rdoc_files: []
89
104
  files:
@@ -97,16 +112,22 @@ files:
97
112
  - README.md
98
113
  - Rakefile
99
114
  - bench/bench.rb
115
+ - bin/prometheus_exporter
100
116
  - examples/custom_collector.rb
101
117
  - lib/prometheus_exporter.rb
102
118
  - lib/prometheus_exporter/client.rb
119
+ - lib/prometheus_exporter/instrumentation.rb
120
+ - lib/prometheus_exporter/instrumentation/method_profiler.rb
121
+ - lib/prometheus_exporter/instrumentation/process.rb
103
122
  - lib/prometheus_exporter/metric.rb
104
123
  - lib/prometheus_exporter/metric/base.rb
105
124
  - lib/prometheus_exporter/metric/counter.rb
106
125
  - lib/prometheus_exporter/metric/gauge.rb
107
126
  - lib/prometheus_exporter/metric/summary.rb
127
+ - lib/prometheus_exporter/middleware.rb
108
128
  - lib/prometheus_exporter/server.rb
109
129
  - lib/prometheus_exporter/server/collector.rb
130
+ - lib/prometheus_exporter/server/collector_base.rb
110
131
  - lib/prometheus_exporter/server/web_server.rb
111
132
  - lib/prometheus_exporter/version.rb
112
133
  - prometheus_exporter.gemspec