influxdb 0.3.17 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6340af963bab464fd867383a9cc807e05595df17
4
- data.tar.gz: 4e6de52c3d235ea4ecef32ec208cd37bf713452f
3
+ metadata.gz: 2b441a52f7c991073a898e33debc4844e21c4fab
4
+ data.tar.gz: d5b4e6eb7b16e760fa2ead3e3ae104e743aad45d
5
5
  SHA512:
6
- metadata.gz: 75666cbccc4d308b0eb75608047041095f78158201c6e9e994bfd41e8e3450826b94f759f56f65f526d042befa73ceb9c0db443aa4d2925f72828fbee8c928b5
7
- data.tar.gz: e0665e344e62644e9e53534eefb9ff26530e7d7aaaf121edd321c5f070bba0aa9894c02b38a8ce28d24b444e475a7860c13c25a90653600f126b050011c64364
6
+ metadata.gz: d8933fc82bca429acb600186ba3c42e946b071d138a231e86f0344d6a28f0f6cbf55ba14419c49c32a531a3112dff47ff96cf2e9be03a2a99e8265c3b1a1bd59
7
+ data.tar.gz: 2b5a07855185ccefd02948b4889838944901dc13cb4e3142ab1a5eeda639f465021659aa42f4764b11339df65b1ce18c6c0f3d27005da804b3e45ded73acdd85
@@ -7,9 +7,10 @@ AllCops:
7
7
  Exclude:
8
8
  - 'bin/**/*'
9
9
  - 'smoke/**/*'
10
+ - 'Gemfile'
10
11
  DisplayCopNames: true
11
12
  StyleGuideCopsOnly: false
12
- TargetRubyVersion: 1.9
13
+ TargetRubyVersion: 2.2
13
14
 
14
15
  Rails:
15
16
  Enabled: false
@@ -31,6 +32,10 @@ Metrics/LineLength:
31
32
  Exclude:
32
33
  - 'spec/**/*.rb'
33
34
 
35
+ Metrics/BlockLength:
36
+ Exclude:
37
+ - 'spec/**/*.rb'
38
+
34
39
  Metrics/ModuleLength:
35
40
  CountComments: false # count full line comments?
36
41
  Max: 120
@@ -42,3 +47,6 @@ Style/TrailingCommaInLiteral:
42
47
 
43
48
  Metrics/AbcSize:
44
49
  Max: 20
50
+
51
+ Style/FormatStringToken:
52
+ Enabled: false
@@ -7,12 +7,9 @@ before_install:
7
7
  - gem update bundler --no-doc
8
8
  - smoke/provision.sh
9
9
  rvm:
10
- - 1.9.3
11
- - 2.0.0
12
- - 2.1.10
13
10
  - 2.2.7
14
- - 2.3.5
15
- - 2.4.2
11
+ - 2.3.4
12
+ - 2.4.1
16
13
  - ruby-head
17
14
  env:
18
15
  - TEST_TASK=spec
@@ -22,23 +19,23 @@ matrix:
22
19
  - rvm: jruby-head
23
20
  - rvm: ruby-head
24
21
  - rvm: jruby-9.1.5.0
25
- - rvm: 2.4.2
22
+ - rvm: 2.4.1
26
23
  env: TEST_TASK=smoke influx_version=nightly channel=nightlies
27
24
  include:
28
- - rvm: 2.4.2
25
+ - rvm: 2.4.1
29
26
  env: TEST_TASK=rubocop
30
27
  - rvm: jruby-9.1.5.0
31
28
  - rvm: jruby-head
32
29
  env: JRUBY_OPTS='--client -J-XX:+TieredCompilation -J-XX:TieredStopAtLevel=1 -J-Xss2m -J-Xmx256M'
33
- - rvm: 2.4.2
30
+ - rvm: 2.4.1
34
31
  env: TEST_TASK=smoke influx_version=1.0.2 pkghash=3e4c349cb57507913d9abda1459bdbed
35
- - rvm: 2.4.2
32
+ - rvm: 2.4.1
36
33
  env: TEST_TASK=smoke influx_version=1.1.0 pkghash=682904c350ecfc2a60ec9c6c08453ef2
