resurrected_god 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +25 -0
  3. data/README.md +3 -2
  4. data/bin/god +1 -0
  5. data/ext/god/extconf.rb +2 -0
  6. data/lib/god/behavior.rb +2 -0
  7. data/lib/god/behaviors/clean_pid_file.rb +2 -0
  8. data/lib/god/behaviors/clean_unix_socket.rb +2 -0
  9. data/lib/god/behaviors/notify_when_flapping.rb +2 -0
  10. data/lib/god/cli/command.rb +3 -1
  11. data/lib/god/cli/run.rb +2 -0
  12. data/lib/god/cli/version.rb +2 -0
  13. data/lib/god/condition.rb +2 -0
  14. data/lib/god/conditions/always.rb +2 -0
  15. data/lib/god/conditions/complex.rb +2 -0
  16. data/lib/god/conditions/cpu_usage.rb +2 -0
  17. data/lib/god/conditions/degrading_lambda.rb +2 -0
  18. data/lib/god/conditions/disk_usage.rb +2 -0
  19. data/lib/god/conditions/file_mtime.rb +2 -0
  20. data/lib/god/conditions/file_touched.rb +2 -0
  21. data/lib/god/conditions/flapping.rb +2 -0
  22. data/lib/god/conditions/http_response_code.rb +2 -0
  23. data/lib/god/conditions/lambda.rb +2 -0
  24. data/lib/god/conditions/memory_usage.rb +2 -0
  25. data/lib/god/conditions/process_exits.rb +2 -0
  26. data/lib/god/conditions/process_running.rb +5 -3
  27. data/lib/god/conditions/socket_responding.rb +4 -0
  28. data/lib/god/conditions/tries.rb +2 -0
  29. data/lib/god/configurable.rb +2 -1
  30. data/lib/god/contact.rb +3 -1
  31. data/lib/god/contacts/airbrake.rb +3 -2
  32. data/lib/god/contacts/email.rb +2 -0
  33. data/lib/god/contacts/slack.rb +2 -1
  34. data/lib/god/contacts/webhook.rb +2 -1
  35. data/lib/god/driver.rb +2 -0
  36. data/lib/god/errors.rb +2 -0
  37. data/lib/god/event_handler.rb +2 -0
  38. data/lib/god/event_handlers/dummy_handler.rb +3 -1
  39. data/lib/god/event_handlers/kqueue_handler.rb +3 -1
  40. data/lib/god/event_handlers/netlink_handler.rb +3 -1
  41. data/lib/god/logger.rb +2 -0
  42. data/lib/god/metric.rb +2 -0
  43. data/lib/god/process.rb +3 -1
  44. data/lib/god/registry.rb +2 -0
  45. data/lib/god/simple_logger.rb +2 -0
  46. data/lib/god/socket.rb +2 -0
  47. data/lib/god/sugar.rb +2 -0
  48. data/lib/god/sys_logger.rb +2 -0
  49. data/lib/god/system/portable_poller.rb +2 -0
  50. data/lib/god/system/process.rb +2 -0
  51. data/lib/god/system/slash_proc_poller.rb +4 -2
  52. data/lib/god/task.rb +2 -0
  53. data/lib/god/timeline.rb +3 -1
  54. data/lib/god/trigger.rb +2 -0
  55. data/lib/god/version.rb +3 -1
  56. data/lib/god/watch.rb +4 -2
  57. data/lib/god.rb +17 -17
  58. metadata +38 -18
  59. data/lib/god/contacts/campfire.rb +0 -119
  60. data/lib/god/contacts/prowl.rb +0 -56
  61. data/lib/god/contacts/scout.rb +0 -52
  62. data/lib/god/contacts/sensu.rb +0 -63
  63. data/lib/god/contacts/statsd.rb +0 -46
  64. data/lib/god/contacts/twitter.rb +0 -51
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8047b13920bf8a719d40a5bd30e305e61ba35dc4fbaf8485711d0e42033d0f81
4
- data.tar.gz: 805b488b5ad867422752da4e6e6694060c1951459594df6015fd986e92560442
3
+ metadata.gz: e65b14e71958dd94729eeba93780283ccdb73e49a202859d816b94832656436f
4
+ data.tar.gz: 9a32895548e3f07d7a0e0f0907475d20217da6fe58e2227fcc5c852644b968b4
5
5
  SHA512:
