lib/statsd.rb in dogstatsd-ruby-1.3.0 vs lib/statsd.rb in dogstatsd-ruby-1.4.0

- old
+ new

@@ -42,30 +42,39 @@ attr_reader :port # Global tags to be added to every statsd call. Defaults to no tags. attr_reader :tags + # Buffer containing the statsd message before they are sent in batch + attr_reader :buffer + + # Maximum number of metrics in the buffer before it is flushed + attr_accessor :max_buffer_size + class << self # Set to a standard logger instance to enable debug logging. attr_accessor :logger end # Return the current version of the library. def self.VERSION - "1.3.0" + "1.4.0" end # @param [String] host your statsd host # @param [Integer] port your statsd port # @option opts [String] :namespace set a namespace to be prepended to every metric name # @option opts [Array<String>] :tags tags to be added to every metric - def initialize(host = DEFAULT_HOST, port = DEFAULT_PORT, opts = {}) + def initialize(host = DEFAULT_HOST, port = DEFAULT_PORT, opts = {}, max_buffer_size=50) self.host, self.port = host, port @prefix = nil @socket = UDPSocket.new self.namespace = opts[:namespace] self.tags = opts[:tags] + @buffer = Array.new + self.max_buffer_size = max_buffer_size + alias :send :send_to_socket end def namespace=(namespace) #:nodoc: @namespace = namespace @prefix = namespace.nil? ? nil : "#{namespace}." @@ -203,18 +212,34 @@ # @option opts [String, nil] :aggregation_key (nil) Assign an aggregation key to the event, to group it with some others # @option opts [String, nil] :priority ('normal') Can be "normal" or "low" # @option opts [String, nil] :source_type_name (nil) Assign a source type to the event # @option opts [String, nil] :alert_type ('info') Can be "error", "warning", "info" or "success". # @option opts [Array<String>, nil] :source_type_name (nil) An array of tags - # @example Report an aweful event: + # @example Report an awful event: # $statsd.event('Something terrible happened', 'The end is near if we do nothing', :alert_type=>'warning', :tags=>['end_of_times','urgent']) def event(title, text, opts={}) event_string = format_event(title, text, opts) raise "Event #{title} payload is too big (more that 8KB), event discarded" if event_string.length > 8 * 1024 send_to_socket event_string end + + # Send several metrics in the same UDP Packet + # They will be buffered and flushed when the block finishes + # + # @example Send several metrics in one packet: + # $statsd.batch do |s| + # s.gauge('users.online',156) + # s.increment('page.views') + # end + def batch() + alias :send :send_to_buffer + yield self + flush_buffer + alias :send :send_to_socket + end + def format_event(title, text, opts={}) escape_event_content title escape_event_content text event_string_data = "_e{#{title.length},#{text.length}}:#{title}|#{text}" @@ -254,11 +279,23 @@ # Replace Ruby module scoping with '.' and reserved chars (: | @) with underscores. stat = stat.to_s.gsub('::', '.').tr(':|@', '_') rate = "|@#{sample_rate}" unless sample_rate == 1 ts = (tags || []) + (opts[:tags] || []) tags = "|##{ts.join(",")}" unless ts.empty? - send_to_socket "#{@prefix}#{stat}:#{delta}|#{type}#{rate}#{tags}" + send "#{@prefix}#{stat}:#{delta}|#{type}#{rate}#{tags}" end + end + + def send_to_buffer(message) + @buffer << message + if @buffer.length >= @max_buffer_size + flush_buffer + end + end + + def flush_buffer() + send_to_socket(@buffer.join('\n')) + @buffer = Array.new end def send_to_socket(message) self.class.logger.debug { "Statsd: #{message}" } if self.class.logger @socket.send(message, 0, @host, @port)