Changes have been pushed for the repository "fawkes.git".
(Fawkes Robotics Software Framework)

Clone:  g...@git.fawkesrobotics.org:fawkes.git
Gitweb: http://git.fawkesrobotics.org/fawkes.git
Trac:   http://trac.fawkesrobotics.org

The branch, timn/webview-2.0 has been updated
        to  ac1cee8fc7a846cf20ae163469167fe6d6281731 (commit)
       via  2b21ec700e18ed1ea4013a4728e6864a23fc53ff (commit)
       via  a3034d36d78fa273309ec465e8cbf0beb74825f2 (commit)
       via  d25f61e00ccc2dcddc168ed8161532566665bde0 (commit)
       via  1d806ddb872ac527b0aa22d24e016e065eefd364 (commit)
       via  8e8758c73345903441ca1af36f2a1b18e7323114 (commit)
      from  ec7a7167b471cbebd3ae28d1a882442126331e3f (commit)

http://git.fawkesrobotics.org/fawkes.git/timn/webview-2.0

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- *Log* ---------------------------------------------------------------
commit 8e8758c73345903441ca1af36f2a1b18e7323114
Author:     Tim Niemueller <niemuel...@kbsg.rwth-aachen.de>
AuthorDate: Fri Apr 13 01:44:21 2018 +0200
Commit:     Tim Niemueller <niemuel...@kbsg.rwth-aachen.de>
CommitDate: Fri Apr 13 01:44:21 2018 +0200

    webview: add configuration REST API
    
    Allow (read-only) access to the configuratio via a REST API.

http://git.fawkesrobotics.org/fawkes.git/commit/8e8758c
http://trac.fawkesrobotics.org/changeset/8e8758c

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 1d806ddb872ac527b0aa22d24e016e065eefd364
Author:     Tim Niemueller <niemuel...@kbsg.rwth-aachen.de>
AuthorDate: Fri Apr 13 01:46:51 2018 +0200
Commit:     Tim Niemueller <niemuel...@kbsg.rwth-aachen.de>
CommitDate: Fri Apr 13 01:46:51 2018 +0200

    webview-frontend: update components to disable refresh on blur
    
    No longer automatically refresh data when focus switches elsewhere.

http://git.fawkesrobotics.org/fawkes.git/commit/1d806dd
http://trac.fawkesrobotics.org/changeset/1d806dd

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit d25f61e00ccc2dcddc168ed8161532566665bde0
Author:     Tim Niemueller <niemuel...@kbsg.rwth-aachen.de>
AuthorDate: Fri Apr 13 01:50:22 2018 +0200
Commit:     Tim Niemueller <niemuel...@kbsg.rwth-aachen.de>
CommitDate: Fri Apr 13 01:50:22 2018 +0200

    webview-frontend: concurrent retrieval multiple metrics in promchart
    
    The Prometheus chart can now be configured with multiple queries. The
    data will be retrieved concurrently and then jointly visualized. This
    allows, for example, a network graph for received and transmitted data.
    
    Anticipating this, also add special bytes/s y tick format.

http://git.fawkesrobotics.org/fawkes.git/commit/d25f61e
http://trac.fawkesrobotics.org/changeset/d25f61e

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit a3034d36d78fa273309ec465e8cbf0beb74825f2
Author:     Tim Niemueller <niemuel...@kbsg.rwth-aachen.de>
AuthorDate: Fri Apr 13 01:52:04 2018 +0200
Commit:     Tim Niemueller <niemuel...@kbsg.rwth-aachen.de>
CommitDate: Fri Apr 13 01:52:04 2018 +0200

    webview-frontend: better error visualization in promchart

http://git.fawkesrobotics.org/fawkes.git/commit/a3034d3
http://trac.fawkesrobotics.org/changeset/a3034d3

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 2b21ec700e18ed1ea4013a4728e6864a23fc53ff
Author:     Tim Niemueller <niemuel...@kbsg.rwth-aachen.de>
AuthorDate: Fri Apr 13 01:52:45 2018 +0200
Commit:     Tim Niemueller <niemuel...@kbsg.rwth-aachen.de>
CommitDate: Fri Apr 13 02:00:33 2018 +0200

    webview-frontend: add ConfigurationService
    
    We can now access arbitrary configuration information from the frontend.

http://git.fawkesrobotics.org/fawkes.git/commit/2b21ec7
http://trac.fawkesrobotics.org/changeset/2b21ec7

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit ac1cee8fc7a846cf20ae163469167fe6d6281731
Author:     Tim Niemueller <niemuel...@kbsg.rwth-aachen.de>
AuthorDate: Fri Apr 13 01:55:55 2018 +0200
Commit:     Tim Niemueller <niemuel...@kbsg.rwth-aachen.de>
CommitDate: Fri Apr 13 02:00:34 2018 +0200

    webview-frontend: configurable prometheus charts on dashboard
    
    Show a default collection if none is configured. Once the configuration
    has been downloaded, display the configured graphs only. Single stats
    not yet configurable.

