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