blob: 8f32c9ad7d8c3c513183f3ecea88413ca75343bd [file]
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License
#ifndef __PROCESS_SYSTEM_HPP__
#define __PROCESS_SYSTEM_HPP__
#include <string>
#include <process/future.hpp>
#include <process/help.hpp>
#include <process/http.hpp>
#include <process/process.hpp>
#include <process/metrics/pull_gauge.hpp>
#include <process/metrics/metrics.hpp>
#include <stout/os.hpp>
namespace process {
// The System process provides HTTP endpoints for retrieving system metrics,
// such as CPU load and memory usage. This is started by default during the
// initialization of libprocess.
class System : public Process<System>
{
public:
System()
: ProcessBase("system"),
load_1min(
self().id + "/load_1min",
defer(self(), &System::_load_1min)),
load_5min(
self().id + "/load_5min",
defer(self(), &System::_load_5min)),
load_15min(
self().id + "/load_15min",
defer(self(), &System::_load_15min)),
cpus_total(
self().id + "/cpus_total",
defer(self(), &System::_cpus_total)),
mem_total_bytes(
self().id + "/mem_total_bytes",
defer(self(), &System::_mem_total_bytes)),
mem_free_bytes(
self().id + "/mem_free_bytes",
defer(self(), &System::_mem_free_bytes)) {}
~System() override {}
protected:
void initialize() override
{
// TODO(dhamon): Check return values.
metrics::add(load_1min);
metrics::add(load_5min);
metrics::add(load_15min);
metrics::add(cpus_total);
metrics::add(mem_total_bytes);
metrics::add(mem_free_bytes);
route("/stats.json", statsHelp(), &System::stats);
}
void finalize() override
{
metrics::remove(load_1min);
metrics::remove(load_5min);
metrics::remove(load_15min);
metrics::remove(cpus_total);
metrics::remove(mem_total_bytes);
metrics::remove(mem_free_bytes);
}
private:
static std::string statsHelp()
{
return HELP(
TLDR(
"Shows local system metrics."),
DESCRIPTION(
"> cpus_total Total number of available CPUs",
"> load_1min Average system load for last"
" minute in uptime(1) style",
"> load_5min Average system load for last"
" 5 minutes in uptime(1) style",
"> load_15min Average system load for last"
" 15 minutes in uptime(1) style",
"> memory_total_bytes Total system memory in bytes",
"> memory_free_bytes Free system memory in bytes"));
}
// Gauge handlers.
Future<double> _load_1min()
{
Try<os::Load> load = os::loadavg();
if (load.isSome()) {
return load->one;
}
return Failure("Failed to get loadavg: " + load.error());
}
Future<double> _load_5min()
{
Try<os::Load> load = os::loadavg();
if (load.isSome()) {
return load->five;
}
return Failure("Failed to get loadavg: " + load.error());
}
Future<double> _load_15min()
{
Try<os::Load> load = os::loadavg();
if (load.isSome()) {
return load->fifteen;
}
return Failure("Failed to get loadavg: " + load.error());
}
Future<double> _cpus_total()
{
Try<long> cpus = os::cpus();
if (cpus.isSome()) {
return cpus.get();
}
return Failure("Failed to get cpus: " + cpus.error());
}
Future<double> _mem_total_bytes()
{
Try<os::Memory> memory = os::memory();
if (memory.isSome()) {
return static_cast<double>(memory->total.bytes());
}
return Failure("Failed to get memory: " + memory.error());
}
Future<double> _mem_free_bytes()
{
Try<os::Memory> memory = os::memory();
if (memory.isSome()) {
return static_cast<double>(memory->free.bytes());
}
return Failure("Failed to get memory: " + memory.error());
}
// HTTP endpoints.
Future<http::Response> stats(const http::Request& request)
{
JSON::Object object;
Try<os::Load> load = os::loadavg();
if (load.isSome()) {
object.values["avg_load_1min"] = load->one;
object.values["avg_load_5min"] = load->five;
object.values["avg_load_15min"] = load->fifteen;
}
Try<long> cpus = os::cpus();
if (cpus.isSome()) {
object.values["cpus_total"] = cpus.get();
}
Try<os::Memory> memory = os::memory();
if (memory.isSome()) {
object.values["mem_total_bytes"] = memory->total.bytes();
object.values["mem_free_bytes"] = memory->free.bytes();
}
return http::OK(object, request.url.query.get("jsonp"));
}
metrics::PullGauge load_1min;
metrics::PullGauge load_5min;
metrics::PullGauge load_15min;
metrics::PullGauge cpus_total;
metrics::PullGauge mem_total_bytes;
metrics::PullGauge mem_free_bytes;
};
} // namespace process {
#endif // __PROCESS_SYSTEM_HPP__