Class: VCAP::Component

Inherits:
Object
  • Object
show all
Defined in:
lib/vcap/component.rb

Overview

Common component setup for discovery and monitoring

Defined Under Namespace

Classes: SafeHash

Constant Summary collapse

CONFIG_SUPPRESS =

We will suppress these from normal varz reporting by default.

Set.new([:message_bus_servers, :mbus, :service_mbus, :keys, :database_environment, :password, :pass, :token])

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.healthzObject

Returns the value of attribute healthz.



94
95
96
# File 'lib/vcap/component.rb', line 94

def healthz
  @healthz
end

Class Method Details

.clear_level(h) ⇒ Object



213
214
215
216
217
218
219
220
221
# File 'lib/vcap/component.rb', line 213

def clear_level(h)
  h.each do |k, v|
    if CONFIG_SUPPRESS.include?(k.to_sym)
      h.delete(k)
    else
      clear_level(h[k]) if v.instance_of? Hash
    end
  end
end

.register(opts) ⇒ Object

Announces the availability of this component to NATS. Returns the published configuration of the component, including the ephemeral port and credentials.



159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/vcap/component.rb', line 159

def register(opts)
  uuid = VCAP.secure_uuid
  type = opts[:type]
  index = opts[:index]
  uuid = "#{index}-#{uuid}" if index
  host = opts[:host] || VCAP.local_ip
  port = opts[:port] || VCAP.grab_ephemeral_port
  nats = opts[:nats] || NATS
  auth = [opts[:user] || VCAP.secure_uuid, opts[:password] || VCAP.secure_uuid]
  logger = opts[:logger] || Logger.new(nil)
  log_counter = opts[:log_counter]

  # Discover message limited
  @discover = {
    :type => type,
    :index => index,
    :uuid => uuid,
    :host => "#{host}:#{port}",
    :credentials => auth,
    :start => Time.now
  }

  # Varz is customizable
  varz.synchronize do
    varz.merge!(@discover.dup)
    varz[:num_cores] = VCAP.num_cores
    varz[:config] = sanitize_config(opts[:config]) if opts[:config]
    varz[:log_counts] = log_counter if log_counter
  end

  @healthz = "ok\n".freeze

  # Next steps require EM
  raise "EventMachine reactor needs to be running" if !EventMachine.reactor_running?

  # Startup the http endpoint for /varz and /healthz
  start_http_server(host, port, auth, logger)

  # Listen for discovery requests
  nats.subscribe('vcap.component.discover') do |msg, reply|
    update_discover_uptime
    nats.publish(reply, @discover.to_json)
  end

  # Also announce ourselves on startup..
  nats.publish('vcap.component.announce', @discover.to_json)

  @discover
end

.sanitize_config(config) ⇒ Object



223
224
225
226
227
228
229
230
231
232
233
# File 'lib/vcap/component.rb', line 223

def sanitize_config(config)
  # Can't Marshal/Deep Copy logger instances that services use
  if config[:logger]
    config = config.dup
    config.delete(:logger)
  end
  # Deep copy
  config = Marshal.load(Marshal.dump(config))
  clear_level(config)
  config
end

.start_http_server(host, port, auth, logger) ⇒ Object



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/vcap/component.rb', line 136

def start_http_server(host, port, auth, logger)
  http_server = Thin::Server.new(host, port, :signals => false) do
    Thin::Logging.silent = true
    use Rack::Auth::Basic do |username, password|
      [username, password] == auth
    end
    map '/healthz' do
      run Healthz.new(logger)
    end
    map '/varz' do
      run Varz.new(logger)
    end
  end
  http_server.start!
end

.update_discover_uptimeObject



209
210
211
# File 'lib/vcap/component.rb', line 209

def update_discover_uptime
  @discover[:uptime] = VCAP.uptime_string(Time.now - @discover[:start])
end

.updated_healthzObject



126
127
128
129
130
131
132
133
134
# File 'lib/vcap/component.rb', line 126

def updated_healthz
  @last_healthz_update ||= 0

  if Time.now.to_f - @last_healthz_update >= 1
    @last_healthz_update = Time.now.to_f
  end

  healthz.dup
end

.updated_varzObject



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/vcap/component.rb', line 96

def updated_varz
  @last_varz_update ||= 0

  if Time.now.to_f - @last_varz_update >= 1
    rss, pcpu = Stats.process_memory_and_cpu

    # Update varz
    varz.synchronize do
      @last_varz_update = Time.now.to_f

      varz[:uptime] = VCAP.uptime_string(Time.now - varz[:start])
      varz[:mem] = rss.to_i
      varz[:cpu] = pcpu.to_f

      varz[:mem_used_bytes] = Stats.memory_used_bytes
      varz[:mem_free_bytes] = Stats.memory_free_bytes

      varz[:cpu_load_avg] = Stats.cpu_load_average

      # Return duplicate while holding lock
      return varz.dup
    end
  else
    # Return duplicate while holding lock
    varz.synchronize do
      return varz.dup
    end
  end
end

.uuidObject



152
153
154
# File 'lib/vcap/component.rb', line 152

def uuid
  @discover[:uuid]
end

.varzObject



90
91
92
# File 'lib/vcap/component.rb', line 90

def varz
  @varz ||= SafeHash.new
end