lib/timber/log_devices/http.rb in timber-1.0.11 vs lib/timber/log_devices/http.rb in timber-1.0.12

- old
+ new

@@ -6,42 +6,33 @@ # # See {#initialize} for options and more details. class HTTP # @private class LogMsgQueue - MAX_MSG_BYTES = 50_000 # 50kb - - def initialize(max_bytes) + def initialize(max_size) @lock = Mutex.new - @max_bytes = max_bytes + @max_size = max_size @array = [] - @bytesize = 0 end def enqueue(msg) - if msg.bytesize > MAX_MSG_BYTES - raise ArgumentError.new("Log message exceeds the #{MAX_MSG_BYTES} bytes limit") - end - @lock.synchronize do @array << msg - @bytesize += msg.bytesize end end def flush @lock.synchronize do old = @array @array = [] - @bytesize = 0 return old end end def full? @lock.synchronize do - @bytesize >= @max_bytes + size >= @max_size end end def size @array.size @@ -68,11 +59,11 @@ end end end TIMBER_URL = "https://logs.timber.io/frames".freeze - CONTENT_TYPE = "application/x-timber-msgpack-frame-1; charset=ascii-8bit".freeze + CONTENT_TYPE = "application/msgpack".freeze USER_AGENT = "Timber Ruby Gem/#{Timber::VERSION}".freeze DELIVERY_FREQUENCY_SECONDS = 2.freeze RETRY_LIMIT = 5.freeze BACKOFF_RATE_SECONDS = 3.freeze @@ -88,21 +79,21 @@ # {DroppingSizedQueue} via the `:request_queue` option. # # @param api_key [String] The API key provided to you after you add your application to # [Timber](https://timber.io). # @param [Hash] options the options to create a HTTP log device with. - # @option attributes [Symbol] :batch_byte_size Determines the maximum size in bytes for - # each HTTP payload. If the buffer exceeds this limit a delivery will be attempted. - # @option attributes [Symbol] :debug Whether to print debug output or not. This is also + # @option attributes [Symbol] :batch_size (500) Determines the maximum of log lines in each HTTP + # payload. If the queue exceeds this limit a HTTP request will be issued. + # @option attributes [Symbol] :debug (false) Whether to print debug output or not. This is also # inferred from ENV['debug']. Output will be sent to `Timber::Config.logger`. # @option attributes [Symbol] :flush_interval (2) How often the client should # attempt to deliver logs to the Timber API. The HTTP client buffers logs and this # options represents how often that will happen, assuming `:batch_byte_size` is not met. - # @option attributes [Symbol] :requests_per_conn The number of requests to send over a + # @option attributes [Symbol] :requests_per_conn (1000) The number of requests to send over a # single persistent connection. After this number is met, the connection will be closed # and a new one will be opened. - # @option attributes [Symbol] :request_queue The request queue object that queues Net::HTTP + # @option attributes [Symbol] :request_queue (SizedQueue.new(3)) The request queue object that queues Net::HTTP # requests for delivery. By deafult this is a `SizedQueue` of size `3`. Meaning once # 3 requests are placed on the queue for delivery, back pressure will be applied. IF # you'd prefer to drop messages instead, pass a {DroppingSizedQueue}. See examples for # an example. # @option attributes [Symbol] :timber_url The Timber URL to delivery the log lines. The @@ -117,16 +108,16 @@ # Timber::Logger.new(http_log_device) def initialize(api_key, options = {}) @api_key = api_key @debug = options[:debug] || ENV['debug'] @timber_url = URI.parse(options[:timber_url] || ENV['TIMBER_URL'] || TIMBER_URL) - @batch_byte_size = options[:batch_byte_size] || 3_000_000 # 3mb + @batch_size = options[:batch_size] || 500 @flush_interval = options[:flush_interval] || 2 # 2 seconds @requests_per_conn = options[:requests_per_conn] || 1_000 - @msg_queue = LogMsgQueue.new(@batch_byte_size) + @msg_queue = LogMsgQueue.new(@batch_size) @request_queue = options[:request_queue] || SizedQueue.new(3) - @req_in_flight = 0 + @requests_in_flight = 0 if options[:threads] != false @outlet_thread = Thread.new { outlet } @flush_thread = Thread.new { intervaled_flush } end @@ -156,21 +147,16 @@ def flush msgs = @msg_queue.flush return if msgs.empty? - body = "" - msgs.each do |msg| - body << msg - end - req = Net::HTTP::Post.new(@timber_url.path) req['Accept'] = "application/json" req['Authorization'] = authorization_payload req['Content-Type'] = CONTENT_TYPE req['User-Agent'] = USER_AGENT - req.body = body + req.body = msgs.to_msgpack @request_queue.enq(req) @last_flush = Time.now end def intervaled_flush @@ -203,20 +189,20 @@ begin http.start do |conn| num_reqs = 0 while num_reqs < @requests_per_conn - #Blocks waiting for a request. + # Blocks waiting for a request. req = @request_queue.deq - @req_in_flight += 1 + @requests_in_flight += 1 resp = nil begin resp = conn.request(req) rescue => e logger.error("Timber request error: #{e.message}") if debug? next ensure - @req_in_flight -= 1 + @requests_in_flight -= 1 end num_reqs += 1 logger.info("Timber request successful: #{resp.code}") if debug? end end \ No newline at end of file