rack-influxdb 0.1.0 → 0.2.0
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/README.md +6 -0
- data/Rakefile +2 -0
- data/lib/rack/influxdb/configuration.rb +15 -5
- data/lib/rack/influxdb/version.rb +3 -1
- data/lib/rack/influxdb.rb +96 -15
- data/spec/rack_influxdb_spec.rb +107 -21
- data/spec/spec_helper.rb +22 -1
- metadata +54 -15
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 56285fb58ca4b8a2a89e99d44d56226ef01fe04617c2211eb23036f5f913dd9c
|
|
4
|
+
data.tar.gz: 61c49b66c095a40936e1014ebb828b6aafe031d60b35a452bbb90ebe661bb2a3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0c477dc8d0368309191d354c5efcdc2d9892b5a1959eba15d04556d2a1bf2c204e2a79380928bcbd523cb1f1cb82b74aac13bc89e586462fb1ec93f790e94a25
|
|
7
|
+
data.tar.gz: c773adb6e3477eb96477f5e88afc579336b50657a12dcf066a410baab9273cb582bdab9490f283848fe58a08ced59b93ea279587340c01269a749dc615f30bea
|
data/README.md
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
# rack-influxdb
|
|
2
|
+

|
|
2
3
|
|
|
3
4
|
[](https://github.com/heychimpy/rack-influxdb/actions/workflows/test.yml)
|
|
5
|
+
[](https://codecov.io/gh/heychimpy/rack-influxdb)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://github.com/rubocop/rubocop)
|
|
8
|
+

|
|
9
|
+

|
|
4
10
|
|
|
5
11
|
This gem provides a Rack middleware for [InfluxDB](https://github.com/influxdata/influxdb).
|
|
6
12
|
|
data/Rakefile
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Rack
|
|
2
4
|
class InfluxDB
|
|
5
|
+
# The main configuration for the gem.
|
|
3
6
|
class Configuration
|
|
4
7
|
attr_accessor :name, :tags, :url, :token, :options, :write_options,
|
|
5
8
|
:fields, :handle_error
|
|
@@ -15,17 +18,24 @@ module Rack
|
|
|
15
18
|
@tags = {}
|
|
16
19
|
@url = ''
|
|
17
20
|
@token = ''
|
|
18
|
-
@fields =
|
|
19
|
-
@handle_error =
|
|
20
|
-
@options =
|
|
21
|
+
@fields = ->(_env, _response) { {} }
|
|
22
|
+
@handle_error = ->(_err) { nil }
|
|
23
|
+
@options = default_options
|
|
24
|
+
@write_options = default_write_options
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def default_options
|
|
28
|
+
{
|
|
21
29
|
org: '',
|
|
22
30
|
bucket: '',
|
|
23
31
|
precision: InfluxDB2::WritePrecision::MILLISECOND
|
|
24
32
|
}
|
|
33
|
+
end
|
|
25
34
|
|
|
26
|
-
|
|
35
|
+
def default_write_options
|
|
36
|
+
InfluxDB2::WriteOptions.new(
|
|
27
37
|
write_type: InfluxDB2::WriteType::BATCHING,
|
|
28
|
-
batch_size: 100
|
|
38
|
+
batch_size: 100
|
|
29
39
|
)
|
|
30
40
|
end
|
|
31
41
|
end
|
data/lib/rack/influxdb.rb
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'influxdb-client'
|
|
2
4
|
require 'rack/influxdb/configuration'
|
|
3
5
|
|
|
4
6
|
module Rack
|
|
7
|
+
# The InfluxDB rack middleware class.
|
|
5
8
|
class InfluxDB
|
|
6
|
-
|
|
7
|
-
|
|
9
|
+
# Caps how many computed points can be buffered while waiting to be
|
|
10
|
+
# written. If InfluxDB becomes slow or unreachable, the queue fills up
|
|
11
|
+
# and further points are dropped (see #enqueue) instead of growing
|
|
12
|
+
# without bound or blocking requests.
|
|
13
|
+
DEFAULT_QUEUE_SIZE = 1_000
|
|
8
14
|
|
|
15
|
+
class << self
|
|
9
16
|
def configuration
|
|
10
17
|
@configuration ||= Rack::InfluxDB::Configuration.new
|
|
11
18
|
end
|
|
@@ -17,12 +24,28 @@ module Rack
|
|
|
17
24
|
|
|
18
25
|
def initialize(app)
|
|
19
26
|
@app = app
|
|
27
|
+
@queue = SizedQueue.new(DEFAULT_QUEUE_SIZE)
|
|
28
|
+
@worker_mutex = Mutex.new
|
|
29
|
+
@worker = nil
|
|
30
|
+
|
|
31
|
+
# Flush whatever is left in the queue when the process exits (e.g. on
|
|
32
|
+
# a graceful Puma shutdown), so the last few requests before shutdown
|
|
33
|
+
# aren't silently lost. This never blocks a request, only exit.
|
|
34
|
+
at_exit { shutdown }
|
|
20
35
|
end
|
|
21
36
|
|
|
22
37
|
def call(env)
|
|
23
38
|
@app.call(env).tap { |response| write_request(env, response) }
|
|
24
39
|
end
|
|
25
40
|
|
|
41
|
+
# Stops accepting new points and waits (briefly) for the worker to
|
|
42
|
+
# drain whatever is already queued. Safe to call multiple times and
|
|
43
|
+
# safe to call even if the worker was never started.
|
|
44
|
+
def shutdown
|
|
45
|
+
@queue.close unless @queue.closed?
|
|
46
|
+
@worker&.join(5)
|
|
47
|
+
end
|
|
48
|
+
|
|
26
49
|
private
|
|
27
50
|
|
|
28
51
|
def write_request(env, response)
|
|
@@ -31,31 +54,89 @@ module Rack
|
|
|
31
54
|
# environment.
|
|
32
55
|
return if config.token.to_s.empty?
|
|
33
56
|
|
|
34
|
-
#
|
|
35
|
-
#
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
write_api = c.create_write_api(write_options: config.write_options)
|
|
40
|
-
write_api.write(data: point(env, response))
|
|
41
|
-
end
|
|
42
|
-
rescue => e
|
|
43
|
-
config.handle_error.call(e)
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
rescue => e
|
|
57
|
+
# Compute the point on the request thread so the queue - and the
|
|
58
|
+
# worker that reads from it - never has to hold a reference to the
|
|
59
|
+
# Rack env or response. Only the resulting Hash is handed off.
|
|
60
|
+
enqueue(point(env, response))
|
|
61
|
+
rescue StandardError => e
|
|
47
62
|
# Let the app decide what needs to be done when an error occurs.
|
|
48
63
|
config.handle_error.call(e)
|
|
49
64
|
end
|
|
50
65
|
|
|
66
|
+
# Rather than spawning a `Thread.new` (and a new client/WriteApi) for
|
|
67
|
+
# every single request, requests push their computed point onto a
|
|
68
|
+
# queue that a single long-lived worker thread drains. This avoids the
|
|
69
|
+
# per-request cost of thread creation/teardown and the memory growth
|
|
70
|
+
# that comes from many short-lived threads each closing over a Rack
|
|
71
|
+
# env and response.
|
|
72
|
+
def enqueue(data)
|
|
73
|
+
start_worker
|
|
74
|
+
# Non-blocking push: if the queue is full (InfluxDB is slow/down) we
|
|
75
|
+
# drop the point instead of blocking the request or growing memory
|
|
76
|
+
# without bound.
|
|
77
|
+
@queue.push(data, true)
|
|
78
|
+
rescue ClosedQueueError, ThreadError
|
|
79
|
+
nil
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Lazily starts exactly one worker thread for this middleware instance.
|
|
83
|
+
#
|
|
84
|
+
# It's started lazily, on first request, rather than eagerly in
|
|
85
|
+
# `initialize`, to stay correct under Puma's `preload_app!`: the app
|
|
86
|
+
# (and this middleware) is built once in the master process, which
|
|
87
|
+
# then fork()s a child process per cluster worker. OS threads do not
|
|
88
|
+
# survive fork - only the forking thread continues to exist in the
|
|
89
|
+
# child - so a thread started eagerly in `initialize` would already be
|
|
90
|
+
# dead in every forked worker. Starting on first request instead means
|
|
91
|
+
# each process (master or forked worker) creates its own worker thread
|
|
92
|
+
# the first time it actually handles a request, so every worker
|
|
93
|
+
# process naturally ends up owning exactly one live worker thread and
|
|
94
|
+
# one queue.
|
|
95
|
+
def start_worker
|
|
96
|
+
return if @worker&.alive?
|
|
97
|
+
|
|
98
|
+
@worker_mutex.synchronize do
|
|
99
|
+
return if @worker&.alive?
|
|
100
|
+
|
|
101
|
+
@worker = Thread.new { process_queue }
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Runs on the single worker thread only. `client` and `write_api` are
|
|
106
|
+
# therefore each created exactly once, lazily, with no need for extra
|
|
107
|
+
# synchronization: nothing else ever touches them.
|
|
108
|
+
def process_queue
|
|
109
|
+
loop do
|
|
110
|
+
data = @queue.pop
|
|
111
|
+
# `pop` only returns nil once the queue has been closed (see
|
|
112
|
+
# #shutdown) and fully drained, which is our signal to stop.
|
|
113
|
+
break if data.nil?
|
|
114
|
+
|
|
115
|
+
write_api.write(data: data)
|
|
116
|
+
rescue StandardError => e
|
|
117
|
+
config.handle_error.call(e)
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
51
121
|
def point(env, response)
|
|
52
122
|
{
|
|
53
123
|
name: config.name,
|
|
54
124
|
tags: config.tags,
|
|
125
|
+
time: (Time.now.to_r * 1_000_000_000).to_i,
|
|
55
126
|
fields: config.fields.call(env, response)
|
|
56
127
|
}
|
|
57
128
|
end
|
|
58
129
|
|
|
130
|
+
def write_api
|
|
131
|
+
@write_api ||= client.create_write_api(write_options: config.write_options)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def client
|
|
135
|
+
@client ||= InfluxDB2::Client.new(
|
|
136
|
+
config.url, config.token, **config.options
|
|
137
|
+
)
|
|
138
|
+
end
|
|
139
|
+
|
|
59
140
|
def config
|
|
60
141
|
Rack::InfluxDB.configuration
|
|
61
142
|
end
|
data/spec/rack_influxdb_spec.rb
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require_relative './spec_helper'
|
|
4
|
+
require 'weakref'
|
|
2
5
|
|
|
3
6
|
RSpec.describe Rack::InfluxDB do
|
|
4
7
|
describe '.configuration' do
|
|
@@ -32,10 +35,6 @@ RSpec.describe Rack::InfluxDB do
|
|
|
32
35
|
end
|
|
33
36
|
|
|
34
37
|
describe '#call' do
|
|
35
|
-
before do
|
|
36
|
-
allow(Thread).to receive(:new).and_yield
|
|
37
|
-
end
|
|
38
|
-
|
|
39
38
|
it 'returns the initial status code' do
|
|
40
39
|
get '/'
|
|
41
40
|
|
|
@@ -49,41 +48,121 @@ RSpec.describe Rack::InfluxDB do
|
|
|
49
48
|
end
|
|
50
49
|
|
|
51
50
|
context 'when no config token is given' do
|
|
52
|
-
it 'does not call InfluxDB2::Client.
|
|
53
|
-
expect(InfluxDB2::Client).not_to receive(:
|
|
51
|
+
it 'does not call InfluxDB2::Client.new' do
|
|
52
|
+
expect(InfluxDB2::Client).not_to receive(:new)
|
|
54
53
|
|
|
55
54
|
get '/'
|
|
56
55
|
end
|
|
57
56
|
end
|
|
58
57
|
|
|
59
58
|
context 'when config token is given' do
|
|
59
|
+
let(:conf) { described_class.configuration }
|
|
60
|
+
let(:influx_client) { double('InfluxDB2::Client') }
|
|
61
|
+
let(:write_api) { double('InfluxDB2::WriteApi') }
|
|
62
|
+
let(:write_calls) { [] }
|
|
63
|
+
let(:write_mutex) { Mutex.new }
|
|
64
|
+
|
|
60
65
|
before do
|
|
61
|
-
allow(InfluxDB2::Client).to receive(:
|
|
66
|
+
allow(InfluxDB2::Client).to receive(:new).and_return(influx_client)
|
|
67
|
+
allow(influx_client).to receive(:create_write_api).and_return(write_api)
|
|
68
|
+
allow(write_api).to receive(:write) do |data:|
|
|
69
|
+
write_mutex.synchronize { write_calls << data }
|
|
70
|
+
end
|
|
62
71
|
|
|
63
72
|
described_class.configure do |config|
|
|
64
|
-
config.token =
|
|
65
|
-
config.url =
|
|
73
|
+
config.token = 'token'
|
|
74
|
+
config.url = 'example.com'
|
|
66
75
|
end
|
|
67
76
|
end
|
|
68
77
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
it 'calls InfluxDB2::Client.use with right params' do
|
|
78
|
+
it 'calls InfluxDB2::Client.new with right params' do
|
|
72
79
|
get '/'
|
|
73
80
|
|
|
81
|
+
wait_for { write_calls.any? }
|
|
82
|
+
|
|
74
83
|
expect(InfluxDB2::Client)
|
|
75
|
-
.to have_received(:
|
|
84
|
+
.to have_received(:new)
|
|
76
85
|
.with(conf.url, conf.token, conf.options)
|
|
77
86
|
end
|
|
87
|
+
|
|
88
|
+
it 'writes a data point to InfluxDB' do
|
|
89
|
+
get '/'
|
|
90
|
+
|
|
91
|
+
wait_for { write_calls.any? }
|
|
92
|
+
|
|
93
|
+
expect(write_calls).to include(hash_including(name: conf.name))
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it 'reuses the same write API instead of creating a new one per request' do
|
|
97
|
+
middleware = described_class.new(->(_env) { [200, {}, ['Hello World']] })
|
|
98
|
+
|
|
99
|
+
2.times { middleware.call(Rack::MockRequest.env_for('/')) }
|
|
100
|
+
|
|
101
|
+
wait_for { write_calls.size >= 2 }
|
|
102
|
+
|
|
103
|
+
expect(influx_client).to have_received(:create_write_api).once
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it 'returns the response without waiting for the write to InfluxDB' do
|
|
107
|
+
allow(write_api).to receive(:write) do |data:|
|
|
108
|
+
sleep 0.3
|
|
109
|
+
write_mutex.synchronize { write_calls << data }
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
middleware = described_class.new(->(_env) { [200, {}, ['Hello World']] })
|
|
113
|
+
|
|
114
|
+
started_at = Time.now
|
|
115
|
+
middleware.call(Rack::MockRequest.env_for('/'))
|
|
116
|
+
elapsed = Time.now - started_at
|
|
117
|
+
|
|
118
|
+
expect(elapsed).to be < 0.1
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it 'creates exactly one worker thread no matter how many requests come in' do
|
|
122
|
+
thread_count = 0
|
|
123
|
+
thread_count_mutex = Mutex.new
|
|
124
|
+
allow(Thread).to receive(:new).and_wrap_original do |original, *args, &block|
|
|
125
|
+
thread_count_mutex.synchronize { thread_count += 1 }
|
|
126
|
+
original.call(*args, &block)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
middleware = described_class.new(->(_env) { [200, {}, ['Hello World']] })
|
|
130
|
+
5.times { middleware.call(Rack::MockRequest.env_for('/')) }
|
|
131
|
+
|
|
132
|
+
wait_for { write_calls.size >= 5 }
|
|
133
|
+
|
|
134
|
+
expect(thread_count).to eq(1)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it 'does not retain the Rack env after the worker has processed it' do
|
|
138
|
+
middleware = described_class.new(->(_env) { [200, {}, ['Hello World']] })
|
|
139
|
+
|
|
140
|
+
# Building the env and the WeakRef inside a lambda, rather than in
|
|
141
|
+
# local variables of the example itself, lets `env` fall out of
|
|
142
|
+
# scope (and become eligible for GC) as soon as the lambda returns.
|
|
143
|
+
weak_env = lambda do
|
|
144
|
+
env = Rack::MockRequest.env_for('/')
|
|
145
|
+
ref = WeakRef.new(env)
|
|
146
|
+
middleware.call(env)
|
|
147
|
+
ref
|
|
148
|
+
end.call
|
|
149
|
+
|
|
150
|
+
wait_for { write_calls.any? }
|
|
151
|
+
GC.start
|
|
152
|
+
|
|
153
|
+
# `weakref_alive?` is falsy (nil or false, depending on Ruby version)
|
|
154
|
+
# once the referenced object has been collected.
|
|
155
|
+
expect(weak_env.weakref_alive?).to be_falsey
|
|
156
|
+
end
|
|
78
157
|
end
|
|
79
158
|
|
|
80
159
|
context 'when an error occurs' do
|
|
81
160
|
before do
|
|
82
|
-
allow(InfluxDB2::Client).to receive(:
|
|
161
|
+
allow(InfluxDB2::Client).to receive(:new).and_raise('Could not write')
|
|
83
162
|
|
|
84
163
|
described_class.configure do |config|
|
|
85
|
-
config.token =
|
|
86
|
-
config.url =
|
|
164
|
+
config.token = 'token'
|
|
165
|
+
config.url = 'example.com'
|
|
87
166
|
end
|
|
88
167
|
end
|
|
89
168
|
|
|
@@ -98,14 +177,21 @@ RSpec.describe Rack::InfluxDB do
|
|
|
98
177
|
end
|
|
99
178
|
|
|
100
179
|
context 'when custom error handling is applied' do
|
|
101
|
-
|
|
180
|
+
it 'passes the raised error to the custom error handler' do
|
|
181
|
+
handled_errors = []
|
|
182
|
+
handled_mutex = Mutex.new
|
|
183
|
+
|
|
102
184
|
described_class.configure do |config|
|
|
103
|
-
config.handle_error =
|
|
185
|
+
config.handle_error = lambda do |e|
|
|
186
|
+
handled_mutex.synchronize { handled_errors << e }
|
|
187
|
+
end
|
|
104
188
|
end
|
|
105
|
-
end
|
|
106
189
|
|
|
107
|
-
|
|
108
|
-
|
|
190
|
+
get '/'
|
|
191
|
+
|
|
192
|
+
wait_for { handled_errors.any? }
|
|
193
|
+
|
|
194
|
+
expect(handled_errors.first.message).to eq('Could not write')
|
|
109
195
|
end
|
|
110
196
|
end
|
|
111
197
|
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'simplecov'
|
|
4
|
+
require 'simplecov-cobertura'
|
|
5
|
+
|
|
6
|
+
SimpleCov.formatter = SimpleCov::Formatter::CoberturaFormatter
|
|
7
|
+
SimpleCov.start
|
|
8
|
+
|
|
1
9
|
require 'bundler/setup'
|
|
2
10
|
|
|
3
11
|
require 'rack'
|
|
@@ -10,10 +18,23 @@ def app
|
|
|
10
18
|
# Include the InfluxDB middleware.
|
|
11
19
|
use Rack::InfluxDB
|
|
12
20
|
|
|
13
|
-
run
|
|
21
|
+
run ->(_env) { [200, {}, ['Hello World']] }
|
|
14
22
|
end.to_app
|
|
15
23
|
end
|
|
16
24
|
|
|
25
|
+
# Polls `block` until it returns truthy, or raises after `timeout` seconds.
|
|
26
|
+
# Used to synchronize with work happening on the middleware's background
|
|
27
|
+
# worker thread without coupling tests to sleep durations.
|
|
28
|
+
def wait_for(timeout: 2)
|
|
29
|
+
deadline = Time.now + timeout
|
|
30
|
+
|
|
31
|
+
until yield
|
|
32
|
+
raise "wait_for timed out after #{timeout}s" if Time.now > deadline
|
|
33
|
+
|
|
34
|
+
sleep 0.01
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
17
38
|
RSpec.configure do |config|
|
|
18
39
|
config.include Rack::Test::Methods
|
|
19
40
|
|
metadata
CHANGED
|
@@ -1,35 +1,42 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rack-influxdb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Henning Vogt
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name:
|
|
13
|
+
name: base64
|
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
|
16
15
|
requirements:
|
|
17
16
|
- - ">="
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
20
|
-
- - "<"
|
|
21
|
-
- !ruby/object:Gem::Version
|
|
22
|
-
version: '4'
|
|
18
|
+
version: '0'
|
|
23
19
|
type: :runtime
|
|
24
20
|
prerelease: false
|
|
25
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
26
22
|
requirements:
|
|
27
23
|
- - ">="
|
|
28
24
|
- !ruby/object:Gem::Version
|
|
29
|
-
version: '
|
|
30
|
-
|
|
25
|
+
version: '0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: csv
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: '
|
|
32
|
+
version: '0'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '0'
|
|
33
40
|
- !ruby/object:Gem::Dependency
|
|
34
41
|
name: influxdb-client
|
|
35
42
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -44,6 +51,40 @@ dependencies:
|
|
|
44
51
|
- - ">="
|
|
45
52
|
- !ruby/object:Gem::Version
|
|
46
53
|
version: '3'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: logger
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0'
|
|
61
|
+
type: :runtime
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '0'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: rack
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '1.0'
|
|
75
|
+
- - "<"
|
|
76
|
+
- !ruby/object:Gem::Version
|
|
77
|
+
version: '4'
|
|
78
|
+
type: :runtime
|
|
79
|
+
prerelease: false
|
|
80
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
81
|
+
requirements:
|
|
82
|
+
- - ">="
|
|
83
|
+
- !ruby/object:Gem::Version
|
|
84
|
+
version: '1.0'
|
|
85
|
+
- - "<"
|
|
86
|
+
- !ruby/object:Gem::Version
|
|
87
|
+
version: '4'
|
|
47
88
|
- !ruby/object:Gem::Dependency
|
|
48
89
|
name: bundler
|
|
49
90
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -124,7 +165,6 @@ homepage: https://github.com/heychimpy/rack-influxdb
|
|
|
124
165
|
licenses:
|
|
125
166
|
- MIT
|
|
126
167
|
metadata: {}
|
|
127
|
-
post_install_message:
|
|
128
168
|
rdoc_options: []
|
|
129
169
|
require_paths:
|
|
130
170
|
- lib
|
|
@@ -132,15 +172,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
132
172
|
requirements:
|
|
133
173
|
- - ">="
|
|
134
174
|
- !ruby/object:Gem::Version
|
|
135
|
-
version: '
|
|
175
|
+
version: '3.0'
|
|
136
176
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
177
|
requirements:
|
|
138
178
|
- - ">="
|
|
139
179
|
- !ruby/object:Gem::Version
|
|
140
180
|
version: '0'
|
|
141
181
|
requirements: []
|
|
142
|
-
rubygems_version:
|
|
143
|
-
signing_key:
|
|
182
|
+
rubygems_version: 4.0.11
|
|
144
183
|
specification_version: 4
|
|
145
184
|
summary: Log HTTP requests to InfluxDB
|
|
146
185
|
test_files:
|