prometheus-client 0.6.0 → 0.7.0.pre.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +17 -17
- data/lib/prometheus/client/counter.rb +1 -1
- data/lib/prometheus/client/gauge.rb +5 -1
- data/lib/prometheus/client/histogram.rb +2 -2
- data/lib/prometheus/client/metric.rb +0 -5
- data/lib/prometheus/client/push.rb +9 -3
- data/lib/prometheus/client/registry.rb +1 -2
- data/lib/prometheus/client/version.rb +1 -1
- data/lib/prometheus/middleware/collector.rb +91 -0
- data/lib/prometheus/middleware/exporter.rb +91 -0
- metadata +7 -7
- data/lib/prometheus/client/rack/collector.rb +0 -82
- data/lib/prometheus/client/rack/exporter.rb +0 -91
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c7df7b1114d199d5da7e201aa5a3d42898c5db9a
|
4
|
+
data.tar.gz: 5bea74f933571336d6dba20f9b5a28aa12321b52
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bdfb89648fb64ee9c9bbfaaf4d4158834b3cbdc79d562530fa61d4511f8e95b2e15f4e01c374fedeb985dbf1c69fa3d5748260d29eaf5e87ed784350e1613437
|
7
|
+
data.tar.gz: acb12ac03128cb6387930d6f4fb43997be306fa590cd9cad706c319f514509cc631e2103152d57294e68738a4a30f42e0c6102a21db4d6ca9335d1bca646bec5
|
data/README.md
CHANGED
@@ -35,7 +35,7 @@ http_requests.increment
|
|
35
35
|
### Rack middleware
|
36
36
|
|
37
37
|
There are two [Rack][2] middlewares available, one to expose a metrics HTTP
|
38
|
-
endpoint to be scraped by a
|
38
|
+
endpoint to be scraped by a Prometheus server ([Exporter][9]) and one to trace all HTTP
|
39
39
|
requests ([Collector][10]).
|
40
40
|
|
41
41
|
It's highly recommended to enable gzip compression for the metrics endpoint,
|
@@ -45,14 +45,14 @@ for example by including the `Rack::Deflater` middleware.
|
|
45
45
|
# config.ru
|
46
46
|
|
47
47
|
require 'rack'
|
48
|
-
require 'prometheus/
|
49
|
-
require 'prometheus/
|
48
|
+
require 'prometheus/middleware/collector'
|
49
|
+
require 'prometheus/middleware/exporter'
|
50
50
|
|
51
|
-
use Rack::Deflater, if: ->(
|
52
|
-
use Prometheus::
|
53
|
-
use Prometheus::
|
51
|
+
use Rack::Deflater, if: ->(_, _, _, body) { body.any? && body[0].length > 512 }
|
52
|
+
use Prometheus::Middleware::Collector
|
53
|
+
use Prometheus::Middleware::Exporter
|
54
54
|
|
55
|
-
run ->(
|
55
|
+
run ->(_) { [200, {'Content-Type' => 'text/html'}, ['OK']] }
|
56
56
|
```
|
57
57
|
|
58
58
|
Start the server and have a look at the metrics endpoint:
|
@@ -85,6 +85,10 @@ Prometheus::Client::Push.new(
|
|
85
85
|
# If you want to replace any previously pushed metrics for a given instance,
|
86
86
|
# use the #replace method.
|
87
87
|
Prometheus::Client::Push.new('my-batch-job', 'instance').replace(prometheus)
|
88
|
+
|
89
|
+
# If you want to delete all previously pushed metrics for a given instance,
|
90
|
+
# use the #delete method.
|
91
|
+
Prometheus::Client::Push.new('my-batch-job', 'instance').delete
|
88
92
|
```
|
89
93
|
|
90
94
|
## Metrics
|
@@ -137,7 +141,7 @@ histogram = Prometheus::Client::Histogram.new(:service_latency_seconds, '...')
|
|
137
141
|
# record a value
|
138
142
|
histogram.observe({ service: 'users' }, Benchmark.realtime { service.call(arg) })
|
139
143
|
|
140
|
-
# retrieve the current
|
144
|
+
# retrieve the current bucket values
|
141
145
|
histogram.get({ service: 'users' })
|
142
146
|
# => { 0.005 => 3, 0.01 => 15, 0.025 => 18, ..., 2.5 => 42, 5 => 42, 10 = >42 }
|
143
147
|
```
|
@@ -158,10 +162,6 @@ summary.get({ service: 'database' })
|
|
158
162
|
# => { 0.5 => 0.1233122, 0.9 => 3.4323, 0.99 => 5.3428231 }
|
159
163
|
```
|
160
164
|
|
161
|
-
## Todo
|
162
|
-
|
163
|
-
* add protobuf support
|
164
|
-
|
165
165
|
## Tests
|
166
166
|
|
167
167
|
Install necessary development gems with `bundle install` and run tests with
|
@@ -173,11 +173,11 @@ rake
|
|
173
173
|
|
174
174
|
[1]: https://github.com/prometheus/prometheus
|
175
175
|
[2]: http://rack.github.io/
|
176
|
-
[3]: https://secure.travis-ci.org/prometheus/client_ruby.
|
176
|
+
[3]: https://secure.travis-ci.org/prometheus/client_ruby.svg?branch=master
|
177
177
|
[4]: https://badge.fury.io/rb/prometheus-client.svg
|
178
178
|
[5]: https://gemnasium.com/prometheus/client_ruby.svg
|
179
|
-
[6]: https://codeclimate.com/github/prometheus/client_ruby.
|
180
|
-
[7]: https://coveralls.io/repos/prometheus/client_ruby/badge.
|
179
|
+
[6]: https://codeclimate.com/github/prometheus/client_ruby.svg
|
180
|
+
[7]: https://coveralls.io/repos/prometheus/client_ruby/badge.svg?branch=master
|
181
181
|
[8]: https://github.com/prometheus/pushgateway
|
182
|
-
[9]: lib/prometheus/
|
183
|
-
[10]: lib/prometheus/
|
182
|
+
[9]: lib/prometheus/middleware/exporter.rb
|
183
|
+
[10]: lib/prometheus/middleware/collector.rb
|
@@ -13,7 +13,11 @@ module Prometheus
|
|
13
13
|
|
14
14
|
# Sets the value for the given label set
|
15
15
|
def set(labels, value)
|
16
|
-
|
16
|
+
unless value.is_a?(Numeric)
|
17
|
+
raise ArgumentError, 'value must be a number'
|
18
|
+
end
|
19
|
+
|
20
|
+
@values[label_set_for(labels)] = value.to_f
|
17
21
|
end
|
18
22
|
end
|
19
23
|
end
|
@@ -16,6 +16,7 @@ module Prometheus
|
|
16
16
|
PATH = '/metrics/jobs/%s'.freeze
|
17
17
|
INSTANCE_PATH = '/metrics/jobs/%s/instances/%s'.freeze
|
18
18
|
HEADER = { 'Content-Type' => Formats::Text::CONTENT_TYPE }.freeze
|
19
|
+
SUPPORTED_SCHEMES = %w(http https).freeze
|
19
20
|
|
20
21
|
attr_reader :job, :instance, :gateway, :path
|
21
22
|
|
@@ -26,6 +27,7 @@ module Prometheus
|
|
26
27
|
@uri = parse(@gateway)
|
27
28
|
@path = build_path(job, instance)
|
28
29
|
@http = Net::HTTP.new(@uri.host, @uri.port)
|
30
|
+
@http.use_ssl = @uri.scheme == 'https'
|
29
31
|
end
|
30
32
|
|
31
33
|
def add(registry)
|
@@ -36,16 +38,20 @@ module Prometheus
|
|
36
38
|
request('PUT', registry)
|
37
39
|
end
|
38
40
|
|
41
|
+
def delete
|
42
|
+
@http.send_request('DELETE', path)
|
43
|
+
end
|
44
|
+
|
39
45
|
private
|
40
46
|
|
41
47
|
def parse(url)
|
42
48
|
uri = URI.parse(url)
|
43
49
|
|
44
|
-
|
45
|
-
uri
|
46
|
-
else
|
50
|
+
unless SUPPORTED_SCHEMES.include?(uri.scheme)
|
47
51
|
raise ArgumentError, 'only HTTP gateway URLs are supported currently.'
|
48
52
|
end
|
53
|
+
|
54
|
+
uri
|
49
55
|
rescue URI::InvalidURIError => e
|
50
56
|
raise ArgumentError, "#{url} is not a valid URL: #{e}"
|
51
57
|
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'prometheus/client'
|
4
|
+
|
5
|
+
module Prometheus
|
6
|
+
module Middleware
|
7
|
+
# Collector is a Rack middleware that provides a sample implementation of a
|
8
|
+
# HTTP tracer.
|
9
|
+
#
|
10
|
+
# By default metrics are registered on the global registry. Set the
|
11
|
+
# `:registry` option to use a custom registry.
|
12
|
+
#
|
13
|
+
# The request counter metric is broken down by code, method and path by
|
14
|
+
# default. Set the `:counter_label_builder` option to use a custom label
|
15
|
+
# builder.
|
16
|
+
#
|
17
|
+
# The request duration metric is broken down by method and path by default.
|
18
|
+
# Set the `:duration_label_builder` option to use a custom label builder.
|
19
|
+
class Collector
|
20
|
+
attr_reader :app, :registry
|
21
|
+
|
22
|
+
def initialize(app, options = {})
|
23
|
+
@app = app
|
24
|
+
@registry = options[:registry] || Client.registry
|
25
|
+
@counter_lb = options[:counter_label_builder] || COUNTER_LB
|
26
|
+
@duration_lb = options[:duration_label_builder] || DURATION_LB
|
27
|
+
|
28
|
+
init_request_metrics
|
29
|
+
init_exception_metrics
|
30
|
+
end
|
31
|
+
|
32
|
+
def call(env) # :nodoc:
|
33
|
+
trace(env) { @app.call(env) }
|
34
|
+
end
|
35
|
+
|
36
|
+
protected
|
37
|
+
|
38
|
+
COUNTER_LB = proc do |env, code|
|
39
|
+
{
|
40
|
+
code: code,
|
41
|
+
method: env['REQUEST_METHOD'].downcase,
|
42
|
+
path: env['PATH_INFO'].to_s,
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
DURATION_LB = proc do |env, _|
|
47
|
+
{
|
48
|
+
method: env['REQUEST_METHOD'].downcase,
|
49
|
+
path: env['PATH_INFO'].to_s,
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
def init_request_metrics
|
54
|
+
@requests = @registry.counter(
|
55
|
+
:http_server_requests_total,
|
56
|
+
'The total number of HTTP requests handled by the Rack application.',
|
57
|
+
)
|
58
|
+
@durations = @registry.histogram(
|
59
|
+
:http_server_request_duration_seconds,
|
60
|
+
'The HTTP response duration of the Rack application.',
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
def init_exception_metrics
|
65
|
+
@exceptions = @registry.counter(
|
66
|
+
:http_server_exceptions_total,
|
67
|
+
'The total number of exceptions raised by the Rack application.',
|
68
|
+
)
|
69
|
+
end
|
70
|
+
|
71
|
+
def trace(env)
|
72
|
+
start = Time.now
|
73
|
+
yield.tap do |response|
|
74
|
+
duration = [(Time.now - start).to_f, 0.0].max
|
75
|
+
record(env, response.first.to_s, duration)
|
76
|
+
end
|
77
|
+
rescue => exception
|
78
|
+
@exceptions.increment(exception: exception.class.name)
|
79
|
+
raise
|
80
|
+
end
|
81
|
+
|
82
|
+
def record(env, code, duration)
|
83
|
+
@requests.increment(@counter_lb.call(env, code))
|
84
|
+
@durations.observe(@duration_lb.call(env, code), duration)
|
85
|
+
rescue
|
86
|
+
# TODO: log unexpected exception during request recording
|
87
|
+
nil
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'prometheus/client'
|
4
|
+
require 'prometheus/client/formats/text'
|
5
|
+
|
6
|
+
module Prometheus
|
7
|
+
module Middleware
|
8
|
+
# Exporter is a Rack middleware that provides a sample implementation of a
|
9
|
+
# Prometheus HTTP exposition endpoint.
|
10
|
+
#
|
11
|
+
# By default it will export the state of the global registry and expose it
|
12
|
+
# under `/metrics`. Use the `:registry` and `:path` options to change the
|
13
|
+
# defaults.
|
14
|
+
class Exporter
|
15
|
+
attr_reader :app, :registry, :path
|
16
|
+
|
17
|
+
FORMATS = [Client::Formats::Text].freeze
|
18
|
+
FALLBACK = Client::Formats::Text
|
19
|
+
|
20
|
+
def initialize(app, options = {})
|
21
|
+
@app = app
|
22
|
+
@registry = options[:registry] || Client.registry
|
23
|
+
@path = options[:path] || '/metrics'
|
24
|
+
@acceptable = build_dictionary(FORMATS, FALLBACK)
|
25
|
+
end
|
26
|
+
|
27
|
+
def call(env)
|
28
|
+
if env['PATH_INFO'] == @path
|
29
|
+
format = negotiate(env, @acceptable)
|
30
|
+
format ? respond_with(format) : not_acceptable(FORMATS)
|
31
|
+
else
|
32
|
+
@app.call(env)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def negotiate(env, formats)
|
39
|
+
parse(env.fetch('HTTP_ACCEPT', '*/*')).each do |content_type, _|
|
40
|
+
return formats[content_type] if formats.key?(content_type)
|
41
|
+
end
|
42
|
+
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
|
46
|
+
def parse(header)
|
47
|
+
header.split(/\s*,\s*/).map do |type|
|
48
|
+
attributes = type.split(/\s*;\s*/)
|
49
|
+
quality = extract_quality(attributes)
|
50
|
+
|
51
|
+
[attributes.join('; '), quality]
|
52
|
+
end.sort_by(&:last).reverse
|
53
|
+
end
|
54
|
+
|
55
|
+
def extract_quality(attributes, default = 1.0)
|
56
|
+
quality = default
|
57
|
+
|
58
|
+
attributes.delete_if do |attr|
|
59
|
+
quality = attr.split('q=').last.to_f if attr.start_with?('q=')
|
60
|
+
end
|
61
|
+
|
62
|
+
quality
|
63
|
+
end
|
64
|
+
|
65
|
+
def respond_with(format)
|
66
|
+
[
|
67
|
+
200,
|
68
|
+
{ 'Content-Type' => format::CONTENT_TYPE },
|
69
|
+
[format.marshal(@registry)],
|
70
|
+
]
|
71
|
+
end
|
72
|
+
|
73
|
+
def not_acceptable(formats)
|
74
|
+
types = formats.map { |format| format::MEDIA_TYPE }
|
75
|
+
|
76
|
+
[
|
77
|
+
406,
|
78
|
+
{ 'Content-Type' => 'text/plain' },
|
79
|
+
["Supported media types: #{types.join(', ')}"],
|
80
|
+
]
|
81
|
+
end
|
82
|
+
|
83
|
+
def build_dictionary(formats, fallback)
|
84
|
+
formats.each_with_object('*/*' => fallback) do |format, memo|
|
85
|
+
memo[format::CONTENT_TYPE] = format
|
86
|
+
memo[format::MEDIA_TYPE] = format
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prometheus-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0.pre.rc.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tobias Schmidt
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-03-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: quantile
|
@@ -41,11 +41,11 @@ files:
|
|
41
41
|
- lib/prometheus/client/label_set_validator.rb
|
42
42
|
- lib/prometheus/client/metric.rb
|
43
43
|
- lib/prometheus/client/push.rb
|
44
|
-
- lib/prometheus/client/rack/collector.rb
|
45
|
-
- lib/prometheus/client/rack/exporter.rb
|
46
44
|
- lib/prometheus/client/registry.rb
|
47
45
|
- lib/prometheus/client/summary.rb
|
48
46
|
- lib/prometheus/client/version.rb
|
47
|
+
- lib/prometheus/middleware/collector.rb
|
48
|
+
- lib/prometheus/middleware/exporter.rb
|
49
49
|
homepage: https://github.com/prometheus/client_ruby
|
50
50
|
licenses:
|
51
51
|
- Apache 2.0
|
@@ -61,12 +61,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
61
61
|
version: '0'
|
62
62
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
63
|
requirements:
|
64
|
-
- - "
|
64
|
+
- - ">"
|
65
65
|
- !ruby/object:Gem::Version
|
66
|
-
version:
|
66
|
+
version: 1.3.1
|
67
67
|
requirements: []
|
68
68
|
rubyforge_project:
|
69
|
-
rubygems_version: 2.
|
69
|
+
rubygems_version: 2.6.8
|
70
70
|
signing_key:
|
71
71
|
specification_version: 4
|
72
72
|
summary: A suite of instrumentation metric primitivesthat can be exposed through a
|
@@ -1,82 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
require 'prometheus/client'
|
4
|
-
|
5
|
-
module Prometheus
|
6
|
-
module Client
|
7
|
-
module Rack
|
8
|
-
# Collector is a Rack middleware that provides a sample implementation of
|
9
|
-
# a HTTP tracer. The default label builder can be modified to export a
|
10
|
-
# different set of labels per recorded metric.
|
11
|
-
class Collector
|
12
|
-
attr_reader :app, :registry
|
13
|
-
|
14
|
-
def initialize(app, options = {}, &label_builder)
|
15
|
-
@app = app
|
16
|
-
@registry = options[:registry] || Client.registry
|
17
|
-
@label_builder = label_builder || DEFAULT_LABEL_BUILDER
|
18
|
-
|
19
|
-
init_request_metrics
|
20
|
-
init_exception_metrics
|
21
|
-
end
|
22
|
-
|
23
|
-
def call(env) # :nodoc:
|
24
|
-
trace(env) { @app.call(env) }
|
25
|
-
end
|
26
|
-
|
27
|
-
protected
|
28
|
-
|
29
|
-
DEFAULT_LABEL_BUILDER = proc do |env|
|
30
|
-
{
|
31
|
-
method: env['REQUEST_METHOD'].downcase,
|
32
|
-
host: env['HTTP_HOST'].to_s,
|
33
|
-
path: env['PATH_INFO'].to_s,
|
34
|
-
}
|
35
|
-
end
|
36
|
-
|
37
|
-
def init_request_metrics
|
38
|
-
@requests = @registry.counter(
|
39
|
-
:http_requests_total,
|
40
|
-
'A counter of the total number of HTTP requests made.',
|
41
|
-
)
|
42
|
-
@durations = @registry.summary(
|
43
|
-
:http_request_duration_seconds,
|
44
|
-
'A histogram of the response latency.',
|
45
|
-
)
|
46
|
-
end
|
47
|
-
|
48
|
-
def init_exception_metrics
|
49
|
-
@exceptions = @registry.counter(
|
50
|
-
:http_exceptions_total,
|
51
|
-
'A counter of the total number of exceptions raised.',
|
52
|
-
)
|
53
|
-
end
|
54
|
-
|
55
|
-
def trace(env)
|
56
|
-
start = Time.now
|
57
|
-
yield.tap do |response|
|
58
|
-
duration = (Time.now - start).to_f
|
59
|
-
record(labels(env, response), duration)
|
60
|
-
end
|
61
|
-
rescue => exception
|
62
|
-
@exceptions.increment(exception: exception.class.name)
|
63
|
-
raise
|
64
|
-
end
|
65
|
-
|
66
|
-
def labels(env, response)
|
67
|
-
@label_builder.call(env).tap do |labels|
|
68
|
-
labels[:code] = response.first.to_s
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def record(labels, duration)
|
73
|
-
@requests.increment(labels)
|
74
|
-
@durations.observe(labels, duration)
|
75
|
-
rescue
|
76
|
-
# TODO: log unexpected exception during request recording
|
77
|
-
nil
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
@@ -1,91 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
require 'prometheus/client'
|
4
|
-
require 'prometheus/client/formats/text'
|
5
|
-
|
6
|
-
module Prometheus
|
7
|
-
module Client
|
8
|
-
module Rack
|
9
|
-
# Exporter is a Rack middleware that provides a sample implementation of
|
10
|
-
# a Prometheus HTTP client API.
|
11
|
-
class Exporter
|
12
|
-
attr_reader :app, :registry, :path
|
13
|
-
|
14
|
-
FORMATS = [Formats::Text].freeze
|
15
|
-
FALLBACK = Formats::Text
|
16
|
-
|
17
|
-
def initialize(app, options = {})
|
18
|
-
@app = app
|
19
|
-
@registry = options[:registry] || Client.registry
|
20
|
-
@path = options[:path] || '/metrics'
|
21
|
-
@acceptable = build_dictionary(FORMATS, FALLBACK)
|
22
|
-
end
|
23
|
-
|
24
|
-
def call(env)
|
25
|
-
if env['PATH_INFO'] == @path
|
26
|
-
format = negotiate(env['HTTP_ACCEPT'], @acceptable)
|
27
|
-
format ? respond_with(format) : not_acceptable(FORMATS)
|
28
|
-
else
|
29
|
-
@app.call(env)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
private
|
34
|
-
|
35
|
-
def negotiate(accept, formats)
|
36
|
-
accept = '*/*' if accept.to_s.empty?
|
37
|
-
|
38
|
-
parse(accept).each do |content_type, _|
|
39
|
-
return formats[content_type] if formats.key?(content_type)
|
40
|
-
end
|
41
|
-
|
42
|
-
nil
|
43
|
-
end
|
44
|
-
|
45
|
-
def parse(header)
|
46
|
-
header.to_s.split(/\s*,\s*/).map do |type|
|
47
|
-
attributes = type.split(/\s*;\s*/)
|
48
|
-
quality = extract_quality(attributes)
|
49
|
-
|
50
|
-
[attributes.join('; '), quality]
|
51
|
-
end.sort_by(&:last).reverse
|
52
|
-
end
|
53
|
-
|
54
|
-
def extract_quality(attributes, default = 1.0)
|
55
|
-
quality = default
|
56
|
-
|
57
|
-
attributes.delete_if do |attr|
|
58
|
-
quality = attr.split('q=').last.to_f if attr.start_with?('q=')
|
59
|
-
end
|
60
|
-
|
61
|
-
quality
|
62
|
-
end
|
63
|
-
|
64
|
-
def respond_with(format)
|
65
|
-
[
|
66
|
-
200,
|
67
|
-
{ 'Content-Type' => format::CONTENT_TYPE },
|
68
|
-
[format.marshal(@registry)],
|
69
|
-
]
|
70
|
-
end
|
71
|
-
|
72
|
-
def not_acceptable(formats)
|
73
|
-
types = formats.map { |format| format::MEDIA_TYPE }
|
74
|
-
|
75
|
-
[
|
76
|
-
406,
|
77
|
-
{ 'Content-Type' => 'text/plain' },
|
78
|
-
["Supported media types: #{types.join(', ')}"],
|
79
|
-
]
|
80
|
-
end
|
81
|
-
|
82
|
-
def build_dictionary(formats, fallback)
|
83
|
-
formats.each_with_object('*/*' => fallback) do |format, memo|
|
84
|
-
memo[format::CONTENT_TYPE] = format
|
85
|
-
memo[format::MEDIA_TYPE] = format
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|