Module: Salus

Extended by:
Configuration, Logging
Defined in:
lib/salus/thread/pool.rb,
lib/salus.rb,
lib/salus/cli.rb,
lib/salus/group.rb,
lib/salus/metric.rb,
lib/salus/zabbix.rb,
lib/salus/logging.rb,
lib/salus/version.rb,
lib/salus/cli/zabbix.rb,
lib/salus/thread/cpu.rb,
lib/salus/metric/text.rb,
lib/salus/metric/delta.rb,
lib/salus/metric/gauge.rb,
lib/salus/thread/latch.rb,
lib/salus/cli/baseutils.rb,
lib/salus/configuration.rb,
lib/salus/metric/derive.rb,
lib/salus/renderer/base.rb,
lib/salus/thread/future.rb,
lib/salus/metric/counter.rb,
lib/salus/renderer/block.rb,
lib/salus/metric/absolute.rb,
lib/salus/renderer/stdout.rb,
lib/salus/thread/lockable.rb,
lib/salus/renderer/collectd.rb,
lib/salus/renderer/graphite.rb,
lib/salus/thread/observable.rb,
lib/salus/metric/accumulator.rb,
lib/salus/renderer/zabbixbulk.rb,
lib/salus/thread/monotonictime.rb,
lib/salus/renderer/zabbixsender.rb

Overview

A future is an object that incapsulates a block which is called in a different thread, upon retrieval the caller gets blocked until the block has finished running, and its result is returned and cached.

Defined Under Namespace

Modules: BaseCliUtils, Configuration, Lockable, Logging, Observable Classes: Absolute, Accumulator, BaseRenderer, BlockRenderer, CLI, CPU, CollectdRenderer, CountDownLatch, Counter, Delta, Derive, Fifo, Future, Gauge, GraphiteRenderer, Group, Metric, MonotonicTime, ObserversSet, StdoutRenderer, Text, ThreadPool, ZabbixBulkRenderer, ZabbixCacheRenderer, ZabbixCli, ZabbixSenderRenderer

Constant Summary collapse

VERSION =
"0.2.1"
@@_groups =
{}
@@_renders =
[]
@@_opts =
{}
@@_vars =
{}
@@_lazy =
[]
@@_discovers =
{}

Constants included from Configuration

Configuration::VALID_OPTIONS_KEYS

Class Method Summary collapse

Methods included from Logging

log

Methods included from Configuration

configure, extended, options, reset

Class Method Details

.default(opts) ⇒ Object



34
35
36
37
38
39
40
# File 'lib/salus.rb', line 34

def default(opts)
  return unless opts.is_a?(Hash)
  opts.each do |k, v|
    next if [:value, :timestamp].include?(k)
    @@_opts[k] = v
  end
end

.defaultsObject



42
43
44
# File 'lib/salus.rb', line 42

def defaults
  @@_opts
end

.discover(name, &block) ⇒ Object

Raises:

  • (ArgumentError)


7
8
9
10
# File 'lib/salus/zabbix.rb', line 7

def discover(name, &block)
  raise ArgumentError, "Block should be given" unless block_given?
  @@_discovers[name] = block
end

.discoversObject



12
13
14
# File 'lib/salus/zabbix.rb', line 12

def discovers
  @@_discovers
end

.discovery(name) ⇒ Object



16
17
18
19
20
21
# File 'lib/salus/zabbix.rb', line 16

def discovery(name)
  return unless @@_discovers.key?(name)
  data = []
  @@_discovers[name].call(data)
  {data: data}.to_json
end

.group(title, &block) ⇒ Object



23
24
25
26
27
# File 'lib/salus.rb', line 23

def group(title, &block)
  unless @@_groups.key?(title)
    @@_groups[title] = Group.new(@@_opts, &block)
  end
end

.groupsObject Also known as: root



29
30
31
# File 'lib/salus.rb', line 29

def groups
  @@_groups
end

.lazy(&block) ⇒ Object

Raises:

  • (ArgumentError)


99
100
101
102
# File 'lib/salus.rb', line 99

def lazy(&block)
  raise ArgumentError, "Block should be given" unless block_given?
  @@_lazy << block
end

.lazy_evalObject



104
105
106
107
108
109
# File 'lib/salus.rb', line 104

def lazy_eval
  # Lazy eval blocks once
  return if @@_lazy.empty?
  @@_lazy.each { |block| instance_eval(&block) }
  @@_lazy.clear