http://git.fawkesrobotics.org/fawkes.git/commit/ac1cee8
http://trac.fawkesrobotics.org/changeset/ac1cee8

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


- *Summary* -----------------------------------------------------------
 src/plugins/webview/Makefile                       |    1 +
 .../{plugin-rest-api => config-rest-api}/Makefile  |    0
 .../{tf-rest-api => config-rest-api}/api.yaml      |   40 +++--
 .../webview/config-rest-api/config-rest-api.cpp    |  186 ++++++++++++++++++
 .../config-rest-api.h}                             |   22 ++-
 .../config-rest-api/model/ConfigTree.cpp}          |   41 ++--
 .../config-rest-api/model/ConfigTree.h}            |   41 ++--
 src/plugins/webview/frontend/src/app/app.module.ts |    6 +-
 .../frontend/src/components/promchart/component.ts |  206 ++++++++++++-------
 .../frontend/src/components/promstat/component.ts  |    9 +
 .../blackboard/components/overview.component.ts    |    1 +
 .../clips-executive/components/domain.component.ts |    1 +
 .../components/goal-detail.component.ts            |    1 +
 .../components/goal-list.component.ts              |    1 +
 .../parts/clips/components/clips-env.component.ts  |    1 +
 .../dashboard/components/dashboard.component.html  |   49 ++++-
 .../dashboard/components/dashboard.component.scss  |    5 +
 .../dashboard/components/dashboard.component.ts    |   16 ++-
 .../parts/plugins/components/overview.component.ts |    1 +
 .../parts/skiller/components/overview.component.ts |    1 +
 .../transforms/components/overview.component.ts    |    1 +
 .../services => services/config}/api.service.ts    |   21 ++-
 .../frontend/src/services/config/config.service.ts |   49 +++++
 .../config/model/ConfigTree.ts}                    |   14 +-
 src/plugins/webview/webview_plugin.cpp             |    2 +
 25 files changed, 545 insertions(+), 171 deletions(-)
 copy src/plugins/webview/{plugin-rest-api => config-rest-api}/Makefile (100%)
 copy src/plugins/webview/{tf-rest-api => config-rest-api}/api.yaml (50%)
 create mode 100644 src/plugins/webview/config-rest-api/config-rest-api.cpp
 copy src/plugins/webview/{backendinfo-rest-api/backendinfo-rest-api.h => 
config-rest-api/config-rest-api.h} (81%)
 copy src/plugins/{skiller/rest-api/model/SkillInfo.cpp => 
webview/config-rest-api/model/ConfigTree.cpp} (70%)
 copy src/plugins/{skiller/rest-api/model/SkillInfo.h => 
webview/config-rest-api/model/ConfigTree.h} (82%)
 copy src/plugins/webview/frontend/src/{parts/transforms/services => 
services/config}/api.service.ts (64%)
 create mode 100644 
src/plugins/webview/frontend/src/services/config/config.service.ts
 copy src/plugins/webview/frontend/src/{parts/clips/models/Environment.ts => 
services/config/model/ConfigTree.ts} (62%)


- *Diffs* -------------------------------------------------------------

- *commit* 8e8758c73345903441ca1af36f2a1b18e7323114 - - - - - - - - - -
Author:  Tim Niemueller <niemuel...@kbsg.rwth-aachen.de>
Date:    Fri Apr 13 01:44:21 2018 +0200
Subject: webview: add configuration REST API

 src/plugins/webview/Makefile                       |    1 +
 .../{plugin-rest-api => config-rest-api}/Makefile  |    0
 .../{tf-rest-api => config-rest-api}/api.yaml      |   40 +++--
 .../webview/config-rest-api/config-rest-api.cpp    |  186 ++++++++++++++++++++
 .../config-rest-api.h}                             |   22 ++-
 .../config-rest-api/model/ConfigTree.cpp}          |   41 ++---
 .../config-rest-api/model/ConfigTree.h}            |   41 ++---
 src/plugins/webview/webview_plugin.cpp             |    2 +
 8 files changed, 265 insertions(+), 68 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/webview/Makefile b/src/plugins/webview/Makefile
index 3d0d25c..0f8e44b 100644
--- a/src/plugins/webview/Makefile
+++ b/src/plugins/webview/Makefile
@@ -63,6 +63,7 @@ ifeq ($(HAVE_BOOST_LIBS)$(HAVE_LIBMICROHTTPD),11)
                   backendinfo-rest-api/backendinfo-rest-api.o \
                   plugin-rest-api/plugin-rest-api.o \
                   tf-rest-api/tf-rest-api.o \
