Log in background thread

Stephen Paul Weber created

File IO is fast, but can still block reactor.

Change summary

.rubocop.yml          |  1 +
lib/background_log.rb | 29 +++++++++++++++++++++++++++++
sgx_jmp.rb            |  4 +++-
3 files changed, 33 insertions(+), 1 deletion(-)

Detailed changes

.rubocop.yml 🔗

@@ -29,6 +29,7 @@ Metrics/ParameterLists:
 Naming/MethodParameterName:
   AllowNamesEndingInNumbers: false
   AllowedNames:
+    - io
     - m
     - e
     - q

lib/background_log.rb 🔗

@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+# Subclass IO because Logger does an is_a? check
+class BackgroundLog < IO
+	def initialize(io)
+		@io = io
+		@q = Queue.new
+		thread
+		at_exit do
+			@q << :done
+			thread.join
+		end
+	end
+
+	def thread
+		@thread ||= Thread.new do
+			loop do
+				m = @q.pop
+				break if m == :done
+
+				@io.write m
+			end
+		end
+	end
+
+	def write(s)
+		@q << s
+	end
+end

sgx_jmp.rb 🔗

@@ -14,8 +14,10 @@ require "ruby-bandwidth-iris"
 require "sentry-ruby"
 require "statsd-instrument"
 
+require_relative "lib/background_log"
+
 $stdout.sync = true
-LOG = Ougai::Logger.new($stdout)
+LOG = Ougai::Logger.new(BackgroundLog.new($stdout))
 LOG.level = ENV.fetch("LOG_LEVEL", "info")
 LOG.formatter = Ougai::Formatters::Readable.new(
 	nil,