end

.load(file) ⇒ Object



111
112
113
# File 'lib/salus.rb', line 111

def load(file)
  instance_eval(File.read(file), File.basename(file), 0) if File.exists?(file)
end

.load_state(&block) ⇒ Object



115
116
117
118
119
120
121
122
123
# File 'lib/salus.rb', line 115

def load_state(&block)
  data = block.call
  return unless data
  return if data.empty?
  lazy_eval
  data.each do |k, v|
    @@_groups[k].load(v) if @@_groups.key?(k)
  end
end

.on_win?Boolean

Returns:

  • (Boolean)


19
20
21
# File 'lib/salus.rb', line 19

def on_win?
  @@_win ||= !(RUBY_PLATFORM =~ /bccwin|cygwin|djgpp|mingw|mswin|wince/i).nil?
end

.render(obj = nil, &block) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
# File 'lib/salus.rb', line 71

def render(obj=nil, &block)
  if block_given?
    @@_renders << BlockRenderer.new(&block)
  else
    unless obj.is_a? Salus::BaseRenderer
      log ERROR, "#{obj.class} must be a subclass of Salus::BaseRenderer"
      return
    end
    @@_renders << obj
  end
end

.rendersObject



83
84
85
# File 'lib/salus.rb', line 83

def renders
  @@_renders
end

.resetObject



87
88
89
90
91
92
93
94
95
96
97
# File 'lib/salus.rb', line 87

def reset
  @@_groups  = {}
  @@_renders = []
  @@_opts    = {}
  @@_vars    = {}
  @@_lazy    = []
  if defined?(@@_pool) && @@_pool.is_a?(Salus::ThreadPool)
    @@_pool.shutdown!
    @@_pool = nil
  end
end

.runObject



172
173
174
175
176
177
178
179
# File 'lib/salus.rb', line 172

def run
  loop do
    pool.process do
      tick
    end
    sleep Salus.interval
  end
end

.save_state(&block) ⇒ Object



125
126
127
128
129
# File 'lib/salus.rb', line 125

def save_state(&block)
  data = {}
  @@_groups.each { |k, v| data[k]  = v.to_h }
  block.call(data)
end

.tickObject



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/salus.rb', line 131

def tick
  log DEBUG, "Tick..."
  lazy_eval
  return if @@_groups.empty?
  pause = (Salus.interval - Salus.tick_timeout - Salus.render_timeout) / 2
  pause = 1 if (pause <= 0)

  log DEBUG, "Starting collection. Top-level groups to spawn: #{@@_groups.count}"
  latch = CountDownLatch.new(@@_groups.count)
  @@_groups.each do |k, v|
    pool.process do
      begin
        v.tick
        latch.count_down
      rescue Exception => e
        log ERROR, e
        latch.count_down
      end
    end.timeout_after(Salus.tick_timeout)
  end
  latch.wait(Salus.tick_timeout + pause)
  log DEBUG, "Collection finished. Threads: #{pool.spawned} spawned, #{pool.waiting} waiting, #{Thread.list.count} total"

  return if @@_renders.empty?
  log DEBUG, "Starting #{@@_renders.count} renderers"
  latch = CountDownLatch.new(@@_renders.count)
  @@_renders.each do |v|
    pool.process do
      begin
        v.render(root)
        latch.count_down
      rescue Exception => e
        log ERROR, e
        latch.count_down
      end
    end.timeout_after(Salus.render_timeout)
  end
  latch.wait(Salus.render_timeout + pause)
  log DEBUG, "Rendering finished. Threads: #{pool.spawned} spawned, #{pool.waiting} waiting, #{Thread.list.count} total"
end

.var(arg, default = nil, &block) ⇒ Object Also known as: let



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/salus.rb', line 46

def var(arg, default=nil, &block)
  if arg.is_a?(Hash)
    arg.each {|k, v| @@_vars[k] = v}
  elsif block_given?
    @@_vars[arg.to_sym] = block
  else
    value = @@_vars.fetch(arg.to_sym, default)
    # Dumb lazy loading
    @@_vars[arg.to_sym] = if value.is_a?(Proc)
      begin
        value = value.call
      rescue Exception => e
        log DEBUG, e
        value = default
      end
    end
    value
  end
end

.varsObject



67
68
69
# File 'lib/salus.rb', line 67

def vars
  @@_vars
end