prometheus_exporter 0.1.6 → 0.1.7

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: 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