Refactor to use service_skeleton (#13)

Refactor to use service_skeleton (#13)

Large refactor to use loggerstash, service_skeleton, and prometheus-client. The original implementation preceded these other gems (actually this is where they came from) so this patch brings mobystash up to date with improvements only present in the new seperate gems.

diff --git a/Gemfile b/Gemfile
index 6e1a561..96f8de0 100644
--- a/Gemfile
+++ b/Gemfile
@@ -12,7 +12,9 @@ gem 'murmurhash3', '~> 0.1'
 gem 'rbtrace', '~> 0.4'
 gem 'sigdump', require: 'sigdump/setup'
 gem 'stackprof'
-gem 'prometheus_exporter'
+gem 'loggerstash'
+gem 'logstash_writer'
+gem 'service_skeleton', '~> 2'
 
 group :development do
   gem 'byebug'
diff --git a/Gemfile.lock b/Gemfile.lock
index 18779ac..4eeaf73 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -18,6 +18,9 @@ GEM
     excon (0.76.0)
     ffi (1.13.1)
     formatador (0.2.5)
+    frankenstein (2.1.0)
+      prometheus-client (~> 2.0)
+      rack (~> 2.0)
     guard (2.16.2)
       formatador (>= 0.2.4)
       listen (>= 2.7, < 4.0)
@@ -38,6 +41,10 @@ GEM
     listen (3.2.1)
       rb-fsevent (~> 0.10, >= 0.10.3)
       rb-inotify (~> 0.9, >= 0.9.10)
+    loggerstash (1.1.0)
+      logstash_writer (>= 0.0.11)
+    logstash_writer (0.0.12)
+      prometheus-client (~> 2.0)
     lumberjack (1.2.6)
     method_source (1.0.0)
     msgpack (1.3.3)
@@ -51,13 +58,14 @@ GEM
     parallel (1.19.2)
     parser (2.7.1.4)
       ast (~> 2.4.1)
-    prometheus_exporter (0.5.3)
+    prometheus-client (2.1.0)
     pry (0.13.1)
       coderay (~> 1.1)
       method_source (~> 1.0)
     pry-byebug (3.9.0)
       byebug (~> 11.0)
       pry (~> 0.13.0)
+    rack (2.2.3)
     rainbow (3.0.0)
     rake (13.0.1)
     rb-fsevent (0.10.4)
@@ -100,6 +108,13 @@ GEM
     rubocop-rspec (1.42.0)
       rubocop (>= 0.87.0)
     ruby-progressbar (1.10.1)
+    service_skeleton (2.0.2)
+      frankenstein (~> 2.0)
+      loggerstash (~> 1)
+      prometheus-client (~> 2.0)
+      sigdump (~> 0.2)
+      to_regexp (~> 0.2)
+      webrick
     shellany (0.0.1)
     sigdump (0.2.4)
     simplecov (0.18.5)
@@ -108,7 +123,9 @@ GEM
     simplecov-html (0.12.2)
     stackprof (0.2.15)
     thor (1.0.1)
+    to_regexp (0.2.1)
     unicode-display_width (1.7.0)
+    webrick (1.7.0)
     yard (0.9.25)
 
 PLATFORMS
@@ -121,9 +138,10 @@ DEPENDENCIES
   excon (~> 0.59)
   guard-rspec
   guard-rubocop
+  loggerstash
+  logstash_writer
   mobystash!
   murmurhash3 (~> 0.1)
-  prometheus_exporter
   pry-byebug
   rake (>= 11)
   rbtrace (~> 0.4)
@@ -132,6 +150,7 @@ DEPENDENCIES
   rubocop
   rubocop-discourse
   rubocop-rspec
+  service_skeleton (~> 2)
   sigdump
   simplecov
   stackprof
diff --git a/bin/mobystash b/bin/mobystash
index 5bec56a..0b3d708 100755
--- a/bin/mobystash
+++ b/bin/mobystash
@@ -1,7 +1,5 @@
 #!/usr/bin/env ruby
 
-Thread.current.name = "main"
-
 if ENV['RUBY_TRACE_ALLOCATIONS'] == "yep"
   require 'objspace'
 
@@ -11,80 +9,11 @@ end
 require 'sigdump'
 Sigdump.setup('SIGCONT', '+')
 
-require 'logger'
 require 'rbtrace'
 require 'mobystash'
 
-logger = Logger.new($stderr)
-logger.level = Logger.const_get((ENV['MOBYSTASH_LOG_LEVEL'] || "INFO").upcase)
-
-if ENV['MOBYSTASH_DEBUG_MODULES'] && ENV['MOBYSTASH_DEBUG_MODULES'] != ""
-  require 'filtered_debug_logger'
-  Logger.prepend(FilteredDebugLogger)
-  logger.permitted_prognames = ENV['MOBYSTASH_DEBUG_MODULES'].split(/,\s*/)
-end
-
-logger.formatter = ->(s, t, p, m) { "#{s[0]} (#{p}) #{m}\n" }
-
-sig_r, sig_w = IO.pipe
-
-Signal.trap("USR1") do
-  sig_w.print '1'
-end
-
-Signal.trap("USR2") do
-  sig_w.print '2'
-end
-
-Signal.trap("TERM") do
-  sig_w.print 'T'
-end
-
-Signal.trap("INT") do
-  sig_w.print 'I'
-end
-
-Signal.trap("HUP") do
-  sig_w.print 'H'
-end
-
 begin
-  system = Mobystash::System.new(ENV, logger: logger)
-
-  Thread.new do
-    Thread.current.name = "SignalHandler"
-
-    loop do
-      begin
-        c = sig_r.getc
-        if c == 'T'
-          logger.info($0) { "Received SIGTERM." }
-          system.shutdown
-        elsif c == 'I'
-          logger.info($0) { "Received SIGINT." }
-          system.shutdown
-        elsif c == '1'
-          logger.level -= 1 unless logger.level == Logger::DEBUG
-          logger.info($0) { "Received SIGUSR1; log level is now #{Logger::SEV_LABEL[logger.level]}." }
-        elsif c == '2'
-          logger.level += 1 unless logger.level == Logger::ERROR
-          logger.info($0) { "Received SIGUSR2; log level is now #{Logger::SEV_LABEL[logger.level]}." }
-        elsif c == 'H'
-          logger.info($0) { "Received SIGHUP." }
-          system.reconnect!
-        else
-          logger.error($0) { "Got an unrecognised character from signal pipe: #{c.inspect}" }
-        end
-      rescue Exception => ex
-        logger.error($0) { "Exception in signal handler: #{ex.message} (#{ex.class})" }
-      end
-    end
-  end
-
-  ls = Loggerstash.new(logstash_server: "unused", logstash_writer: system.config.logstash_writer)
-  ls.attach(logger)
-
-  system.run
+  Mobystash.new(ENV).start
 rescue Mobystash::Config::InvalidEnvironmentError => ex
   $stderr.puts "F Invalid configuration: #{ex.message}"
   exit 1
diff --git a/lib/mobystash.rb b/lib/mobystash.rb
index bab225c..5430fc6 100644
--- a/lib/mobystash.rb
+++ b/lib/mobystash.rb
@@ -1,12 +1,74 @@
-require 'prometheus_exporter'
-require 'prometheus_exporter/metric'
+require 'loggerstash'
+require 'logstash_writer'
+
+require 'service_skeleton'
+
+class Mobystash
+  include ServiceSkeleton
+
+  boolean   :MOBYSTASH_ENABLE_METRICS, default: false
+  integer   :MOBYSTASH_METRICS_PORT, default: 9367
+  float     :MOBYSTASH_SAMPLE_RATIO, default: 1, range: 1..Float::INFINITY
+  float     :MOBYSTASH_STATE_CHECKPOINT_INTERVAL, default: 1, range: 0..Float::INFINITY
+  kv_list   :MOBYSTASH_SAMPLE_KEYS, default: {}, key_pattern: /\AMOBYSTASH_SAMPLE_KEY_(.*)\z/
+  string    :MOBYSTASH_STATE_FILE, default: "./mobystash_state.dump"
+  string    :DOCKER_HOST, default: "unix:///var/run/docker.sock"
+
+  counter :mobystash_moby_read_event_exceptions_total,
+          docstring: " Exception counts while attempting to read log entries from the Moby server",
+          labels: [:container_name, :container_id, :class]
+
+  counter :mobystash_log_entries_read_total,
+          docstring: "How many log entries have been received from Moby",
+          labels: [:container_name, :container_id, :stream]
+
+  counter :mobystash_log_entries_sent_total,
+          docstring: "How many log entries have been sent to the LogstashWriter",
+          labels: [:container_name, :container_id, :stream]
+
+  counter :mobystash_sampled_entries_sent_total,
+          docstring: "The number of sampled entries which have been sent",
+          labels: [:sample_key]
+
+  counter :mobystash_sampled_entries_dropped_total,
+          docstring: "The number of sampled log entries which didn't get sent",
+          labels: [:sample_key]
+
+  counter :mobystash_unsampled_entries_total,
+          docstring: "How many log messages we've seen which didn't match any defined sample keys"
+
+  counter :mobystash_moby_watch_exceptions_total,
+          docstring: "How many exceptions have been raised while handling docker events",
+          labels: [:class]
+
+  counter :mobystash_moby_events_total,
+          docstring: "How many docker events we have seen and processed",
+          labels: [:type]
+
+  histogram :mobystash_last_log_entry_at,
+            docstring: "The time at which the last log entry was timestamped",
+            labels: [:container_name, :container_id, :stream]
+
+  gauge :mobystash_sample_ratios,
+        docstring: "The current sample ratio for each sample key",
+        labels: [:sample_key]
+
+  def initialize(*_)
+    super
+
+    writer = LogstashWriter.new(server_name: config.logstash_server, backlog: config.backlog_size, logger: logger, metrics_registry: metrics, metrics_prefix: :syslogstash_writer)
+    sampler = MobyStash::Sampler.new(config, metrics)
+    @system = Mobystash::System.new(config, logger: logger, metrics: metrics, writer: writer, sampler: sampler)
+  end
+
+  def run
+    @system.start!
+  end
+end
 
-require_relative "mobystash/logstash_writer"
-require_relative "mobystash/loggerstash"
 require_relative "mobystash/log_exception"

[... diff too long, it was truncated ...]

GitHub sha: a57e94931a12e779f320394991d7738b0062717d

This commit appears in #13 which was approved by SamSaffron. It was merged by fitzy1011.