# frozen_string_literal: true module StatsD module Instrument # The environment module is used to detect, and initialize the environment in # which this library is active. It will use different default values based on the environment. class Environment class << self def current @current ||= StatsD::Instrument::Environment.new(ENV) end # @deprecated For backwards compatibility only. Use {StatsD::Instrument::Environment#environment} # through {StatsD::Instrument::Environment.current} instead. def environment current.environment end # Sets default values for sample rate and logger. # # - Default sample rate is set to the value in the STATSD_SAMPLE_RATE environment variable, # or 1.0 otherwise. See {StatsD#default_sample_rate} # - {StatsD#logger} is set to a logger that send output to stderr. # # If you are including this library inside a Rails environment, additional initialization will # be done as part of the {StatsD::Instrument::Railtie}. # # @return [void] def setup StatsD.logger = Logger.new($stderr) end end attr_reader :env def initialize(env) @env = env if env.key?("STATSD_FLUSH_INTERVAL") value = env["STATSD_FLUSH_INTERVAL"] if Float(value) == 0.0 warn("STATSD_FLUSH_INTERVAL=#{value} is deprecated, please set STATSD_BUFFER_CAPACITY=0 instead.") else warn("STATSD_FLUSH_INTERVAL=#{value} is deprecated and has no effect, please remove it.") end end end # Detects the current environment, either by asking Rails, or by inspecting environment variables. # # - It will prefer the value set in ENV['STATSD_ENV'] # - Within a Rails application, Rails.env is used. # - It will check the following environment variables in order: # - RAILS_ENV, # - RACK_ENV # - ENV. # - If none of these are set, it will return development # # @return [String] The detected environment. def environment if env["STATSD_ENV"] env["STATSD_ENV"] elsif defined?(Rails) && Rails.respond_to?(:env) Rails.env.to_s else env["RAILS_ENV"] || env["RACK_ENV"] || env["ENV"] || "development" end end def statsd_implementation env.fetch("STATSD_IMPLEMENTATION", "datadog") end def statsd_sample_rate env.fetch("STATSD_SAMPLE_RATE", 1.0).to_f end def statsd_prefix env.fetch("STATSD_PREFIX", nil) end def statsd_addr env.fetch("STATSD_ADDR", "localhost:8125") end def statsd_socket_path env.fetch("STATSD_SOCKET_PATH", "") end def statsd_default_tags env.key?("STATSD_DEFAULT_TAGS") ? env.fetch("STATSD_DEFAULT_TAGS").split(",") : nil end def statsd_buffer_capacity Integer(env.fetch("STATSD_BUFFER_CAPACITY", StatsD::Instrument::BatchedSink::DEFAULT_BUFFER_CAPACITY)) end def statsd_batching? statsd_buffer_capacity > 0 && Float(env.fetch("STATSD_FLUSH_INTERVAL", 1.0)) > 0.0 end def statsd_uds_send? !statsd_socket_path.empty? end def statsd_max_packet_size if statsd_uds_send? return Float(env.fetch("STATSD_MAX_PACKET_SIZE", StatsD::Instrument::UdsConnection::DEFAULT_MAX_PACKET_SIZE)) end Float(env.fetch("STATSD_MAX_PACKET_SIZE", StatsD::Instrument::UdpConnection::DEFAULT_MAX_PACKET_SIZE)) end def statsd_batch_statistics_interval Integer(env.fetch( "STATSD_BATCH_STATISTICS_INTERVAL", StatsD::Instrument::BatchedSink::DEFAULT_STATISTICS_INTERVAL, )) end def experimental_aggregation_enabled? env.key?("STATSD_ENABLE_AGGREGATION") end def aggregation_interval Float(env.fetch("STATSD_AGGREGATION_INTERVAL", 2.0)) end def aggregation_max_context_size Integer(env.fetch( "STATSD_AGGREGATION_MAX_CONTEXT_SIZE", StatsD::Instrument::Aggregator::DEFAULT_MAX_CONTEXT_SIZE, )) end def client StatsD::Instrument::Client.from_env(self) end def default_sink_for_environment case environment when "production", "staging" connection = if statsd_uds_send? StatsD::Instrument::UdsConnection.new(statsd_socket_path) else host, port = statsd_addr.split(":") StatsD::Instrument::UdpConnection.new(host, port.to_i) end sink = StatsD::Instrument::Sink.new(connection) if statsd_batching? # if we are batching, wrap the sink in a batched sink return StatsD::Instrument::BatchedSink.new( sink, buffer_capacity: statsd_buffer_capacity, max_packet_size: statsd_max_packet_size, statistics_interval: statsd_batch_statistics_interval, ) end sink when "test" StatsD::Instrument::NullSink.new else StatsD::Instrument::LogSink.new(StatsD.logger) end end end end end StatsD::Instrument::Environment.setup