+                  config-rest-api/config-rest-api.o \
                   $(patsubst %.cpp,%.o,$(subst $(SRCDIR)/,,$(realpath 
$(wildcard $(SRCDIR)/*-rest-api/model/*.cpp))))
 
   ifeq ($(HAVE_TF),1)
diff --git a/src/plugins/webview/webview_plugin.cpp 
b/src/plugins/webview/webview_plugin.cpp
index 81d072a..9a66268 100644
--- a/src/plugins/webview/webview_plugin.cpp
+++ b/src/plugins/webview/webview_plugin.cpp
@@ -28,6 +28,7 @@
 #  include "blackboard-rest-api/blackboard-rest-api.h"
 #  include "backendinfo-rest-api/backendinfo-rest-api.h"
 #  include "plugin-rest-api/plugin-rest-api.h"
+#  include "config-rest-api/config-rest-api.h"
 #  ifdef HAVE_JPEG
 #    include "image-rest-api/image-rest-api.h"
 #  endif
@@ -58,6 +59,7 @@ WebviewPlugin::WebviewPlugin(Configuration *config)
   thread_list.push_back(new BlackboardRestApi());
   thread_list.push_back(new BackendInfoRestApi());
   thread_list.push_back(new PluginRestApi());
+  thread_list.push_back(new ConfigurationRestApi());
 #  ifdef HAVE_JPEG
   thread_list.push_back(new ImageRestApi());
 #  endif

- *commit* 1d806ddb872ac527b0aa22d24e016e065eefd364 - - - - - - - - - -
Author:  Tim Niemueller <niemuel...@kbsg.rwth-aachen.de>
Date:    Fri Apr 13 01:46:51 2018 +0200
Subject: webview-frontend: update components to disable refresh on blur

 .../blackboard/components/overview.component.ts    |    1 +
 .../clips-executive/components/domain.component.ts |    1 +
 .../components/goal-detail.component.ts            |    1 +
 .../components/goal-list.component.ts              |    1 +
 .../parts/clips/components/clips-env.component.ts  |    1 +
 .../parts/plugins/components/overview.component.ts |    1 +
 .../parts/skiller/components/overview.component.ts |    1 +
 .../transforms/components/overview.component.ts    |    1 +
 8 files changed, 8 insertions(+), 0 deletions(-)

_Diff for modified files_:
diff --git 
a/src/plugins/webview/frontend/src/parts/blackboard/components/overview.component.ts
 
b/src/plugins/webview/frontend/src/parts/blackboard/components/overview.component.ts
index b91141b..c5a9fc8 100644
--- 
a/src/plugins/webview/frontend/src/parts/blackboard/components/overview.component.ts
+++ 
b/src/plugins/webview/frontend/src/parts/blackboard/components/overview.component.ts
@@ -46,6 +46,7 @@ export class BlackboardOverviewComponent implements OnInit, 
OnDestroy {
   {
     this.backend_subscription.unsubscribe();
     this.backend_subscription = null;
+    this.disable_autorefresh();
   }
 
   keys(obj) {
diff --git 
a/src/plugins/webview/frontend/src/parts/clips-executive/components/domain.component.ts
 
b/src/plugins/webview/frontend/src/parts/clips-executive/components/domain.component.ts
index c2567e7..a59eaf2 100644
--- 
a/src/plugins/webview/frontend/src/parts/clips-executive/components/domain.component.ts
+++ 
b/src/plugins/webview/frontend/src/parts/clips-executive/components/domain.component.ts
@@ -63,6 +63,7 @@ export class DomainComponent implements OnInit {
   {
     this.backend_subscription.unsubscribe();
     this.backend_subscription = null;
+    this.disable_autorefresh();
   }
 
   reset_domain_data()
diff --git 
a/src/plugins/webview/frontend/src/parts/clips-executive/components/goal-detail.component.ts
 
b/src/plugins/webview/frontend/src/parts/clips-executive/components/goal-detail.component.ts
index da878c5..48a1e70 100644
--- 
a/src/plugins/webview/frontend/src/parts/clips-executive/components/goal-detail.component.ts
+++ 
b/src/plugins/webview/frontend/src/parts/clips-executive/components/goal-detail.component.ts
@@ -64,6 +64,7 @@ export class GoalDetailComponent implements OnInit, OnDestroy 
{
   {
     this.backend_subscription.unsubscribe();
     this.backend_subscription = null;
+    this.disable_autorefresh();
   }
 
   refresh_domain()
diff --git 
a/src/plugins/webview/frontend/src/parts/clips-executive/components/goal-list.component.ts
 
b/src/plugins/webview/frontend/src/parts/clips-executive/components/goal-list.component.ts
index f558d29..d4ce0ee 100644
--- 
a/src/plugins/webview/frontend/src/parts/clips-executive/components/goal-list.component.ts
+++ 
b/src/plugins/webview/frontend/src/parts/clips-executive/components/goal-list.component.ts
@@ -48,6 +48,7 @@ export class GoalListComponent implements OnInit, OnDestroy {
   {
     this.backend_subscription.unsubscribe();
     this.backend_subscription = null;
+    this.disable_autorefresh();
   }
 
   refresh()
diff --git 
a/src/plugins/webview/frontend/src/parts/clips/components/clips-env.component.ts
 
b/src/plugins/webview/frontend/src/parts/clips/components/clips-env.component.ts
index 20e37fc..32b2e2f 100644
--- 
a/src/plugins/webview/frontend/src/parts/clips/components/clips-env.component.ts
+++ 
b/src/plugins/webview/frontend/src/parts/clips/components/clips-env.component.ts
@@ -69,6 +69,7 @@ export class ClipsEnvComponent implements OnInit, OnDestroy {
   {
     this.backend_subscription.unsubscribe();
     this.backend_subscription = null;
+    this.disable_autorefresh();
   }
 
   refresh()
diff --git 
a/src/plugins/webview/frontend/src/parts/plugins/components/overview.component.ts
 
b/src/plugins/webview/frontend/src/parts/plugins/components/overview.component.ts
index eb58000..497c513 100644
--- 
a/src/plugins/webview/frontend/src/parts/plugins/components/overview.component.ts
+++ 
b/src/plugins/webview/frontend/src/parts/plugins/components/overview.component.ts
@@ -60,6 +60,7 @@ export class PluginOverviewComponent implements OnInit, 
OnDestroy {
   {
     this.backend_subscription.unsubscribe();
     this.backend_subscription = null;
+    this.disable_autorefresh();
   }
 
   refresh()
diff --git 
a/src/plugins/webview/frontend/src/parts/skiller/components/overview.component.ts
 
b/src/plugins/webview/frontend/src/parts/skiller/components/overview.component.ts
index e5c4ba3..ea876f2 100644
--- 
a/src/plugins/webview/frontend/src/parts/skiller/components/overview.component.ts
+++ 
b/src/plugins/webview/frontend/src/parts/skiller/components/overview.component.ts
@@ -45,6 +45,7 @@ export class SkillerOverviewComponent implements OnInit, 
OnDestroy {
   {
     this.backend_subscription.unsubscribe();
     this.backend_subscription = null;
+    this.disable_autorefresh();
   }
 
   refresh()
diff --git 
a/src/plugins/webview/frontend/src/parts/transforms/components/overview.component.ts
 
b/src/plugins/webview/frontend/src/parts/transforms/components/overview.component.ts
index 3a52e43..ec798f8 100644
--- 
a/src/plugins/webview/frontend/src/parts/transforms/components/overview.component.ts
+++ 
b/src/plugins/webview/frontend/src/parts/transforms/components/overview.component.ts
@@ -39,6 +39,7 @@ export class TransformsOverviewComponent implements OnInit, 
OnDestroy {
   {
     this.backend_subscription.unsubscribe();
     this.backend_subscription = null;
+    this.disable_autorefresh();
   }
 
   refresh()

- *commit* d25f61e00ccc2dcddc168ed8161532566665bde0 - - - - - - - - - -
Author:  Tim Niemueller <niemuel...@kbsg.rwth-aachen.de>
Date:    Fri Apr 13 01:50:22 2018 +0200
Subject: webview-frontend: concurrent retrieval multiple metrics in promchart

 .../frontend/src/components/promchart/component.ts |  206 ++++++++++++-------
 1 files changed, 130 insertions(+), 76 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/webview/frontend/src/components/promchart/component.ts 
b/src/plugins/webview/frontend/src/components/promchart/component.ts
index 80bfed5..a099d1b 100644
--- a/src/plugins/webview/frontend/src/components/promchart/component.ts
+++ b/src/plugins/webview/frontend/src/components/promchart/component.ts
@@ -8,6 +8,7 @@ import { HttpClient } from '@angular/common/http';
 
 import { Observable } from 'rxjs/Observable';
 import 'rxjs/add/observable/interval';
+import 'rxjs/add/observable/forkJoin';
 
 import { BackendConfigurationService } from 
'../../services/backend-config/backend-config.service';
 
@@ -39,16 +40,17 @@ export class PrometheusChartComponent implements 
AfterViewInit, OnInit, OnDestro
   @Input() time_range?: number = 900;
   @Input() step_sec?: number = 15;
   @Input() query?: string = null;
-  @Input() legend_label?: string = 'groupname';
+  @Input() queries?: string[] = [];
+  @Input() legend_format?: string = null;;
+  @Input() legend_formats?: string[] = [];
   @Input() y_axis?: c3.YAxisConfiguration = Object.assign({}, DEFAULT_Y_AXIS);
   @Input() show_grid?: boolean = true;
   @Input() legend?: c3.LegendOptions = Object.assign({}, DEFAULT_LEGEND);
   @Input() groups?: string[][] = null;
   @Input() group_all?: boolean = true;
-  @Input() unit?: string = 'bytes';
   @Input() remove_all_zero?: boolean = true;
   @Input() x_tick_format?: string = '%H:%M:%S';
-  @Input() y_tick_format?: string = '.2f';
+  @Input() y_tick_format?: string = '.1f';
   @Input() y_min?: number = null;
   @Input() y_max?: number = null;
   @Input() y_tick_count?: number = 4;
@@ -68,9 +70,25 @@ export class PrometheusChartComponent implements 
AfterViewInit, OnInit, OnDestro
 
   ngAfterViewInit()
   {
-    if (!this.query) {
+    if (!this.query && this.queries.length == 0) {
       this.zero_message='No query configured';
     } else {
+      if (this.query) {
+        this.queries.push(this.query);
+        if (this.legend_format) {
+          this.legend_formats.push(this.legend_format);
+        } else {
+          this.legend_formats.push(this.query);
+        }
+      }
+
+      if (this.queries.length == 0) {
+        this.zero_message='No queries configured';
+      } else if (this.legend_formats.length != this.queries.length) {
+        this.queries = [];
+        this.zero_message = '#queries != #legend_formats';
+      }
+
       this.enable_autorefresh();
     }
   }
@@ -109,92 +127,64 @@ export class PrometheusChartComponent implements 
AfterViewInit, OnInit, OnDestro
 
     let end   = Math.floor(Date.now() / 1000);
     let start = end - this.time_range;
-    let url =
-      
`${this.backendcfg.url_for('prometheus')}/api/v1/query_range?query=${encodeURIComponent(String(this.query))}&start=${start}&end=${end}&step=${this.step_sec}s`;
-    this.http.get<any>(url)
+    let step_sec = this.step_sec;
+    let urls = this.queries
+      .map((q) =>
+           
`${this.backendcfg.url_for('prometheus')}/api/v1/query_range?query=${encodeURIComponent(String(q))}&start=${start}&end=${end}&step=${this.step_sec}s`);
+
+
+    Observable
+      .forkJoin(urls.map((u) => this.http.get<any>(u)))
+      .map((res: any[]) =>
+           res.map((r,i) => this.proc_res(r, start, end, step_sec, 
this.legend_formats[i])))
       .subscribe(
-        (obj) => {
+        (data_arr: any[]) => {
+          if (data_arr.length > 0) {
 
-          if (obj.status == 'success' && obj.data.result.length > 0) {
-            let x: number[] = [];
-            let data = [];
-            
+            let timeline: number[] = [];
             for (let i = start; i <= end; i += this.step_sec) {
-              x.push(i * 1000);
+              timeline.push(i * 1000);
             }
 
-            for (let r of obj.data.result) {
-              let d = {
-                name: r.metric[this.legend_label],
-                values: []
-              };
-
-              let base_timestamp = start;
-              for (let v of r.values) {
-                let dp = parseFloat(v[1]);
-                if (isNaN(dp)) {
-                  dp = 0.;
-                }
+            // From here on, the index in data does not reflect the
+            // index in obj.data.result since we may have deleted some
 
-                const timestamp = parseFloat(v[0]);
-                for (let t = base_timestamp; t < timestamp; t += this.step_sec)
-                {
-                  d.values.push(0.);
-                }
+            let columns = [['__x', ...timeline]];
+            let groups = this.group_all ? [[]] : this.groups;
+            let types = {};
 
-                base_timestamp = timestamp + this.step_sec;
-                d.values.push(dp);
-              }
-              data.push(d);
-            }
+            for (let data of data_arr) {
 
-            // filter all-zero metrics
-            if (this.remove_all_zero) {
-              let to_erase = []
-              for (let i = 0; i < obj.data.result.length; ++i) {
-                if (data[i].values.every((y) => (Math.abs(y) < 
Number.EPSILON))) {
-                  to_erase.push(i);
+              for (let d of data) {
+                if (d.name in types) {
+                  console.warn(`Duplicate data name ${d.name}, overwriting`);
                 }
+                types[d.name] = 'area';
               }
-              if (to_erase.length > 0) {
-                let erase_names = to_erase.map((e) => data[e].name);
-                //console.log(`Removing ${erase_names}`);
-                for (let e of to_erase.sort((a,b) => b - a)) {
-                  data.splice(e, 1);
+
+              let group = [];
+              if (this.group_all) {
+                for (let d of data) {
+                  groups[0].push(d.name);
                 }
               }
-            }
 
-            // From here on, the index in data does not reflect the
-            // index in obj.data.result since we may have deleted some
-          
-            let types = {};
-            for (let d of data) {
-              types[d.name] = 'area';
-            }
-
-            let group = [];
-            if (this.group_all) {
               for (let d of data) {
-                group.push(d.name);
+                columns.push([d.name, ...d.values]);
               }
             }
-            this.groups = this.group_all ? [group] : [];
-
-            let columns = [['__x', ...x]];
-            for (let d of data) {
-              columns.push([d.name, ...d.values]);
-            }
 
             if (! this.y_axis.tick) {
               this.y_axis.tick = {};
             }
             if (this.y_tick_format) {
-              if (this.y_tick_format == 'bytes') {
-                this.y_axis.tick.format = this.format_bytes;
+              if (this.y_tick_format == 'bytes' || this.y_tick_format == 
'bytes/s') {
+                this.y_axis.tick.format = 
this.format_bytes_func(this.y_tick_format);
               } else {
                 this.y_axis.tick.format = d3.format(this.y_tick_format);
               }
+            } else {
+              this.y_axis.tick.format = d3.format('.1f');
             }
             if (this.y_min) {
               this.y_axis.min = this.y_min;
@@ -237,7 +227,7 @@ export class PrometheusChartComponent implements 
AfterViewInit, OnInit, OnDestro
                 x: '__x',
                 columns: columns,
                 types: types,
-                groups: this.groups,
+                groups: groups,
               },
               axis: {
                 x: {
@@ -277,18 +267,82 @@ export class PrometheusChartComponent implements 
AfterViewInit, OnInit, OnDestro
       );
   }
 
-  format_bytes(value: number)
+  render_label_template(str, labels) {
+    var regex = /\(\(\s*(.+?)\s*\)\)/g;
+    return str.replace(regex, (m,g) => labels[g] ? labels[g] : g);
+  }
+
+  private proc_res(res, start, end, step_sec, legend_format) {
+    if (res.status != 'success')  return null;
+    let data = [];
+
+    for (let r of  res.data.result) {
+      let d = {
+        name: this.render_label_template(legend_format, r.metric),
+        values: []
+      };
+
+      let base_timestamp = start;
+      for (let v of r.values) {
+        let dp = parseFloat(v[1]);
+        if (isNaN(dp)) {
+          dp = 0.;
+        }
+
+        const timestamp = parseFloat(v[0]);
+        for (let t = base_timestamp; t < timestamp; t += step_sec)
+        {
+          d.values.push(0.);
+        }
+
+        base_timestamp = timestamp + step_sec;
+        d.values.push(dp);
+      }
+
+      for (let t = base_timestamp; t < end; t += step_sec)
+      {
+        d.values.push(0.);
+      }
+
+      data.push(d);
+    }
+
+    // filter all-zero metrics
+    if (this.remove_all_zero) {
+      let to_erase = []
+      for (let i = 0; i < res.data.result.length; ++i) {
+        if (data[i].values.every((y) => (Math.abs(y) < Number.EPSILON))) {
+          to_erase.push(i);
+        }
+      }
+      if (to_erase.length > 0) {
+        let erase_names = to_erase.map((e) => data[e].name);
+        for (let e of to_erase.sort((a,b) => b - a)) {
+          data.splice(e, 1);
+        }
+      }
+    }
+
+    return data;
+  }
+
+  format_bytes_func(what: string)
   {
     let units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB']
-    let idx = 0;
-    while (value > 1024 && idx < units.length - 1) {
-      value /= 1024;
-      idx += 1;
+    if (what == "bytes/s") {
+      units = ['B/s', 'KB/s', 'MB/s', 'GB/s', 'TB/s', 'PB/s', 'EB/s']
     }
-    if (value > 0 && value < 10) {
-      return d3.format('.1f')(value) + units[idx];
-    } else {
-      return d3.format('.0f')(value) + units[idx];
+    return function(value: number): string {
+      let idx = 0;
+      while (value > 1024 && idx < units.length - 1) {
+        value /= 1024;
+        idx += 1;
+      }
+      if (value > 0 && value < 10) {
+        return d3.format('.1f')(value) + ' ' + units[idx];
+      } else {
+        return d3.format('.0f')(value) + ' ' + units[idx];
+      }
     }
   }
 

- *commit* a3034d36d78fa273309ec465e8cbf0beb74825f2 - - - - - - - - - -
Author:  Tim Niemueller <niemuel...@kbsg.rwth-aachen.de>
Date:    Fri Apr 13 01:52:04 2018 +0200
Subject: webview-frontend: better error visualization in promchart

 .../frontend/src/components/promstat/component.ts  |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/webview/frontend/src/components/promstat/component.ts 
b/src/plugins/webview/frontend/src/components/promstat/component.ts
index 025480f..dca40c2 100644
--- a/src/plugins/webview/frontend/src/components/promstat/component.ts
+++ b/src/plugins/webview/frontend/src/components/promstat/component.ts
@@ -120,6 +120,15 @@ export class PrometheusStatComponent implements 
AfterViewInit, OnInit, OnDestroy
                 }
               }
             }
+          } else if (obj.status != 'success') {
+            this.value = "N/A";
+            this.css_class = "promstat-red";
+          } else if (obj.data.result.length == 0) {
+            this.value = "N/A";
+            this.css_class = "promstat-orange";
+          } else {
+            this.value = `N/A (${obj.message || '?'})`;
+            this.css_class = "promstat-red";
           }
         });
   }

- *commit* 2b21ec700e18ed1ea4013a4728e6864a23fc53ff - - - - - - - - - -
Author:  Tim Niemueller <niemuel...@kbsg.rwth-aachen.de>
Date:    Fri Apr 13 01:52:45 2018 +0200
Subject: webview-frontend: add ConfigurationService

 src/plugins/webview/frontend/src/app/app.module.ts |    6 ++-
 .../services => services/config}/api.service.ts    |   21 +++++----
 .../frontend/src/services/config/config.service.ts |   49 ++++++++++++++++++++
 .../config/model/ConfigTree.ts}                    |   14 +++---
 4 files changed, 73 insertions(+), 17 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/webview/frontend/src/app/app.module.ts 
b/src/plugins/webview/frontend/src/app/app.module.ts
index ce5fc6f..1dc1145 100644
--- a/src/plugins/webview/frontend/src/app/app.module.ts
+++ b/src/plugins/webview/frontend/src/app/app.module.ts
@@ -14,6 +14,8 @@ import { AppRoutingModule } from './app-routing.module';
 import { AppComponent } from './app.component';
 import { ChromeModule } from '../chrome/module';
 import { BackendConfigurationService } from 
'../services/backend-config/backend-config.service';
+import { ConfigurationService } from '../services/config/config.service';
+import { ConfigurationApiService } from '../services/config/api.service';
 import { AssetsService } from '../services/global/assets';
 import { SwUpdateNotifierService } from 
'../services/update-notifier/update-notifier.service';
 
@@ -50,7 +52,9 @@ import { HttpClientInMemoryWebApiModule } from 
'angular-in-memory-web-api';
          // Keep the AppRoutingModule last
          AppRoutingModule,
        ],
-  providers: [BackendConfigurationService, AssetsService, 
SwUpdateNotifierService],
+  providers: [BackendConfigurationService,
+              ConfigurationService, ConfigurationApiService,
+              AssetsService, SwUpdateNotifierService],
        bootstrap: [AppComponent]
 })
 export class AppModule { }

- *commit* ac1cee8fc7a846cf20ae163469167fe6d6281731 - - - - - - - - - -
Author:  Tim Niemueller <niemuel...@kbsg.rwth-aachen.de>
Date:    Fri Apr 13 01:55:55 2018 +0200
Subject: webview-frontend: configurable prometheus charts on dashboard

 .../dashboard/components/dashboard.component.html  |   49 ++++++++++++++++----
 .../dashboard/components/dashboard.component.scss  |    5 ++
 .../dashboard/components/dashboard.component.ts    |   16 ++++++-
 3 files changed, 60 insertions(+), 10 deletions(-)

_Diff for modified files_:
diff --git 
a/src/plugins/webview/frontend/src/parts/dashboard/components/dashboard.component.html
 
b/src/plugins/webview/frontend/src/parts/dashboard/components/dashboard.component.html
index ef4e66e..123dc94 100644
--- 
a/src/plugins/webview/frontend/src/parts/dashboard/components/dashboard.component.html
+++ 
b/src/plugins/webview/frontend/src/parts/dashboard/components/dashboard.component.html
@@ -2,8 +2,9 @@
  Copyright  2018  Tim Niemueller <niemuel...@kbsg.rwth-aachen.de>
  License: Apache 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
        -->
-<div fxLayout="row">
-       <mat-card class="ff-content-card" fxFlex="32">
+<div fxLayout="row wrap" fxLayoutAlign="space-between">
+       <ng-container *ngIf="charts.length == 0">
+       <mat-card class="ff-content-card promchart-card" fxFlex="30">
                <mat-card-title>
                        <div>CPU</div>
                </mat-card-title>
@@ -11,7 +12,7 @@
                <mat-card-content class="ff-card-content">
                        <prom-chart
                                [query]="query_cpu"
-                               legend_label="mode"
+                               legend_format="((mode))"
                                y_tick_format=".0%"
                                [y_min]="0.0"
                                [y_max]="1.0">
@@ -19,7 +20,7 @@
                </mat-card-content>
        </mat-card>
 
-       <mat-card class="ff-content-card" fxFlex="32">
+       <mat-card class="ff-content-card promchart-card" fxFlex="30">
                <mat-card-title>
                        <div>Memory</div>
                </mat-card-title>
@@ -27,13 +28,13 @@
                <mat-card-content class="ff-card-content">
                        <prom-chart
                                [query]="query_mem"
-                               legend_label="groupname"
+                               legend_format="((groupname))"
                                y_tick_format="bytes">
                        </prom-chart>
                </mat-card-content>
        </mat-card>
 
-       <mat-card class="ff-content-card" fxFlex="32">
+       <mat-card class="ff-content-card promchart-card" fxFlex="30">
                <mat-card-title>
                        <div>Per Thread CPU</div>
                </mat-card-title>
@@ -41,14 +42,37 @@
                <mat-card-content class="ff-card-content">
                        <prom-chart
                                [query]="query_threads"
-                               legend_label="threadname"
+                               legend_format="((threadname))"
                                y_tick_format=".1%">
                        </prom-chart>
                </mat-card-content>
        </mat-card>
-</div>
+       </ng-container>
+       <ng-container *ngIf="charts.length > 0">
+               <mat-card *ngFor="let c of charts"
+                                                       class="ff-content-card 
promchart-card" fxFlex="30">
+                       <mat-card-title>
+                               <div>{{ c.name }}</div>
+                       </mat-card-title>
+                       <mat-divider></mat-divider>
+                       <mat-card-content class="ff-card-content">
+                               <prom-chart *ngIf="c.query"
+                                                                               
[query]="c.query"
+                                                                               
[legend_format]="c.legend_format"
+                                                                               
[y_tick_format]="c.y_tick_format"
+                                                                               
[remove_all_zero]="c.remove_all_zero">
+                               </prom-chart>
+                               <prom-chart *ngIf="c.queries"
+                                                                               
[queries]="c.queries"
+                                                                               
[legend_formats]="c.legend_formats"
+                                                                               
[y_tick_format]="c.y_tick_format"
+                                                                               
[remove_all_zero]="c.remove_all_zero">
+                               </prom-chart>
+                       </mat-card-content>
+               </mat-card>
+       </ng-container>
 
-<div fxLayout="row">
+<div fxLayout="row wrap">
        <prom-stat
                [query]="query_ntp_offset"
                [factor]="1000"
@@ -70,4 +94,11 @@
                label="SSD Avail"
                unit="GB">
        </prom-stat>
+       <prom-stat
+               [query]="query_swap_used"
+               [factor]="100"
+               [thresholds]="[10,50]"
+               label="Swap Used"
+               unit="%">
+       </prom-stat>
 </div>
diff --git 
a/src/plugins/webview/frontend/src/parts/dashboard/components/dashboard.component.scss
 
b/src/plugins/webview/frontend/src/parts/dashboard/components/dashboard.component.scss
index c1d01b5..349e3ff 100644
--- 
a/src/plugins/webview/frontend/src/parts/dashboard/components/dashboard.component.scss
+++ 
b/src/plugins/webview/frontend/src/parts/dashboard/components/dashboard.component.scss
@@ -3,3 +3,8 @@
 // License: Apache 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
 
 @import '../../../_variables';
+
+.promchart-card {
+               padding: 12px;
+               padding-bottom: 4px;
+}
diff --git 
a/src/plugins/webview/frontend/src/parts/dashboard/components/dashboard.component.ts
 
b/src/plugins/webview/frontend/src/parts/dashboard/components/dashboard.component.ts
index 99dcaea..940c6da 100644
--- 
a/src/plugins/webview/frontend/src/parts/dashboard/components/dashboard.component.ts
+++ 
b/src/plugins/webview/frontend/src/parts/dashboard/components/dashboard.component.ts
@@ -8,6 +8,7 @@ import { Observable } from 'rxjs/Observable';
 import 'rxjs/add/observable/interval';
 
 import { BackendConfigurationService } from 
'../../../services/backend-config/backend-config.service';
+import { ConfigurationService } from '../../../services/config/config.service';
 
 @Component({
   selector: 'dashboard',
@@ -32,12 +33,25 @@ export class DashboardComponent implements OnInit, 
OnDestroy {
   query_ntp_offset = 'node_ntp_offset_seconds{instance="localhost:9100"}';
   query_mem_avail = 'node_memory_MemAvailable{instance="localhost:9100"}';
   query_ssd_avail = 
'node_filesystem_avail{instance="localhost:9100",mountpoint="/"}'
+  query_swap_used = 
'(node_memory_SwapTotal{instance="localhost:9100"}-node_memory_SwapFree{instance="localhost:9100"})/node_memory_SwapTotal{instance="localhost:9100"}';
 
-  constructor(private backendcfg: BackendConfigurationService)
+  charts = [];
+
+  constructor(private backendcfg: BackendConfigurationService,
+              private config: ConfigurationService)
   {}
 
   ngOnInit() {
     this.backend_subscription = this.backendcfg.backend_changed.subscribe((b) 
=> { this.refresh() });
+    this.config.get('/webview/dashboard')
+      .subscribe(conf => {
+        this.charts = Object.values(conf['webview']['dashboard']['charts']);
+        this.charts.forEach(c => {
+          if (! ('remove_all_zero' in c)) {
+            c.remove_all_zero = true;
+          }
+        });
+      });
   }
 
   ngOnDestroy()




-- 
Fawkes Robotics Framework                 http://www.fawkesrobotics.org
_______________________________________________
fawkes-commits mailing list
fawkes-commits@lists.kbsg.rwth-aachen.de
https://lists.kbsg.rwth-aachen.de/listinfo/fawkes-commits

Reply via email to