1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
|
require "uri"
module InfluxDB
# DEFAULT_CONFIG_OPTIONS maps (most) of the configuration options to
# their default value. Each option (except for "async" and "udp") can
# be changed at runtime throug the InfluxDB::Client instance.
#
# If you need to change the writer to be asynchronuous or use UDP, you
# need to get a new InfluxDB::Client instance.
DEFAULT_CONFIG_OPTIONS = {
# HTTP connection options
port: 8086,
prefix: "".freeze,
username: "root".freeze,
password: "root".freeze,
open_timeout: 5,
read_timeout: 300,
auth_method: nil,
proxy_addr: nil,
proxy_port: nil,
# SSL options
use_ssl: false,
verify_ssl: true,
ssl_ca_cert: false,
# Database options
database: nil,
time_precision: "s".freeze,
epoch: false,
# Writer options
async: false,
udp: false,
discard_write_errors: false,
# Retry options
retry: -1,
max_delay: 30,
initial_delay: 0.01,
# Query options
chunk_size: nil,
denormalize: true,
}.freeze
# InfluxDB client configuration
class Config
# Valid values for the "auth_method" option.
AUTH_METHODS = [
"params".freeze,
"basic_auth".freeze,
"none".freeze,
].freeze
ATTR_READER = %i[async udp].freeze
private_constant :ATTR_READER
ATTR_ACCESSOR = (DEFAULT_CONFIG_OPTIONS.keys - ATTR_READER).freeze
private_constant :ATTR_ACCESSOR
attr_reader(*ATTR_READER)
attr_accessor(*ATTR_ACCESSOR)
# Creates a new instance. See `DEFAULT_CONFIG_OPTIONS` for available
# config options and their default values.
#
# If you provide a "url" option, either as String (hint: ENV) or as
# URI instance, you can override the defaults. The precedence for a
# config value is as follows (first found wins):
#
# - values given in the options hash
# - values found in URL (if given)
# - default values
def initialize(url: nil, **opts)
opts = opts_from_url(url).merge(opts) if url
DEFAULT_CONFIG_OPTIONS.each do |name, value|
set_ivar! name, opts.fetch(name, value)
end
configure_hosts! opts[:hosts] || opts[:host] || "localhost".freeze
end
def udp?
udp != false
end
def async?
async != false
end
def next_host
host = @hosts_queue.pop
@hosts_queue.push(host)
host
end
def hosts
Array.new(@hosts_queue.length) do
host = @hosts_queue.pop
@hosts_queue.push(host)
host
end
end
private
def set_ivar!(name, value)
case name
when :auth_method
value = "params".freeze unless AUTH_METHODS.include?(value)
when :retry
value = normalize_retry_option(value)
end
instance_variable_set "@#{name}", value
end
def normalize_retry_option(value)
case value
when Integer then value
when true, nil then -1
when false then 0
end
end
# load the hosts into a Queue for thread safety
def configure_hosts!(hosts)
@hosts_queue = Queue.new
Array(hosts).each do |host|
@hosts_queue.push(host)
end
end
# merges URI options into opts
def opts_from_url(url)
url = URI.parse(url) unless url.is_a?(URI)
opts_from_non_params(url).merge opts_from_params(url.query)
rescue URI::InvalidURIError
{}
end
# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/CyclomaticComplexity
def opts_from_non_params(url)
{}.tap do |o|
o[:host] = url.host if url.host
o[:port] = url.port if url.port
o[:username] = URI.decode_www_form_component(url.user) if url.user
o[:password] = URI.decode_www_form_component(url.password) if url.password
o[:database] = url.path[1..-1] if url.path.length > 1
o[:use_ssl] = url.scheme == "https".freeze
o[:udp] = { host: o[:host], port: o[:port] } if url.scheme == "udp"
end
end
# rubocop:enable Metrics/AbcSize
# rubocop:enable Metrics/CyclomaticComplexity
OPTIONS_FROM_PARAMS = (DEFAULT_CONFIG_OPTIONS.keys - %i[
host port username password database use_ssl udp
]).freeze
private_constant :OPTIONS_FROM_PARAMS
def opts_from_params(query)
params = CGI.parse(query || "").tap { |h| h.default = [] }
OPTIONS_FROM_PARAMS.each_with_object({}) do |k, opts|
next unless params[k.to_s].size == 1
opts[k] = coerce(k, params[k.to_s].first)
end
end
def coerce(name, value)
case name
when :open_timeout, :read_timeout, :max_delay, :retry, :chunk_size
value.to_i
when :initial_delay
value.to_f
when :verify_ssl, :denormalize, :async, :discard_write_errors
%w[true 1 yes on].include?(value.downcase)
else
value
end
end
end
end
|