1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-09 00:00:00 +01:00

api: extend status endpoint

This commit is contained in:
Steffen Vogel 2020-10-15 14:47:43 +02:00
parent 11d1786d9d
commit 8a6902bd90
6 changed files with 184 additions and 19 deletions

View file

@ -58,7 +58,46 @@ paths:
examples:
example1:
value:
{ test: 1 }
state: running
version: v0.10.0
release: 1.node_uuid_unique_debug.20201015git335440d
build_id: v0.10.0-335440d-debug
build_date: '20201015'
hostname: ernie
uuid: c9d64cc7-c6e1-4dd4-8873-126318e9d42c
time_now: 1602765814.9240997
time_started: 1602765814.3103526
timezone:
name: CEST
offset: -3600
dst: true
kernel:
sysname: Linux
nodename: ernie
release: 5.6.17-rt10
version: "#5 SMP Fri Jul 10 14:02:33 CEST 2020"
machine: x86_64
domainname: "(none)"
system:
cores_configured: 28
cores: 28
procecces: 780
uptime: 1379600
load:
- 1.66259765625
- 1.271484375
- 1.18701171875
ram:
total: 269994606592
free: 262204465152
shared: 44191744
buffer: 130211840
swap:
total: 4294963200
free: 4294963200
highmem:
total: 0
free: 0
"/capabilities":
get:

View file

