MarkController.php 5.92 KiB
<?php
namespace App\Http\Controllers;
use Cylab\Mark\Client;
class MarkController extends Controller
{
private $server;
private function server()
{
if ($this->server === null) {
$mark_url = 'http://' . config("app.mark_host") . ':' . config('app.mark_port');
$this->server = new Client($mark_url);
// test we can connect to the server
try {
$this->server->test();
} catch (\JsonRPC\Exception\ConnectionFailureException $ex) {
session()->flash('error', 'Failed to connect to MARK server at ' . $mark_url);
abort(redirect('app/error'));
}
}
return $this->server;
}
public function error()
{
return view('app.error', ["message" => session()->pull('error')]);
}
public function status()
{
$status = $this->server()->status();
$status_history = $this->server()->history();
$history_memory = $this->extractPoints($status_history, "memory_used");
$history_load = $this->extractPoints($status_history, "load");
$history_jobs_executed = $this->extractPoints($status_history, "executor_jobs_executed");
$history_jobs_execution_rate = $this->computeExecutionRate($history_jobs_executed);
return view("app.status", [
"status" => $status,
"history_memory" => $history_memory,
"history_load" => $history_load,
"history_jobs_execution_rate" => $history_jobs_execution_rate]);
}
public function pause()
{
$this->server()->pause();
return redirect(action('MarkController@status'));
}
public function resume()
{
$this->server()->resume();
return redirect(action('MarkController@status'));
}
public function reload()
{
$this->server()->reload();
return redirect(action('MarkController@status'));
}
public function ranking(string $label)
{
// find the detector corresponding to this label
$detectors = $this->server()->activation();
$detector = null;
foreach ($detectors as $d) {
if ($d["label"] == $label) {
$detector = $d;
break;
}
}
$evidences = $this->server()->findEvidence($label);
$now = \Carbon\Carbon::now();
return view(
"app.ranking",
[
"label" => $label,
"evidences" => $evidences,
"detector" => $detector,
"now" => $now]
);
}
public function rankingHome()
{
$activation_graph_elements = [];
$activation = $this->server()->activation();
foreach ($activation as $agent) {
// nodes
$activation_graph_elements[] = ["data" => ["id" => $agent["label"]]];
$activation_graph_elements[] = ["data" => ["id" => $agent["triggerLabel"]]];
// edges
$activation_graph_elements[] = ["data" => [
"id" => rand(),
"source" => $agent["triggerLabel"],
"target" => $agent["label"]]];
}
return view("app.detectors", ["activation_graph_elements" => $activation_graph_elements]);
}
public function extractPoints(array $evidences, string $field) : array
{
$points = [];
foreach ($evidences as $evidence) {
// used by status history
// this is dirty :-(
// status history should return an array of objects
if (is_array($evidence)) {
$points[] = new \App\TimePoint(
$evidence["time"],
$evidence[$field]
);
} else {
$points[] = new \App\TimePoint(
$evidence->time,
$evidence->$field
);
}
}
return $points;
}
public function evidence(string $id)
{
$time_window = 3600; // in seconds
$ev = $this->server()->findEvidenceById($id);
$since = $ev->time - $time_window * 1000;
$references = [];
foreach ($ev->references as $id) {
$references[] = $this->server()->findEvidenceById($id);
}
$history = $this->server()->findEvidenceSince($ev->label, $ev->subject, $since);
return view(
'app.evidence',
[
"evidence" => $ev,
"history" => $history,
"history_points" => $this->extractPoints($history, "score"),
"references" => $references]
);
}
public function evidenceData(string $id, $data_id)
{
$ev = $this->server()->findEvidenceById($id);
$query = $ev->requests[$data_id];
$data = $this->server->findData($query);
return view('app.data', [
"evidence" => $ev,
"query" => $query,
"data" => $data
]);
}
/**
* Compute the number of jobs executed per minute.
*
* @param array $history_jobs_executed
* @return array
*/
private function computeExecutionRate(array $history_jobs_executed) : array
{
if (count($history_jobs_executed) < 2) {
// not enough points to compute execution rate...
return [];
}
$points = [];
$last_point_time = $history_jobs_executed[0]->t;
$last_point_value = $history_jobs_executed[0]->y;
foreach ($history_jobs_executed as $point) {
// this point is less than a minute after the last computed point
if (($point->t - $last_point_time) < 60000) {
continue;
}
$points[] = new \App\TimePoint($point->t, $point->y - $last_point_value);
$last_point_time = $point->t;
$last_point_value = $point->y;
}
return $points;
}
}