37
- - rvm: 2.4.2
34
+ - rvm: 2.4.1
38
35
  env: TEST_TASK=smoke influx_version=1.2.4 pkghash=0545d67217393282188e5d5cdedfdc85
39
- - rvm: 2.4.2
40
- env: TEST_TASK=smoke influx_version=1.3.5 pkghash=479c63bbb66561c302aff2d9bf639bf3
41
- - rvm: 2.4.2
36
+ - rvm: 2.4.1
37
+ env: TEST_TASK=smoke influx_version=1.3.2 pkghash=27b200344bed9de9df193b62a59d378f
38
+ - rvm: 2.4.1
42
39
  env: TEST_TASK=smoke influx_version=nightly channel=nightlies
43
40
  fail_fast: true
44
41
  addons:
@@ -2,21 +2,19 @@
2
2
 
3
3
  For the full commit log, [see here](https://github.com/influxdata/influxdb-ruby/commits/master).
4
4
 
5
- ## Unreleased changes
5
+ ## v0.4.0 (unreleased)
6
6
 
7
- - nothing yet
8
-
9
- ## v0.3.17, released 2017-09-27
10
-
11
- - (Backport from v0.4.1) Bugfix in async client: Flush queue before exit
12
- (#198, #199 @onlynone)
13
- - (Backport from v0.4.2) Bugfix in `InfluxDB::PointValue`: Properly
14
- encode backslashes (#200)
7
+ - **Dropped support for Ruby < 2.2.**
8
+ - Updated dependencies.
9
+ - Refactor some method declarations, to take kwargs instead of an
10
+ options hash (this shouldn't break call sites).
11
+ - Allow configuration by an URL (idea by @carlhoerberg in #188).
12
+ - Improved logging (#180).
15
13
 
16
14
  ## v0.3.16, released 2017-08-17
17
15
 
18
- - **This is propably the last release in the 0.3.x series**
19
- - Typo fix in README (#196, @MichaelSp)
16
+ - **This is propably the last release in the 0.3.x series.**
17
+ - Typo fix in README (#196, @MichaelSp).
20
18
 
21
19
  ## v0.3.15, released 2017-07-17
22
20
 
data/Gemfile CHANGED
@@ -1,10 +1,5 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- if RUBY_ENGINE != "jruby" && RUBY_VERSION < "2.0"
4
- gem "json", "~> 1.8.3"
5
- gem "public_suffix", "< 1.5"
6
- end
7
-
8
3
  gemspec
9
4
 
10
5
  local_gemfile = 'Gemfile.local'
data/README.md CHANGED
@@ -24,6 +24,7 @@ Maintained by [@toddboom](https://github.com/toddboom) and [@dmke](https://githu
24
24
  - [De-normalization](#de--normalization)
25
25
  - [Streaming response](#streaming-response)
26
26
  - [Retry](#retry)
27
+ - [List of configuration options](#list-of-configuration-options)
27
28
  - [Testing](#testing)
28
29
  - [Contributing](#contributing)
29
30
 
@@ -38,14 +39,9 @@ Maintained by [@toddboom](https://github.com/toddboom) and [@dmke](https://githu
38
39
 
39
40
  ## Ruby support
40
41
 
41
- Up to and including version 0.3.x, this gem will work with Ruby 1.9+. Starting
42
- with 0.4.0, only Ruby 2.2+ will be supported.
43
-
44
- To read the documentation for 0.3.x, see the [stable-03 branch](https://github.com/influxdata/influxdb-ruby/tree/stable-03).
45
-
46
- Please note that for Ruby 1.9, you'll need to install the JSON gem in version
47
- 1.8.x yourself, for example by pinning the version in your `Gemfile` (i.e.
48
- `gem "json", "~> 1.8.3"`).
42
+ Since v0.4.0, this gem requires Ruby >= 2.2.0. Support for MRI < 2.2 is
43
+ still available in the v0.3.x series, see [stable-03 branch](https://github.com/influxdata/influxdb-ruby/tree/stable-03)
44
+ for documentation.
49
45
 
50
46
  ## Installation
51
47
 
@@ -57,26 +53,45 @@ Or add it to your `Gemfile`, and run `bundle install`.
57
53
 
58
54
  ## Usage
59
55
 
56
+ *All examples assume you have a `require "influxdb"` in your code.*
57
+
60
58
  ### Creating a client
61
59
 
62
60
  Connecting to a single host:
63
61
 
64
62
  ``` ruby
65
- require 'influxdb'
63
+ influxdb = InfluxDB::Client.new # default connects to localhost:8086
66
64
 
67
- influxdb = InfluxDB::Client.new host: "influxdb.domain.com"
68
65
  # or
69
- influxdb = InfluxDB::Client.new # no host given defaults connecting to localhost
66
+ influxdb = InfluxDB::Client.new host: "influxdb.domain.com"
70
67
  ```
71
68
 
72
69
  Connecting to multiple hosts (with built-in load balancing and failover):
73
70
 
74
71
  ``` ruby
75
- require 'influxdb'
76
-
77
72
  influxdb = InfluxDB::Client.new hosts: ["influxdb1.domain.com", "influxdb2.domain.com"]
78
73
  ```
79
74
 
75
+ #### Using a configuration URL
76
+
77
+ You can also provide a URL to connect to your server. This is particulary
78
+ useful for 12-factor apps, i.e. you can put the configuration in an environment
79
+ variable:
80
+
81
+ ``` ruby
82
+ url = ENV["INFLUXDB_URL"] || "https://influxdb.example.com:8086/database_name?retry=3"
83
+ influxdb = InfluxDB::Client.new url: url
84
+ ```
85
+
86
+ Please note, that the config options found in the URL have a lower precedence
87
+ than those explicitly given in the options hash. This means, that the following
88
+ sample will use an open-timeout of 10 seconds:
89
+
90
+ ``` ruby
91
+ url = "https://influxdb.example.com:8086/database_name?open_timeout=3"
92
+ influxdb = InfluxDB::Client.new url: url, open_timeout: 10
93
+ ```
94
+
80
95
  ### Writing data
81
96
 
82
97
  Write some data:
@@ -107,8 +122,6 @@ end
107
122
  Write data with time precision (precision can be set in 2 ways):
108
123
 
109
124
  ``` ruby
110
- require 'influxdb'
111
-
112
125
  username = 'foo'
113
126
  password = 'bar'
114
127
  database = 'site_development'
@@ -263,6 +276,7 @@ data = {
263
276
  influxdb.write_point(name, data)
264
277
  ```
265
278
 
279
+ <a name="async-options"></a>
266
280
  Using `async: true` is a shortcut for the following:
267
281
 
268
282
  ``` ruby
@@ -281,6 +295,7 @@ async_options = {
281
295
  influxdb = InfluxDB::Client.new database, async: async_options
282
296
  ```
283
297
 
298
+ <a name="udp-options"></a>
284
299
  Write data via UDP (note that a retention policy cannot be specified for UDP writes):
285
300
 
286
301
  ``` ruby
@@ -671,17 +686,46 @@ $ irb -r influxdb
671
686
  => #<InfluxDB::Client:0x00000002bb5ce0 ...>
672
687
 
673
688
  > influxdb.query 'select * from serie limit 1'
674
- E, [2016-08-31T23:55:18.287947 #23476] ERROR -- InfluxDB: Failed to contact host localhost: #<Errno::ECONNREFUSED: Failed to open TCP connection to localhost:8086 (Connection refused - connect(2) for "localhost" port 8086)> - retrying in 0.01s.
675
- E, [2016-08-31T23:55:18.298455 #23476] ERROR -- InfluxDB: Failed to contact host localhost: #<Errno::ECONNREFUSED: Failed to open TCP connection to localhost:8086 (Connection refused - connect(2) for "localhost" port 8086)> - retrying in 0.02s.
676
- E, [2016-08-31T23:55:18.319122 #23476] ERROR -- InfluxDB: Failed to contact host localhost: #<Errno::ECONNREFUSED: Failed to open TCP connection to localhost:8086 (Connection refused - connect(2) for "localhost" port 8086)> - retrying in 0.04s.
677
- E, [2016-08-31T23:55:18.359785 #23476] ERROR -- InfluxDB: Failed to contact host localhost: #<Errno::ECONNREFUSED: Failed to open TCP connection to localhost:8086 (Connection refused - connect(2) for "localhost" port 8086)> - retrying in 0.08s.
678
- E, [2016-08-31T23:55:18.440422 #23476] ERROR -- InfluxDB: Failed to contact host localhost: #<Errno::ECONNREFUSED: Failed to open TCP connection to localhost:8086 (Connection refused - connect(2) for "localhost" port 8086)> - retrying in 0.16s.
679
- E, [2016-08-31T23:55:18.600936 #23476] ERROR -- InfluxDB: Failed to contact host localhost: #<Errno::ECONNREFUSED: Failed to open TCP connection to localhost:8086 (Connection refused - connect(2) for "localhost" port 8086)> - retrying in 0.32s.
680
- E, [2016-08-31T23:55:18.921740 #23476] ERROR -- InfluxDB: Failed to contact host localhost: #<Errno::ECONNREFUSED: Failed to open TCP connection to localhost:8086 (Connection refused - connect(2) for "localhost" port 8086)> - retrying in 0.64s.
681
- E, [2016-08-31T23:55:19.562428 #23476] ERROR -- InfluxDB: Failed to contact host localhost: #<Errno::ECONNREFUSED: Failed to open TCP connection to localhost:8086 (Connection refused - connect(2) for "localhost" port 8086)> - retrying in 1.28s.
689
+ E, [2016-08-31T23:55:18.287947 #23476] WARN -- InfluxDB: Failed to contact host localhost: #<Errno::ECONNREFUSED: Failed to open TCP connection to localhost:8086 (Connection refused - connect(2) for "localhost" port 8086)> - retrying in 0.01s.
690
+ E, [2016-08-31T23:55:18.298455 #23476] WARN -- InfluxDB: Failed to contact host localhost: #<Errno::ECONNREFUSED: Failed to open TCP connection to localhost:8086 (Connection refused - connect(2) for "localhost" port 8086)> - retrying in 0.02s.
691
+ E, [2016-08-31T23:55:18.319122 #23476] WARN -- InfluxDB: Failed to contact host localhost: #<Errno::ECONNREFUSED: Failed to open TCP connection to localhost:8086 (Connection refused - connect(2) for "localhost" port 8086)> - retrying in 0.04s.
692
+ E, [2016-08-31T23:55:18.359785 #23476] WARN -- InfluxDB: Failed to contact host localhost: #<Errno::ECONNREFUSED: Failed to open TCP connection to localhost:8086 (Connection refused - connect(2) for "localhost" port 8086)> - retrying in 0.08s.
693
+ E, [2016-08-31T23:55:18.440422 #23476] WARN -- InfluxDB: Failed to contact host localhost: #<Errno::ECONNREFUSED: Failed to open TCP connection to localhost:8086 (Connection refused - connect(2) for "localhost" port 8086)> - retrying in 0.16s.
694
+ E, [2016-08-31T23:55:18.600936 #23476] WARN -- InfluxDB: Failed to contact host localhost: #<Errno::ECONNREFUSED: Failed to open TCP connection to localhost:8086 (Connection refused - connect(2) for "localhost" port 8086)> - retrying in 0.32s.
695
+ E, [2016-08-31T23:55:18.921740 #23476] WARN -- InfluxDB: Failed to contact host localhost: #<Errno::ECONNREFUSED: Failed to open TCP connection to localhost:8086 (Connection refused - connect(2) for "localhost" port 8086)> - retrying in 0.64s.
696
+ E, [2016-08-31T23:55:19.562428 #23476] WARN -- InfluxDB: Failed to contact host localhost: #<Errno::ECONNREFUSED: Failed to open TCP connection to localhost:8086 (Connection refused - connect(2) for "localhost" port 8086)> - retrying in 1.28s.
682
697
  InfluxDB::ConnectionError: Tried 8 times to reconnect but failed.
683
698
  ```
684
699
 
700
+ ## List of configuration options
701
+
702
+ This index might be out of date. Please refer to `InfluxDB::DEFAULT_CONFIG_OPTIONS`,
703
+ found in `lib/influxdb/config.rb` for the source of truth.
704
+
705
+ | Category | Option | Default value | Notes
706
+ |:----------------|:------------------------|:--------------|:-----
707
+ | HTTP connection | `:host` or `:hosts` | "localhost" | can be an array and can include port
708
+ | | `:port` | 8086 | fallback port, unless provided by `:host` option
709
+ | | `:prefix` | "" | URL path prefix (e.g. server is behind reverse proxy)
710
+ | | `:username` | "root" | user credentials
711
+ | | `:password` | "root" | user credentials
712
+ | | `:open_timeout` | 5 | socket timeout
713
+ | | `:read_timeout` | 300 | socket timeout
714
+ | | `:auth_method` | "params" | "params", "basic_auth" or "none"
715
+ | Retry | `:retry` | -1 | max. number of retry attempts (reading and writing)
716
+ | | `:initial_delay` | 0.01 | initial wait time (doubles every retry attempt)
717
+ | | `:max_delay` | 30 | max. wait time when retrying
718
+ | SSL/HTTPS | `:use_ssl` | false | whether or not to use SSL (HTTPS)
719
+ | | `:verify_ssl` | true | verify vertificate when using SSL
720
+ | | `:ssl_ca_cert` | false | path to or name of CA cert
721
+ | Database | `:database` | *empty* | name of database
722
+ | | `:time_precision` | "s" | time resolution for data send to server
723
+ | | `:epoch` | false | time resolution for server responses (false = server default)
724
+ | Writer | `:async` | false | Async options hash, [details here](#async-options)
725
+ | | `:udp` | false | UDP connection info, [details here](#udp-options)
726
+ | | `:discard_write_errors` | false | suppress UDP socket errors
727
+ | Query | `:chunk_size` | *empty* | [details here](#streaming-response)
728
+ | | `:denormalize` | true | format of result
685
729
 
686
730
  ## Testing
687
731
 
data/Rakefile CHANGED
@@ -18,7 +18,7 @@ Rake::TestTask.new(:smoke) do |t|
18
18
  t.test_files = FileList["smoke/*.rb"]
19
19
  end
20
20
 
21
- task default: [:spec, :rubocop]
21
+ task default: %i[spec rubocop]
22
22
 
23
23
  task :console do
24
24
  lib = File.expand_path("../lib", __FILE__)
@@ -29,16 +29,17 @@ task :console do
29
29
  require "pry-byebug"
30
30
  Pry.start
31
31
  rescue LoadError
32
- puts <<-TEXT.gsub(/^\s{6}([^ ])/, "\1"), ""
33
- Could not load pry-byebug. Create a file Gemfile.local with
34
- the following line, if you want to get rid of this message:
35
-
36
- \tgem "pry-byebug"
37
-
38
- (don't forget to run bundle afterwards). Falling back to IRB.
39
- TEXT
32
+ puts \
33
+ "Could not load pry-byebug. Create a file Gemfile.local with",
34
+ "the following line, if you want to get rid of this message:",
35
+ "",
36
+ "\tgem \"pry-byebug\"",
37
+ "",
38
+ "(don't forget to run bundle afterwards). Falling back to IRB.",
39
+ ""
40
40
 
41
41
  require "irb"
42
+ require "irb/completion"
42
43
  ARGV.clear
43
44
  IRB.start
44
45
  end
@@ -1,4 +1,5 @@
1
1
  # coding: utf-8
2
+
2
3
  lib = File.expand_path('../lib', __FILE__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'influxdb/version'
@@ -19,13 +20,11 @@ Gem::Specification.new do |spec|
19
20
  spec.test_files = spec.files.grep(%r{^(test|spec|features|smoke)/})
20
21
  spec.require_paths = ["lib"]
21
22
 
22
- spec.add_runtime_dependency "json"
23
- spec.post_install_message = "Heads up: version 0.4 will drop support for MRI <= 2.1"
23
+ spec.required_ruby_version = ">= 2.2.0"
24
24
 
25
25
  spec.add_development_dependency "rake"
26
26
  spec.add_development_dependency "bundler", "~> 1.3"
27
- spec.add_development_dependency "rspec", "~> 3.5.0"
28
- spec.add_development_dependency "webmock", "~> 2.1.0"
29
- spec.add_development_dependency "rubocop", "~> 0.41.2"
30
- spec.add_development_dependency "cause"
27
+ spec.add_development_dependency "rspec", "~> 3.6"
28
+ spec.add_development_dependency "webmock", "~> 3.0"
29
+ spec.add_development_dependency "rubocop", "~> 0.49"
31
30
  end
@@ -49,23 +49,17 @@ module InfluxDB
49
49
  # +:ssl_ca_cert+:: ssl CA certificate, chainfile or CA path.
50
50
  # The system CA path is automatically included
51
51
  # +:retry:: number of times a failed request should be retried. Defaults to infinite.
52
- def initialize(*args)
53
- opts = args.last.is_a?(Hash) ? args.last : {}
54
- opts[:database] = args.first if args.first.is_a? String
52
+ def initialize(database = nil, **opts)
53
+ opts[:database] = database if database.is_a? String
55
54
  @config = InfluxDB::Config.new(opts)
56
55
  @stopped = false
57
56
  @writer = find_writer
58
57
 
59
- at_exit { stop! }
58
+ at_exit { stop! } if config.retry > 0
60
59
  end
61
60
 
62
61
  def stop!
63
- if config.async?
64
- # If retry was infinite (-1), set it to zero to give the main thread one
65
- # last chance to flush the queue
66
- config.retry = 0 if config.retry < 0
67
- writer.worker.stop!
68
- end
62
+ writer.worker.stop! if config.async?
69
63
  @stopped = true
70
64
  end
71
65
 
@@ -78,8 +72,10 @@ module InfluxDB
78
72
  def find_writer
79
73
  if config.async?
80
74
  InfluxDB::Writer::Async.new(self, config.async)
75
+ elsif config.udp.is_a?(Hash)
76
+ InfluxDB::Writer::UDP.new(self, **config.udp)
81
77
  elsif config.udp?
82
- InfluxDB::Writer::UDP.new(self, config.udp)
78
+ InfluxDB::Writer::UDP.new(self)
83
79
  else
84
80
  self
85
81
  end
@@ -51,7 +51,6 @@ module InfluxDB
51
51
 
52
52
  http = setup_ssl(http)
53
53
  yield http
54
-
55
54
  rescue *InfluxDB::NON_RECOVERABLE_EXCEPTIONS => e
56
55
  raise InfluxDB::ConnectionError, InfluxDB::NON_RECOVERABLE_MESSAGE
57
56
  rescue Timeout::Error, *InfluxDB::RECOVERABLE_EXCEPTIONS => e
@@ -59,7 +58,7 @@ module InfluxDB
59
58
  unless (config.retry == -1 || retry_count <= config.retry) && !stopped?
60
59
  raise InfluxDB::ConnectionError, "Tried #{retry_count - 1} times to reconnect but failed."
61
60
  end
62
- log :error, "Failed to contact host #{host}: #{e.inspect} - retrying in #{delay}s."
61
+ log(:warn) { "Failed to contact host #{host}: #{e.inspect} - retrying in #{delay}s." }
63
62
  sleep delay
64
63
  delay = [config.max_delay, delay * 2].min
65
64
  retry
@@ -1,40 +1,83 @@
1
- require 'thread'
1
+ require "thread"
2
+ require "uri"
2
3
 
3
4
  module InfluxDB
5
+ # DEFAULT_CONFIG_OPTIONS maps (most) of the configuration options to
6
+ # their default value. Each option (except for "async" and "udp") can
7
+ # be changed at runtime throug the InfluxDB::Client instance.
8
+ #
9
+ # If you need to change the writer to be asynchronuous or use UDP, you
10
+ # need to get a new InfluxDB::Client instance.
11
+ DEFAULT_CONFIG_OPTIONS = {
12
+ # HTTP connection options
13
+ port: 8086,
14
+ prefix: "".freeze,
15
+ username: "root".freeze,
16
+ password: "root".freeze,
17
+ open_timeout: 5,
18
+ read_timeout: 300,
19
+ auth_method: nil,
20
+
21
+ # SSL options
22
+ use_ssl: false,
23
+ verify_ssl: true,
24
+ ssl_ca_cert: false,
25
+
26
+ # Database options
27
+ database: nil,
28
+ time_precision: "s".freeze,
29
+ epoch: false,
30
+
31
+ # Writer options
32
+ async: false,
33
+ udp: false,
34
+ discard_write_errors: false,
35
+
36
+ # Retry options
37
+ retry: -1,
38
+ max_delay: 30,
39
+ initial_delay: 0.01,
40
+
41
+ # Query options
42
+ chunk_size: nil,
43
+ denormalize: true,
44
+ }.freeze
45
+
4
46
  # InfluxDB client configuration
5
47
  class Config
6
- AUTH_METHODS = ["params".freeze, "basic_auth".freeze, "none".freeze].freeze
7
-
8
- attr_accessor :port,
9
- :username,
10
- :password,
11
- :database,
12
- :time_precision,
13
- :use_ssl,
14
- :verify_ssl,
15
- :ssl_ca_cert,
16
- :auth_method,
17
- :initial_delay,
18
- :max_delay,
19
- :open_timeout,
20
- :read_timeout,
21
- :retry,
22
- :prefix,
23
- :chunk_size,
24
- :denormalize,
25
- :epoch,
26
- :discard_write_errors
27
-
28
- attr_reader :async, :udp
29
-
30
- def initialize(opts = {})
31
- extract_http_options!(opts)
32
- extract_ssl_options!(opts)
33
- extract_database_options!(opts)
34
- extract_writer_options!(opts)
35
- extract_query_options!(opts)
36
-
37
- configure_retry! opts.fetch(:retry, nil)
48
+ # Valid values for the "auth_method" option.
49
+ AUTH_METHODS = [
50
+ "params".freeze,
51
+ "basic_auth".freeze,
52
+ "none".freeze,
53
+ ].freeze
54
+
55
+ ATTR_READER = %i[async udp].freeze
56
+ private_constant :ATTR_READER
57
+
58
+ ATTR_ACCESSOR = (DEFAULT_CONFIG_OPTIONS.keys - ATTR_READER).freeze
59
+ private_constant :ATTR_ACCESSOR
60
+
61
+ attr_reader(*ATTR_READER)
62
+ attr_accessor(*ATTR_ACCESSOR)
63
+
64
+ # Creates a new instance. See `DEFAULT_CONFIG_OPTIONS` for available
65
+ # config options and their default values.
66
+ #
67
+ # If you provide a "url" option, either as String (hint: ENV) or as
68
+ # URI instance, you can override the defaults. The precedence for a
69
+ # config value is as follows (first found wins):
70
+ #
71
+ # - values given in the options hash
72
+ # - values found in URL (if given)
73
+ # - default values
74
+ def initialize(url: nil, **opts)
75
+ opts = opts_from_url(url).merge(opts) if url
76
+
77
+ DEFAULT_CONFIG_OPTIONS.each do |name, value|
78
+ set_ivar! name, opts.fetch(name, value)
79
+ end
80
+
38
81
  configure_hosts! opts[:hosts] || opts[:host] || "localhost".freeze
39
82
  end
40
83
 
@@ -62,34 +105,22 @@ module InfluxDB
62
105
 
63
106
  private
64
107
 
65
- def extract_http_options!(opts)
66
- @port = opts.fetch :port, 8086
67
- @prefix = opts.fetch :prefix, "".freeze
68
- @username = opts.fetch :username, "root".freeze
69
- @password = opts.fetch :password, "root".freeze
70
- @open_timeout = opts.fetch :write_timeout, 5
71
- @read_timeout = opts.fetch :read_timeout, 300
72
- @max_delay = opts.fetch :max_delay, 30
73
- @initial_delay = opts.fetch :initial_delay, 0.01
74
- auth = opts[:auth_method]
75
- @auth_method = AUTH_METHODS.include?(auth) ? auth : "params".freeze
76
- end
108
+ def set_ivar!(name, value)
109
+ case name
110
+ when :auth_method
111
+ value = "params".freeze unless AUTH_METHODS.include?(value)
112
+ when :retry
113
+ value = normalize_retry_option(value)
114
+ end
77
115
 
78
- def extract_ssl_options!(opts)
79
- @use_ssl = opts.fetch :use_ssl, false
80
- @verify_ssl = opts.fetch :verify_ssl, true
81
- @ssl_ca_cert = opts.fetch :ssl_ca_cert, false
116
+ instance_variable_set "@#{name}", value
82
117
  end
83
118
 
84
- # normalize retry option
85
- def configure_retry!(value)
119
+ def normalize_retry_option(value)
86
120
  case value
87
- when Integer
88
- @retry = value
89
- when true, nil
90
- @retry = -1
91
- when false
92
- @retry = 0
121
+ when Integer then value
122
+ when true, nil then -1
123
+ when false then 0
93
124
  end
94
125
  end
95
126
 
@@ -101,21 +132,58 @@ module InfluxDB
101
132
  end
102
133
  end
103
134
 
104
- def extract_database_options!(opts)
105
- @database = opts[:database]
106
- @time_precision = opts.fetch :time_precision, "s".freeze
107
- @denormalize = opts.fetch :denormalize, true
108
- @epoch = opts.fetch :epoch, false
135
+ # merges URI options into opts
136
+ def opts_from_url(url)
137
+ url = URI.parse(url) unless url.is_a?(URI)
138
+ opts_from_non_params(url).merge opts_from_params(url.query)
139
+ rescue URI::InvalidURIError
140
+ {}
109
141
  end
110
142
 
111
- def extract_writer_options!(opts)
112
- @async = opts.fetch :async, false
113
- @udp = opts.fetch :udp, false
114
- @discard_write_errors = opts.fetch :discard_write_errors, false
143
+ # rubocop:disable Metrics/AbcSize
144
+ # rubocop:disable Metrics/CyclomaticComplexity
145
+
146
+ def opts_from_non_params(url)
147
+ {}.tap do |o|
148
+ o[:host] = url.host if url.host
149
+ o[:port] = url.port if url.port
150
+ o[:username] = url.user if url.user
151
+ o[:password] = url.password if url.password
152
+ o[:database] = url.path[1..-1] if url.path.length > 1
153
+ o[:use_ssl] = url.scheme == "https".freeze
154
+
155
+ o[:udp] = { host: o[:host], port: o[:port] } if url.scheme == "udp"
156
+ end
115
157
  end
116
158
 
117
- def extract_query_options!(opts)
118
- @chunk_size = opts.fetch :chunk_size, nil
159
+ # rubocop:enable Metrics/AbcSize
160
+ # rubocop:enable Metrics/CyclomaticComplexity
161
+
162
+ OPTIONS_FROM_PARAMS = (DEFAULT_CONFIG_OPTIONS.keys - %i[
163
+ host port username password database use_ssl udp
164
+ ]).freeze
165
+ private_constant :OPTIONS_FROM_PARAMS
166
+
167
+ def opts_from_params(query)
168
+ params = CGI.parse(query || "").tap { |h| h.default = [] }
169
+
170
+ OPTIONS_FROM_PARAMS.each_with_object({}) do |k, opts|
171
+ next unless params[k.to_s].size == 1
172
+ opts[k] = coerce(k, params[k.to_s].first)
173
+ end
174
+ end
175
+
176
+ def coerce(name, value)
177
+ case name
178
+ when :open_timeout, :read_timeout, :max_delay, :retry, :chunk_size
179
+ value.to_i
180
+ when :initial_delay
181
+ value.to_f
182
+ when :verify_ssl, :denormalize, :async, :discard_write_errors
183
+ %w[true 1 yes on].include?(value.downcase)
184
+ else
185
+ value
186
+ end
119
187
  end
120
188
  end
121
189
  end