@ -78,6 +78,10 @@ protected:
struct Task task; /**< Task for periodic stats output */
uuid_t uuid; /**< A globally unique identifier of the instance */
struct timespec started; /**< The time at which the instance has been started. */
std::string uri; /**< URI of configuration */
Config config; /** The configuration file. */
@ -156,6 +160,16 @@ public:
return state;
}
void getUUID(uuid_t out) const
{
uuid_copy(out, uuid);
}
struct timespec getStartTime() const
{
return started;
}
#ifdef WITH_API
Api * getApi()
{

View file

@ -89,7 +89,7 @@ void Api::worker()
logger->info("Started worker");
/* Process pending requests */
while (!pending.empty() && running) {
while (running) {
Session *s = pending.pop();
if (s) {
/* Check that the session is still alive */

View file

@ -74,8 +74,7 @@ public:
}
#endif
auto *json_capabilities = json_pack("{ s: s, s: o, s: o, s: o, s: o }",
"build", PROJECT_BUILD_ID,
auto *json_capabilities = json_pack("{ s: o, s: o, s: o, s: o }",
"hooks", json_hooks,
"node-types", json_nodes,
"apis", json_apis,

View file

@ -20,27 +20,49 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************************/
#ifdef LWS_WITH_SERVER_STATUS
#include <jansson.h>
#include <time.h>
#include <uuid/uuid.h>
#include <sys/utsname.h>
#include <sys/sysinfo.h>
#include <villas/timing.h>
#include <villas/api/request.hpp>
#include <villas/api/response.hpp>
#ifndef UUID_STR_LEN
#define UUID_STR_LEN 37
#endif
namespace villas {
namespace node {
namespace api {
class StatusRequest : public Request {
protected:
#ifdef LWS_WITH_SERVER_STATUS
json_t * getLwsStatus()
{
int ret;
struct lws_context *ctx = lws_get_context(session->wsi);
char buf[4096];
ret = lws_json_dump_context(ctx, buf, sizeof(buf), 0);
if (ret)
throw Error();
return json_loads(buf, 0, nullptr);
}
#endif /* LWS_WITH_SERVER_STATUS */
public:
using Request::Request;
virtual Response * execute()
{
int ret;
struct lws_context *ctx = lws_get_context(s->wsi);
char buf[4096];
if (method != Session::Method::GET)
throw InvalidMethod(this);
@ -48,11 +70,83 @@ public:
if (body != nullptr)
throw BadRequest("Status endpoint does not accept any body data");
ret = lws_json_dump_context(ctx, buf, sizeof(buf), 0);
if (ret)
throw Error();
auto *sn = session->getSuperNode();
auto *json_status = json_loads(buf, 0, nullptr);
uuid_t uuid;
struct utsname uts;
struct sysinfo sinfo;
char hname[128];
char uuid_str[UUID_STR_LEN];
sn->getUUID(uuid);
uuid_unparse_lower(uuid, uuid_str);
auto now = time_now();
auto started = sn->getStartTime();
ret = gethostname(hname, sizeof(hname));
if (ret)
throw Error(HTTP_STATUS_INTERNAL_SERVER_ERROR, "Failed to get system hostname");
ret = uname(&uts);
if (ret)
throw Error(HTTP_STATUS_INTERNAL_SERVER_ERROR, "Failed to get kernel information");
ret = sysinfo(&sinfo);
if (ret)
throw Error(HTTP_STATUS_INTERNAL_SERVER_ERROR, "Failed to get system information");
float f_load = 1.f / (1 << SI_LOAD_SHIFT);
json_error_t err;
json_t *json_status = json_pack_ex(&err, 0, "{ s: s, s: s, s: s, s: s, s: s, s: s, s: s, s: f, s: f, s: { s: s, s: I, s: b }, s: { s: s, s: s, s: s, s: s, s: s, s: s}, s: { s: i, s: i, s: I, s: I, s: [ f, f, f ], s: { s: I, s, I, s: I, s: I }, s: { s: I, s: I }, s: { s: I, s: I } } }",
"state", state_print(sn->getState()),
"version", PROJECT_VERSION_STR,
"release", PROJECT_RELEASE,
"build_id", PROJECT_BUILD_ID,
"build_date", PROJECT_BUILD_DATE,
"hostname", hname,
"uuid", uuid_str,
"time_now", time_to_double(&now),
"time_started", time_to_double(&started),
"timezone",
"name", tzname[daylight],
"offset", (json_int_t) timezone,
"dst", daylight,
"kernel",
"sysname", uts.sysname,
"nodename", uts.nodename,
"release", uts.release,
"version", uts.version,
"machine", uts.machine,
"domainname", uts.domainname,
"system",
"cores_configured", get_nprocs_conf(),
"cores", get_nprocs(),
"procecces", (json_int_t) sinfo.procs,
"uptime", (json_int_t) sinfo.uptime,
"load",
f_load * sinfo.loads[0],
f_load * sinfo.loads[1],
f_load * sinfo.loads[2],
"ram",
"total", (json_int_t) (sinfo.totalram * sinfo.mem_unit),
"free", (json_int_t) (sinfo.freeram * sinfo.mem_unit),
"shared", (json_int_t) (sinfo.sharedram * sinfo.mem_unit),
"buffer", (json_int_t) (sinfo.bufferram * sinfo.mem_unit),
"swap",
"total", (json_int_t) (sinfo.totalswap * sinfo.mem_unit),
"free", (json_int_t) (sinfo.freeswap * sinfo.mem_unit),
"highmem",
"total", (json_int_t) (sinfo.totalhigh * sinfo.mem_unit),
"free", (json_int_t) (sinfo.freehigh * sinfo.mem_unit)
);
if (!json_status)
throw Error(HTTP_STATUS_INTERNAL_SERVER_ERROR, "Failed to prepare response: {}", err.text);
#ifdef LWS_WITH_SERVER_STATUS
json_object_set(json_status, "lws", getLwsStatus());
#endif /* LWS_WITH_SERVER_STATUS */
return new Response(session, json_status);
}
@ -68,4 +162,3 @@ static RequestPlugin<StatusRequest, n, r, d> p;
} /* namespace node */
} /* namespace villas */
#endif /* LWS_WITH_SERVER_STATUS */

View file

@ -34,6 +34,7 @@
#include <villas/memory.h>
#include <villas/config_helper.hpp>
#include <villas/log.hpp>
#include <villas/timing.h>
#include <villas/node/exceptions.hpp>
#include <villas/kernel/rt.hpp>
#include <villas/kernel/if.hpp>
@ -48,7 +49,7 @@ using namespace villas::utils;
SuperNode::SuperNode() :
state(State::INITIALIZED),
idleStop(true),
idleStop(-1),
#ifdef WITH_API
api(this),
#endif
@ -63,10 +64,18 @@ SuperNode::SuperNode() :
affinity(0),
hugepages(DEFAULT_NR_HUGEPAGES),
statsRate(1.0),
task(CLOCK_REALTIME)
task(CLOCK_REALTIME),
started(time_now())
{
int ret;
char hname[128];
ret = gethostname(hname, sizeof(hname));
if (ret)
throw SystemError("Failed to determine hostname");
uuid_generate_from_str(uuid, hname);
ret = vlist_init(&nodes);
if (ret)
throw RuntimeError("Failed to initialize list");
@ -95,6 +104,8 @@ void SuperNode::parse(json_t *root)
assert(state != State::STARTED);
const char *uuid_str = nullptr;
json_t *json_nodes = nullptr;
json_t *json_paths = nullptr;
json_t *json_logging = nullptr;
@ -102,7 +113,9 @@ void SuperNode::parse(json_t *root)
json_error_t err;
ret = json_unpack_ex(root, &err, 0, "{ s?: F, s?: o, s?: o, s?: o, s?: o, s?: i, s?: i, s?: i, s?: b }",
idleStop = 1;
ret = json_unpack_ex(root, &err, 0, "{ s?: F, s?: o, s?: o, s?: o, s?: o, s?: i, s?: i, s?: i, s?: b, s?: s }",
"stats", &statsRate,
"http", &json_http,
"logging", &json_logging,
@ -111,11 +124,18 @@ void SuperNode::parse(json_t *root)
"hugepages", &hugepages,
"affinity", &affinity,
"priority", &priority,
"idle_stop", &idleStop
"idle_stop", &idleStop,
"uuid", &uuid_str
);
if (ret)
throw ConfigError(root, err, "node-config", "Unpacking top-level config failed");
if (uuid_str) {
ret = uuid_parse(uuid_str, uuid);
if (ret)
throw ConfigError(root, "node-config-uuid", "Failed to parse UUID: {}", uuid_str);
}
#ifdef WITH_WEB
if (json_http)
web.parse(json_http);
@ -502,7 +522,7 @@ int SuperNode::periodic()
}
}
if (idleStop && state == State::STARTED && started == 0) {
if (idleStop > 0 && state == State::STARTED && started == 0) {
info("No more active paths. Stopping super-node");
return -1;