Suppose we have apps running on CloudFoundry, how can we get the stats of app and doing some analysis here?
vmc stats appname is really useful. But what we need is a component which returns a json result according to a sepecific URL.
According to the code of CF, we can find there's something useful here:
https://github.com/cloudfoundry/vcap-common/blob/master/lib/vcap/component.rb#L44
#Common component setup for discovery and monitoring
During the start process of router, an endpoint of var component will be startup for /varz or /healthz
The method register(opts) will be called in router.rb:
# Register ourselves with the system
status_config = config['status'] || {}
VCAP::Component.register(:type => 'Router',
:host => VCAP.local_ip(config['local_route']),
:index => config['index'],
:config => config,
:port => status_config['port'],
:user => status_config['user'],
:password => status_config['password'],
:logger => Router.log)
The method to start a server is below, so if we can request this server with /varz, the stats will be returned.
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
We can see Thin is is used here to start a http server.
So, we need to figure out the port and host on which the server is running. Actually, this things is customizable. We can find this in dea.yml
# Used for /healthz and /vars endpoints. If not provided random
# values will be generated on component start. Uncomment to use
# static values.
#status:
# port: 34501
# user: thin
# password: thin
That means we can specify its port and auth before we start a DEA, just add status part in your config file, and then:
Sending http request to that server will return you a JSON response which contains a key named "running apps", its value what you need!
What's more, in
.../cloudfoundry/.deployments/devbox/deploy/rubies/ruby-1.9.2-p180/lib/ruby/gems/1.9.1/gems/vcap_common-1.0.10/lib/vcap/component.rb
we can see how these parameters before to be used to register itself into your local vcap environment:
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)
# Discover message limited
@discover = {
:type => type,
:index => index,
:uuid => uuid,
:host => "#{host}:#{port}",
:credentials => auth,
:start => Time.now
}
# Varz is customizable
@varz = @discover.dup
@varz[:num_cores] = VCAP.num_cores
@varz[:config] = sanitize_config(opts[:config]) if opts[:config]
@healthz = "ok\n".freeze
... ...
But the rest of this part requires some knowledge of EventMachine. So we'll talk about it later.