6
- metadata.gz: c30d5a5f22a6badea13a8cad1455f6494f431bae14037664e1d4dce04bdf0be19ff3b5b4369e5a9665101472eac07ca5229dbb614868414580f93387bb82ce52
7
- data.tar.gz: edf6622f0d6aeb50678b55e3b3231e39f0f5bd1c1cc2f8d4f93d7a003b97b8cdd6f87f7b14aa574402a33fb90b53d3a704658d4b3b3bed79683b3826a5eb327b
6
+ metadata.gz: 37610457947e042fbeaa46aca0087b5f8cf022188ad9049c0512decf13136a879f19b8993da7ace3035dd574163d94fdd2ffb63bb148ab13513aaa45bcb29044
7
+ data.tar.gz: f0cc1a3ffc8a58c0c6b5285a30134a6a4657ed7479913b4bcfd66ebaf7978eba1aaf2ac3a409543ecf17caf84b872e48fa16b841056b56a07aa33eaadbcd4e3d
data/History.md CHANGED
@@ -1,3 +1,28 @@
1
+ ## 1.1.1 / 2023-12-29
2
+
3
+ * Minor Changes
4
+ * Add drb and syslog to runtime dependencies for Ruby 3.4+
5
+
6
+ ## 1.1.0 / 2022-06-29
7
+
8
+ * Major Changes
9
+ * Drop support for Campfire
10
+ * Drop support for Prowl
11
+ * Drop support for Scout
12
+ * Drop support for Sensu
13
+ * Drop support for StatsD
14
+ * Drop support for Twitter
15
+ * Bug fixes
16
+ * Use `String#+@` to avoid modify frozen String in `God.running_load`
17
+ * Minor Enhancements
18
+ * Enable `frozen_string_literal` entirely
19
+ * Remove unused gems from Gemfile
20
+ * Regenerate documents by using AsciiDoctor
21
+ * Polish documents
22
+ * Avoid modifying constant `CONTACT_DEPS`
23
+ * Remove an unused variable in `God::Configurable#base_name`
24
+ * It was for fix MRI's local scope optimization bug.
25
+
1
26
  ## 1.0.0 / 2022-06-22
2
27
 
3
28
  * Major Changes
data/README.md CHANGED
@@ -2,7 +2,8 @@ ResurrectedGod: The Ruby Framework for Process Management
2
2
  ==============================================
3
3
 
4
4
  [![Gem Version](https://badge.fury.io/rb/resurrected_god.svg)](https://badge.fury.io/rb/resurrected_god)
5
- [![CI](https://github.com/mishina2228/resurrected_god/actions/workflows/ci.yml/badge.svg)](https://github.com/mishina2228/resurrected_god/actions/workflows/ci.yml)
5
+ [![Test](https://github.com/mishina2228/resurrected_god/actions/workflows/test.yml/badge.svg)](https://github.com/mishina2228/resurrected_god/actions/workflows/test.yml)
6
+ [![Documentation](https://img.shields.io/badge/docs-rubydoc.info-blue.svg)](https://rubydoc.info/gems/resurrected_god)
6
7
  [![Maintainability](https://api.codeclimate.com/v1/badges/27b37a69e634eba75483/maintainability)](https://codeclimate.com/github/mishina2228/resurrected_god/maintainability)
7
8
  [![codecov](https://codecov.io/gh/mishina2228/resurrected_god/branch/master/graph/badge.svg?token=K1DJPS9PSU)](https://codecov.io/gh/mishina2228/resurrected_god)
8
9
 
@@ -25,7 +26,7 @@ Documentation
25
26
  -------------
26
27
 
27
28
  See in-repo documentation at [doc](doc).
28
- See online documentation at http://godrb.com.
29
+ See online documentation at [here](https://mishina2228.github.io/resurrected_god/).
29
30
 
30
31
  Community
31
32
  ---------
data/bin/god CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  $stdout.sync = true
4
5
 
data/ext/god/extconf.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mkmf'
2
4
 
3
5
  fail = false
data/lib/god/behavior.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  class Behavior
3
5
  include Configurable
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  module Behaviors
3
5
  class CleanPidFile < Behavior
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  module Behaviors
3
5
  class CleanUnixSocket < Behavior
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  module Behaviors
3
5
  class NotifyWhenFlapping < Behavior
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  module CLI
3
5
  class Command
@@ -25,7 +27,7 @@ module God
25
27
  def dispatch
26
28
  if %w[load status signal log quit terminate].include?(@command)
27
29
  setup
28
- send("#{@command}_command")
30
+ send(:"#{@command}_command")
29
31
  elsif %w[start stop restart monitor unmonitor remove].include?(@command)
30
32
  setup
31
33
  lifecycle_command
data/lib/god/cli/run.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  module CLI
3
5
  class Run
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  module CLI
3
5
  class Version
data/lib/god/condition.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  class Condition < Behavior
3
5
  attr_accessor :transition, :notify, :info, :phase
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  module Conditions
3
5
  # Always trigger or never trigger.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  module Conditions
3
5
  class Complex < PollCondition
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  module Conditions
3
5
  # Condition Symbol :cpu_usage
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  module Conditions
3
5
  # This condition degrades its interval by a factor of two for 3 tries before failing
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  module Conditions
3
5
  class DiskUsage < PollCondition
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  module Conditions
3
5
  class FileMtime < PollCondition
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  module Conditions
3
5
  # Condition Symbol :file_touched
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  module Conditions
3
5
  # Condition Symbol :flapping
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'net/http'
2
4
  require 'net/https'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  module Conditions
3
5
  class Lambda < PollCondition
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  module Conditions
3
5
  # Condition Symbol :memory_usage
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  module Conditions
3
5
  # Trigger when a process exits.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  module Conditions
3
5
  # Trigger when a process is running or not running depending on attributes.
@@ -46,13 +48,13 @@ module God
46
48
  active = pid && System::Process.new(pid).exists?
47
49
 
48
50
  if running && active
49
- info.concat(['process is running'])
51
+ info.push('process is running')
50
52
  true
51
53
  elsif !running && !active
52
- info.concat(['process is not running'])
54
+ info.push('process is not running')
53
55
  true
54
56
  else
55
- info.concat(['process is not running']) if running
57
+ info.push('process is not running') if running
56
58
  false
57
59
  end
58
60
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'socket'
2
4
  include Socket::Constants
3
5
 
@@ -112,12 +114,14 @@ module God
112
114
  begin
113
115
  s = TCPSocket.new(addr, port)
114
116
  rescue SystemCallError
117
+ # NOOP
115
118
  end
116
119
  status = responding != s.nil?
117
120
  when 'unix'
118
121
  begin
119
122
  s = UNIXSocket.new(path)
120
123
  rescue SystemCallError
124
+ # NOOP
121
125
  end
122
126
  status = responding != s.nil?
123
127
  else
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  module Conditions
3
5
  class Tries < PollCondition
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  module Configurable
3
5
  # Override this method in your Configurable (optional)
@@ -28,7 +30,6 @@ module God
28
30
  end
29
31
 
30
32
  def base_name
31
- x = 1 # fix for MRI's local scope optimization bug DO NOT REMOVE!
32
33
  @base_name ||= self.class.name.split('::').last
33
34
  end
34
35
 
data/lib/god/contact.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  class Contact
3
5
  include Configurable
@@ -26,7 +28,7 @@ module God
26
28
  end
27
29
 
28
30
  def arg(name)
29
- instance_variable_get("@#{name}") || self.class.instance_variable_get("@#{name}")
31
+ instance_variable_get(:"@#{name}") || self.class.instance_variable_get(:"@#{name}")
30
32
  end
31
33
 
32
34
  # Normalize the given notify specification into canonical form.
@@ -1,8 +1,9 @@
1
- # Send a notice to Airbrake (http://airbrake.io/).
1
+ # frozen_string_literal: true
2
+
3
+ # Send a notice to Airbrake (https://airbrake.io).
2
4
  #
3
5
  # apikey - The String API key.
4
6
 
5
- CONTACT_DEPS[:airbrake] = ['airbrake']
6
7
  CONTACT_DEPS[:airbrake].each do |d|
7
8
  require d
8
9
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Send a notice to an email address.
2
4
  #
3
5
  # to_email - The String email address to which the email will be sent.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Send a message to a Slack channel
2
4
  #
3
5
  # account - The name of your Slack account (visible in URL, e.g. foo.slack.com)
@@ -9,7 +11,6 @@
9
11
  require 'net/http'
10
12
  require 'uri'
11
13
 
12
- CONTACT_DEPS[:slack] = ['json']
13
14
  CONTACT_DEPS[:slack].each do |d|
14
15
  require d
15
16
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Send a notice to a webhook.
2
4
  #
3
5
  # url - The String webhook URL.
@@ -6,7 +8,6 @@
6
8
  require 'net/http'
7
9
  require 'uri'
8
10
 
9
- CONTACT_DEPS[:webhook] = ['json']
10
11
  CONTACT_DEPS[:webhook].each do |d|
11
12
  require d
12
13
  end
data/lib/god/driver.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'monitor'
2
4
 
3
5
  module God
data/lib/god/errors.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  class AbstractMethodNotOverriddenError < StandardError
3
5
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  class EventHandler
3
5
  @@actions = {}
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  class DummyHandler
3
- EVENT_SYSTEM = 'none'.freeze
5
+ EVENT_SYSTEM = 'none'
4
6
 
5
7
  def self.register_process(pid, events)
6
8
  raise NotImplementedError
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'kqueue_handler_ext'
2
4
 
3
5
  module God
4
6
  class KQueueHandler
5
- EVENT_SYSTEM = 'kqueue'.freeze
7
+ EVENT_SYSTEM = 'kqueue'
6
8
 
7
9
  def self.register_process(pid, events)
8
10
  monitor_process(pid, events_mask(events))
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'netlink_handler_ext'
2
4
 
3
5
  module God
4
6
  class NetlinkHandler
5
- EVENT_SYSTEM = 'netlink'.freeze
7
+ EVENT_SYSTEM = 'netlink'
6
8
 
7
9
  def self.register_process(pid, events)
8
10
  # netlink doesn't need to do this
data/lib/god/logger.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  class Logger < SimpleLogger
3
5
  attr_accessor :logs
data/lib/god/metric.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  # Metrics are responsible for holding watch conditions. An instance of
3
5
  # Metric is yielded to blocks in the start_if, restart_if, stop_if, and
data/lib/god/process.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  class Process
3
5
  WRITES_PID = [:start, :restart].freeze
@@ -251,7 +253,7 @@ module God
251
253
  $stdout.reopen(w)
252
254
  r.close
253
255
  pid = self.spawn(command)
254
- puts pid.to_s # send pid back to forker
256
+ puts pid # send pid back to forker
255
257
  exit!(0)
256
258
  end
257
259
 
data/lib/god/registry.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  def self.registry
3
5
  @registry ||= Registry.new
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  class SimpleLogger
3
5
  DEBUG = 2
data/lib/god/socket.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'drb'
2
4
 
3
5
  module God
data/lib/god/sugar.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Numeric
2
4
  # Public: Units of seconds.
3
5
  def seconds
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  begin
2
4
  require 'syslog'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  module System
3
5
  class PortablePoller
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  module System
3
5
  class Process
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  module System
3
5
  class SlashProcPoller < PortablePoller
@@ -5,8 +7,8 @@ module God
5
7
  @@hertz = 100
6
8
  @@total_mem = nil
7
9
 
8
- MEMINFO_PATH = '/proc/meminfo'.freeze
9
- UPTIME_PATH = '/proc/uptime'.freeze
10
+ MEMINFO_PATH = '/proc/meminfo'
11
+ UPTIME_PATH = '/proc/uptime'
10
12
 
11
13
  REQUIRED_PATHS = [MEMINFO_PATH, UPTIME_PATH].freeze
12
14
 
data/lib/god/task.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  class Task
3
5
  # Public: Gets/Sets the String name of the task.
data/lib/god/timeline.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  class Timeline < Array
3
5
  # Instantiate a new Timeline
@@ -14,7 +16,7 @@ module God
14
16
  #
15
17
  # Returns Timeline
16
18
  def push(val)
17
- concat([val])
19
+ super
18
20
  shift if size > @max_size
19
21
  end
20
22
 
data/lib/god/trigger.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  class Trigger
3
5
  class << self
data/lib/god/version.rb CHANGED
@@ -1,4 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module God
2
4
  # The String version number for this package.
3
- VERSION = '1.0.0'.freeze
5
+ VERSION = '1.1.1'
4
6
  end
data/lib/god/watch.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'etc'
2
4
  require 'forwardable'
3
5
 
@@ -282,7 +284,7 @@ module God
282
284
  before_items = behaviors
283
285
  before_items += [condition] if condition
284
286
  before_items.each do |b|
285
- info = b.send("before_#{action}")
287
+ info = b.send(:"before_#{action}")
286
288
  if info
287
289
  msg = "#{name} before_#{action}: #{info} (#{b.base_name})"
288
290
  applog(self, :info, msg)
@@ -302,7 +304,7 @@ module God
302
304
  after_items = behaviors
303
305
  after_items += [condition] if condition
304
306
  after_items.each do |b|
305
- info = b.send("after_#{action}")
307
+ info = b.send(:"after_#{action}")
306
308
  if info
307
309
  msg = "#{name} after_#{action}: #{info} (#{b.base_name})"
308
310
  applog(self, :info, msg)
data/lib/god.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Bail out before loading anything unless this flag is set.
2
4
  #
3
5
  # We are doing this to guard against bundler autoloading because there is
@@ -60,7 +62,11 @@ if $load_god
60
62
  require 'god/cli/version'
61
63
  require 'god/cli/command'
62
64
 
63
- CONTACT_DEPS = {}
65
+ CONTACT_DEPS = {
66
+ webhook: ['json'],
67
+ slack: ['json'],
68
+ airbrake: ['airbrake']
69
+ }.freeze
64
70
  CONTACT_LOAD_SUCCESS = {}
65
71
 
66
72
  def load_contact(name)
@@ -71,16 +77,10 @@ if $load_god
71
77
  end
72
78
 
73
79
  require 'god/contact'
74
- load_contact(:campfire)
75
80
  load_contact(:email)
76
- load_contact(:prowl)
77
- load_contact(:scout)
78
- load_contact(:statsd)
79
- load_contact(:twitter)
80
81
  load_contact(:webhook)
81
82
  load_contact(:airbrake)
82
83
  load_contact(:slack)
83
- load_contact(:sensu)
84
84
 
85
85
  $LOAD_PATH.unshift File.join(File.dirname(__FILE__), *%w[.. ext god])
86
86
 
@@ -124,7 +124,7 @@ if $load_god
124
124
  class Module
125
125
  def safe_attr_accessor(*args)
126
126
  args.each do |arg|
127
- define_method("#{arg}=".intern) do |other|
127
+ define_method(:"#{arg}=") do |other|
128
128
  abort "God.#{arg} must be set before any Tasks are defined" if !running && inited
129
129
 
130
130
  if running && inited
@@ -132,11 +132,11 @@ if $load_god
132
132
  return
133
133
  end
134
134
 
135
- instance_variable_set("@#{arg}".intern, other)
135
+ instance_variable_set(:"@#{arg}", other)
136
136
  end
137
137
 
138
138
  define_method(arg) do
139
- instance_variable_get("@#{arg}".intern)
139
+ instance_variable_get(:"@#{arg}")
140
140
  end
141
141
  end
142
142
  end
@@ -168,7 +168,7 @@ if $load_god
168
168
  STOP_TIMEOUT_DEFAULT = 10
169
169
 
170
170
  # The default String signal to send for the stop command.
171
- STOP_SIGNAL_DEFAULT = 'TERM'.freeze
171
+ STOP_SIGNAL_DEFAULT = 'TERM'
172
172
 
173
173
  class << self
174
174
  # user configurable
@@ -461,7 +461,7 @@ if $load_god
461
461
  # Returns true on success, false if all tasks could not be stopped within 10
462
462
  # seconds
463
463
  def self.stop_all
464
- watches.sort.each do |_name, w|
464
+ watches.sort.each do |(_name, w)|
465
465
  Thread.new do
466
466
  w.action(:stop)
467
467
  w.unmonitor if w.state != :unmonitored
@@ -553,7 +553,7 @@ if $load_god
553
553
  # from the system (if 'remove' or 'stop' was
554
554
  # specified as the action).
555
555
  def self.running_load(code, filename, action = nil)
556
- errors = ''
556
+ error_message = +''
557
557
  loaded_watches = []
558
558
  unloaded_watches = []
559
559
  jobs = []
@@ -598,17 +598,17 @@ if $load_god
598
598
  LOG.finish_capture
599
599
  rescue Exception => e
600
600
  # Don't ever let running_load take down god.
601
- errors << LOG.finish_capture
601
+ error_message << LOG.finish_capture
602
602
 
603
603
  unless e.instance_of?(SystemExit)
604
- errors << e.message << "\n"
605
- errors << e.backtrace.join("\n")
604
+ error_message << e.message << "\n"
605
+ error_message << e.backtrace.join("\n")
606
606
  end
607
607
  end
608
608
 
609
609
  jobs.each(&:join)
610
610
 
611
- [loaded_watches, errors, unloaded_watches]
611
+ [loaded_watches, error_message, unloaded_watches]
612
612
  end
613
613
 
614
614
  # Load the given file(s) according to the given glob.
metadata CHANGED
@@ -1,18 +1,46 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: resurrected_god
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Preston-Werner
8
8
  - Kevin Clark
9
9
  - Eric Lindvall
10
10
  - mishina2228
11
- autorequire:
11
+ autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2022-06-21 00:00:00.000000000 Z
15
- dependencies: []
14
+ date: 2023-12-29 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: drb
18
+ requirement: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - "~>"
21
+ - !ruby/object:Gem::Version
22
+ version: '2.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '2.0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: syslog
32
+ requirement: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - "~>"
35
+ - !ruby/object:Gem::Version
36
+ version: '0.1'
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '0.1'
16
44
  description: An easy to configure, easy to extend monitoring framework written in
17
45
  Ruby.
18
46
  email:
@@ -22,8 +50,7 @@ executables:
22
50
  - god
23
51
  extensions:
24
52
  - ext/god/extconf.rb
25
- extra_rdoc_files:
26
- - README.md
53
+ extra_rdoc_files: []
27
54
  files:
28
55
  - History.md
29
56
  - LICENSE
@@ -59,14 +86,8 @@ files:
59
86
  - lib/god/configurable.rb
60
87
  - lib/god/contact.rb
61
88
  - lib/god/contacts/airbrake.rb
62
- - lib/god/contacts/campfire.rb
63
89
  - lib/god/contacts/email.rb
64
- - lib/god/contacts/prowl.rb
65
- - lib/god/contacts/scout.rb
66
- - lib/god/contacts/sensu.rb
67
90
  - lib/god/contacts/slack.rb
68
- - lib/god/contacts/statsd.rb
69
- - lib/god/contacts/twitter.rb
70
91
  - lib/god/contacts/webhook.rb
71
92
  - lib/god/driver.rb
72
93
  - lib/god/errors.rb
@@ -98,10 +119,9 @@ metadata:
98
119
  changelog_uri: https://github.com/mishina2228/resurrected_god/blob/master/History.md
99
120
  homepage_uri: https://github.com/mishina2228/resurrected_god
100
121
  rubygems_mfa_required: 'true'
101
- source_code_uri: https://github.com/mishina2228/resurrected_god/tree/v1.0.0
102
- post_install_message:
103
- rdoc_options:
104
- - "--charset=UTF-8"
122
+ source_code_uri: https://github.com/mishina2228/resurrected_god/tree/v1.1.1
123
+ post_install_message:
124
+ rdoc_options: []
105
125
  require_paths:
106
126
  - lib
107
127
  - ext
@@ -116,8 +136,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
116
136
  - !ruby/object:Gem::Version
117
137
  version: '0'
118
138
  requirements: []
119
- rubygems_version: 3.3.7
120
- signing_key:
139
+ rubygems_version: 3.4.10
140
+ signing_key:
121
141
  specification_version: 4
122
142
  summary: Process monitoring framework.
123
143
  test_files: []
@@ -1,119 +0,0 @@
1
- # Send a notice to a Campfire room (http://campfirenow.com).
2
- #
3
- # subdomain - The String subdomain of the Campfire account. If your URL is
4
- # "foo.campfirenow.com" then your subdomain is "foo".
5
- # token - The String token used for authentication.
6
- # room - The String room name to which the message should be sent.
7
- # ssl - A Boolean determining whether or not to use SSL
8
- # (default: false).
9
-
10
- require 'net/http'
11
- require 'net/https'
12
-
13
- CONTACT_DEPS[:campfire] = ['json']
14
- CONTACT_DEPS[:campfire].each do |d|
15
- require d
16
- end
17
-
18
- module Marshmallow
19
- class Connection
20
- def initialize(options)
21
- raise 'Required option :subdomain not set.' unless options[:subdomain]
22
- raise 'Required option :token not set.' unless options[:token]
23
-
24
- @options = options
25
- end
26
-
27
- def base_url
28
- scheme = @options[:ssl] ? 'https' : 'http'
29
- subdomain = @options[:subdomain]
30
- "#{scheme}://#{subdomain}.campfirenow.com"
31
- end
32
-
33
- def find_room_id_by_name(room)
34
- url = URI.parse("#{base_url}/rooms.json")
35
-
36
- http = Net::HTTP.new(url.host, url.port)
37
- http.use_ssl = true if @options[:ssl]
38
-
39
- req = Net::HTTP::Get.new(url.path)
40
- req.basic_auth(@options[:token], 'X')
41
-
42
- res = http.request(req)
43
- case res
44
- when Net::HTTPSuccess
45
- rooms = JSON.parse(res.body)
46
- room = rooms['rooms'].select { |x| x['name'] == room }
47
- rooms.empty? ? nil : room.first['id']
48
- else
49
- raise res.error!
50
- end
51
- end
52
-
53
- def speak(room, message)
54
- room_id = find_room_id_by_name(room)
55
- raise "No such room: #{room}." unless room_id
56
-
57
- url = URI.parse("#{base_url}/room/#{room_id}/speak.json")
58
-
59
- http = Net::HTTP.new(url.host, url.port)
60
- http.use_ssl = true if @options[:ssl]
61
-
62
- req = Net::HTTP::Post.new(url.path)
63
- req.basic_auth(@options[:token], 'X')
64
- req.set_content_type('application/json')
65
- req.body = { 'message' => { 'body' => message } }.to_json
66
-
67
- res = http.request(req)
68
- case res
69
- when Net::HTTPSuccess
70
- true
71
- else
72
- raise res.error!
73
- end
74
- end
75
- end
76
- end
77
-
78
- module God
79
- module Contacts
80
- class Campfire < Contact
81
- class << self
82
- attr_accessor :subdomain, :token, :room, :ssl, :format
83
- end
84
-
85
- self.ssl = false
86
-
87
- self.format = lambda do |message, time, _priority, _category, host|
88
- "[#{time.strftime('%H:%M:%S')}] #{host} - #{message}"
89
- end
90
-
91
- attr_accessor :subdomain, :token, :room, :ssl
92
-
93
- def valid?
94
- valid = true
95
- valid &= complain("Attribute 'subdomain' must be specified", self) unless arg(:subdomain)
96
- valid &= complain("Attribute 'token' must be specified", self) unless arg(:token)
97
- valid &= complain("Attribute 'room' must be specified", self) unless arg(:room)
98
- valid
99
- end
100
-
101
- def notify(message, time, priority, category, host)
102
- body = Campfire.format.call(message, time, priority, category, host)
103
-
104
- conn = Marshmallow::Connection.new(
105
- subdomain: arg(:subdomain),
106
- token: arg(:token),
107
- ssl: arg(:ssl)
108
- )
109
-
110
- conn.speak(arg(:room), body)
111
-
112
- self.info = "notified campfire: #{arg(:subdomain)}"
113
- rescue Object => e
114
- applog(nil, :info, "failed to notify campfire: #{e.message}")
115
- applog(nil, :debug, e.backtrace.join("\n"))
116
- end
117
- end
118
- end
119
- end
@@ -1,56 +0,0 @@
1
- # Send a notice to Prowl (http://prowl.weks.net/).
2
- #
3
- # apikey - The String API key.
4
-
5
- CONTACT_DEPS[:prowl] = ['prowly']
6
- CONTACT_DEPS[:prowl].each do |d|
7
- require d
8
- end
9
-
10
- module God
11
- module Contacts
12
- class Prowl < Contact
13
- class << self
14
- attr_accessor :apikey
15
- end
16
-
17
- def valid?
18
- valid = true
19
- valid &= complain("Attribute 'apikey' must be specified", self) if apikey.nil?
20
- valid
21
- end
22
-
23
- attr_accessor :apikey
24
-
25
- def notify(message, time, priority, category, host)
26
- result = Prowly.notify do |n|
27
- n.apikey = arg(:apikey)
28
- n.priority = map_priority(priority.to_i)
29
- n.application = category || 'God'
30
- n.event = "on #{host}"
31
- n.description = "#{message} at #{time}"
32
- end
33
-
34
- self.info = if result.succeeded?
35
- "sent prowl notification to #{name}"
36
- else
37
- "failed to send prowl notification to #{name}: #{result.message}"
38
- end
39
- rescue Object => e
40
- applog(nil, :info, "failed to send prowl notification to #{name}: #{e.message}")
41
- applog(nil, :debug, e.backtrace.join("\n"))
42
- end
43
-
44
- def map_priority(priority)
45
- case priority
46
- when 1 then Prowly::Notification::Priority::EMERGENCY
47
- when 2 then Prowly::Notification::Priority::HIGH
48
- when 3 then Prowly::Notification::Priority::NORMAL
49
- when 4 then Prowly::Notification::Priority::MODERATE
50
- when 5 then Prowly::Notification::Priority::VERY_LOW
51
- else Prowly::Notification::Priority::NORMAL
52
- end
53
- end
54
- end
55
- end
56
- end
@@ -1,52 +0,0 @@
1
- # Send a notice to Scout (http://scoutapp.com/).
2
- #
3
- # client_key - The String client key.
4
- # plugin_id - The String plugin id.
5
-
6
- require 'net/http'
7
- require 'uri'
8
-
9
- module God
10
- module Contacts
11
- class Scout < Contact
12
- class << self
13
- attr_accessor :client_key, :plugin_id, :format
14
- end
15
-
16
- self.format = lambda do |message, priority, category, host|
17
- text = "Message: #{message}\n"
18
- text += "Host: #{host}\n" if host
19
- text += "Priority: #{priority}\n" if priority
20
- text += "Category: #{category}\n" if category
21
- return text
22
- end
23
-
24
- attr_accessor :client_key, :plugin_id
25
-
26
- def valid?
27
- valid = true
28
- valid &= complain("Attribute 'client_key' must be specified", self) unless arg(:client_key)
29
- valid &= complain("Attribute 'plugin_id' must be specified", self) unless arg(:plugin_id)
30
- valid
31
- end
32
-
33
- def notify(message, _time, priority, category, host)
34
- data = {
35
- :client_key => arg(:client_key),
36
- :plugin_id => arg(:plugin_id),
37
- :format => 'xml',
38
- 'alert[subject]' => message,
39
- 'alert[body]' => Scout.format.call(message, priority, category, host)
40
- }
41
-
42
- uri = URI.parse('http://scoutapp.com/alerts/create')
43
- Net::HTTP.post_form(uri, data)
44
-
45
- self.info = "sent scout alert to plugin ##{plugin_id}"
46
- rescue => e
47
- applog(nil, :info, "failed to send scout alert to plugin ##{plugin_id}: #{e.message}")
48
- applog(nil, :debug, e.backtrace.join("\n"))
49
- end
50
- end
51
- end
52
- end
@@ -1,63 +0,0 @@
1
- # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2
- # Send a notice to a SENSU client socket, port 3030 on 'localhost' only.
3
- # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4
- # [mandatory]
5
- # check_name - a unique check name
6
- #
7
- # [optional]
8
- # status_code - status codes used are 0 for OK, 1 for WARNING, 2 for CRITICAL, and 3 or greater to indicate UNKNOWN or CUSTOM.
9
- # handler - default handler
10
- #
11
-
12
- CONTACT_DEPS[:sensu] = ['json']
13
- CONTACT_DEPS[:sensu].each do |d|
14
- require d
15
- end
16
-
17
- module God
18
- module Contacts
19
- class Sensu < Contact
20
- class << self
21
- attr_accessor :check_name, :status_code, :handler, :host, :port
22
- end
23
-
24
- self.status_code = 2
25
- self.handler = 'default'
26
- self.host = 'localhost'
27
- self.port = 3030
28
-
29
- def valid?
30
- valid = true
31
- valid &= complain("Attribute 'check_name' must be specified", self) unless arg(:check_name)
32
- valid
33
- end
34
-
35
- attr_accessor :check_name, :status_code, :handler, :host, :port
36
-
37
- def sensu_client_socket(msg)
38
- u = UDPSocket.new
39
- u.send("#{msg}\n", 0, arg(:host).nil? ? host : arg(:host), arg(:port).nil? ? port : arg(:port))
40
- u.close
41
- end
42
-
43
- def notify(message, time, priority, category, host)
44
- data = {
45
- category: category,
46
- message: message,
47
- priority: priority,
48
- host: host,
49
- time: time
50
- }
51
- parcel = {
52
- 'name' => arg(:check_name),
53
- 'status' => arg(:status_code).nil? ? status_code : arg(:status_code),
54
- 'output' => data.to_json,
55
- 'handler' => arg(:handler).empty? ? handler : arg(:handler),
56
- 'executed' => Time.now.to_i
57
- }
58
- sensu_client_socket parcel.to_json
59
- self.info = "notified sensu: #{arg(:check_name)}"
60
- end
61
- end
62
- end
63
- end
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Send a notice to statsd
4
- #
5
- # host - statsd host
6
- # port - statsd port (optional)
7
-
8
- require 'statsd-ruby'
9
-
10
- module God
11
- module Contacts
12
- class Statsd < Contact
13
- class << self
14
- attr_accessor :host, :port
15
- end
16
-
17
- attr_accessor :host, :port
18
-
19
- def valid?
20
- valid = true
21
- valid &= complain("Attribute 'statsd_host' must be specified", self) unless arg(:host)
22
- valid
23
- end
24
-
25
- def notify(message, _time, _priority, _category, hostname)
26
- statsd = ::Statsd.new host, (port ? port.to_i : 8125) # 8125 is the default statsd port
27
-
28
- hostname = hostname.tr('.', '_')
29
- app = message.gsub(/([^\s]*).*/, '\1')
30
-
31
- [
32
- 'cpu out of bounds',
33
- 'memory out of bounds',
34
- 'process is flapping'
35
- ].each do |event_type|
36
- statsd.increment "god.#{event_type.gsub(/\s/, '_')}.#{hostname}.#{app}" if message.include? event_type
37
- end
38
-
39
- self.info = 'sent statsd alert'
40
- rescue => e
41
- applog(nil, :info, "failed to send statsd alert: #{e.message}")
42
- applog(nil, :debug, e.backtrace.join("\n"))
43
- end
44
- end
45
- end
46
- end
@@ -1,51 +0,0 @@
1
- # Send a notice to a Twitter account (http://twitter.com/).
2
- #
3
- # consumer_token - The String OAuth consumer token (defaults to God's
4
- # existing consumer token).
5
- # consumer_secret - The String OAuth consumer secret (defaults to God's
6
- # existing consumer secret).
7
- # access_token - The String OAuth access token.
8
- # access_secret - The String OAuth access secret.
9
-
10
- CONTACT_DEPS[:twitter] = ['twitter']
11
- CONTACT_DEPS[:twitter].each do |d|
12
- require d
13
- end
14
-
15
- module God
16
- module Contacts
17
- class Twitter < Contact
18
- class << self
19
- attr_accessor :consumer_token, :consumer_secret,
20
- :access_token, :access_secret
21
- end
22
-
23
- self.consumer_token = 'gOhjax6s0L3mLeaTtBWPw'
24
- self.consumer_secret = 'yz4gpAVXJHKxvsGK85tEyzQJ7o2FEy27H1KEWL75jfA'
25
-
26
- def valid?
27
- valid = true
28
- valid &= complain("Attribute 'consumer_token' must be specified", self) unless arg(:consumer_token)
29
- valid &= complain("Attribute 'consumer_secret' must be specified", self) unless arg(:consumer_secret)
30
- valid &= complain("Attribute 'access_token' must be specified", self) unless arg(:access_token)
31
- valid &= complain("Attribute 'access_secret' must be specified", self) unless arg(:access_secret)
32
- valid
33
- end
34
-
35
- attr_accessor :consumer_token, :consumer_secret,
36
- :access_token, :access_secret
37
-
38
- def notify(message, _time, _priority, _category, _host)
39
- oauth = ::Twitter::OAuth.new(arg(:consumer_token), arg(:consumer_secret))
40
- oauth.authorize_from_access(arg(:access_token), arg(:access_secret))
41
-
42
- ::Twitter::Base.new(oauth).update(message)
43
-
44
- self.info = 'sent twitter update'
45
- rescue => e
46
- applog(nil, :info, "failed to send twitter update: #{e.message}")
47
- applog(nil, :debug, e.backtrace.join("\n"))
48
- end
49
- end
50
- end
51
- end