aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastien Douheret <sebastien.douheret@iot.bzh>2019-07-13 10:21:53 +0200
committerSebastien Douheret <sebastien.douheret@iot.bzh>2019-07-14 14:06:14 +0200
commit701548c5b25efba70c3818e96a4394701cfb913e (patch)
tree347881ae607acda17f2014a5e7ed1aadee055145
parent247bb7c2db5f0d48178398599348249bf886ebbc (diff)
Add LowCollector & rename Supervisor to Monitoringsandbox/SebD/dev_supervisor_als_2019
Change-Id: Ibd78f1200ed71b0100ebd48dddb9236377e2fb36 Signed-off-by: Sebastien Douheret <sebastien.douheret@iot.bzh>
-rw-r--r--.vscode/settings.json1
-rw-r--r--Makefile2
-rw-r--r--lib/agent/agent.go15
-rw-r--r--lib/agent/apiv1-monitoring.go214
-rw-r--r--lib/agent/apiv1-supervisor.go114
-rw-r--r--lib/agent/apiv1.go12
-rw-r--r--lib/agent/xds-low-collector.go321
-rw-r--r--lib/agent/xdsmonitoring.go (renamed from lib/agent/xdssupervior.go)69
-rw-r--r--lib/aglafb/afb.go53
-rw-r--r--lib/xdsconfig/config.go8
-rw-r--r--lib/xdsconfig/configfile.go12
-rw-r--r--webapp/src/app/@core-xds/services/@core-xds-services.module.ts4
-rw-r--r--webapp/src/app/@core-xds/services/monitoring.service.ts106
-rw-r--r--webapp/src/app/@core-xds/services/supervision.service.ts61
-rw-r--r--webapp/src/app/@core-xds/services/xdsagent.service.ts33
-rw-r--r--webapp/src/app/pages/config/config-global/config-global.component.html2
-rw-r--r--webapp/src/app/pages/monitoring/monitoring-config.component.html77
-rw-r--r--webapp/src/app/pages/monitoring/monitoring-config.component.scss (renamed from webapp/src/app/pages/supervision/supervision-config.component.scss)13
-rw-r--r--webapp/src/app/pages/monitoring/monitoring-config.component.ts (renamed from webapp/src/app/pages/supervision/supervision-config.component.ts)117
-rw-r--r--webapp/src/app/pages/monitoring/monitoring.component.html (renamed from webapp/src/app/pages/supervision/supervision.component.html)2
-rw-r--r--webapp/src/app/pages/monitoring/monitoring.component.scss (renamed from webapp/src/app/pages/supervision/supervision.component.scss)0
-rw-r--r--webapp/src/app/pages/monitoring/monitoring.component.ts (renamed from webapp/src/app/pages/supervision/supervision.component.ts)24
-rw-r--r--webapp/src/app/pages/monitoring/monitoring.module.ts (renamed from webapp/src/app/pages/supervision/supervision.module.ts)10
-rw-r--r--webapp/src/app/pages/pages-menu.ts8
-rw-r--r--webapp/src/app/pages/pages-routing.module.ts12
-rw-r--r--webapp/src/app/pages/pages.module.ts4
-rw-r--r--webapp/src/app/pages/supervision/supervision-config.component.html45
-rw-r--r--webapp/tslint.json13
28 files changed, 998 insertions, 354 deletions
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 59cafea..84bb4a3 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -56,6 +56,7 @@
"WSID",
"XDSSUPERV",
"abortinstall",
+ "aglafb",
"apiv",
"cmdi",
"conv",
diff --git a/Makefile b/Makefile
index 273458f..fe8c9ec 100644
--- a/Makefile
+++ b/Makefile
@@ -149,7 +149,7 @@ else
@echo "Skipping webapp build (SKIP_WEBAPP_BUILD var is set)"
endif
-webapp/debug:
+webapp/debug dev-frontend devf:
cd webapp && npm run watch
webapp/install:
diff --git a/lib/agent/agent.go b/lib/agent/agent.go
index 506976d..e90c1a0 100644
--- a/lib/agent/agent.go
+++ b/lib/agent/agent.go
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017-2018 "IoT.bzh"
+ * Copyright (C) 2017-2019 "IoT.bzh"
* Author Sebastien Douheret <sebastien@iot.bzh>
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -47,12 +47,13 @@ type Context struct {
SThgCmd *exec.Cmd
SThgInotCmd *exec.Cmd
- webServer *WebServer
- xdsServers map[string]*XdsServer
- XdsSupervisor *XdsSupervisor
- sessions *Sessions
- events *Events
- projects *Projects
+ webServer *WebServer
+ xdsServers map[string]*XdsServer
+ XdsMonitoring *XdsMonitoring
+ XdsLowCollector *XdsLowCollector
+ sessions *Sessions
+ events *Events
+ projects *Projects
Exit chan os.Signal
}
diff --git a/lib/agent/apiv1-monitoring.go b/lib/agent/apiv1-monitoring.go
new file mode 100644
index 0000000..cf651ce
--- /dev/null
+++ b/lib/agent/apiv1-monitoring.go
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2017-2019 "IoT.bzh"
+ * Author Sebastien Douheret <sebastien@iot.bzh>
+ *
+ * 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.
+ */
+
+package agent
+
+import (
+ "net/http"
+
+ "gerrit.automotivelinux.org/gerrit/src/xds/xds-agent.git/lib/aglafb"
+ common "gerrit.automotivelinux.org/gerrit/src/xds/xds-common.git"
+ "github.com/gin-gonic/gin"
+)
+
+//************************* AGL XDS Monitoring *************************
+
+// getMonitoringTopo : return current AGL daemons topology using monitoring
+func (s *APIService) getMonitoringTopo(c *gin.Context) {
+
+ xdspvr, err := s._initXdsMonitoring()
+ if err != nil {
+ common.APIError(c, err.Error())
+ return
+ }
+
+ var res aglafb.AfbReply
+ if err = xdspvr.GetTopo(&res); err != nil {
+ common.APIError(c, err.Error())
+ return
+ }
+
+ if res.Request.Status != "success" {
+ common.APIError(c, res.Request.Info)
+ return
+ }
+
+ c.JSON(http.StatusOK, res.Response)
+}
+
+// startMonitoring : resquest to monitoring to start tracing
+func (s *APIService) startMonitoring(c *gin.Context) {
+
+ xdspvr, err := s._initXdsMonitoring()
+ if err != nil {
+ common.APIError(c, err.Error())
+ return
+ }
+
+ var cfg XdsSuperVTraceConfig
+ if c.BindJSON(&cfg) != nil {
+ common.APIError(c, "Invalid config argument")
+ return
+ }
+ s.Log.Debugf("Start Monitoring cfgArg %v", cfg)
+
+ res := aglafb.NewAfbReply()
+ if err = xdspvr.StartTrace(cfg, res); err != nil {
+ common.APIError(c, err.Error())
+ return
+ }
+
+ if !res.Success() {
+ common.APIError(c, res.GetInfo())
+ return
+ }
+
+ c.JSON(http.StatusOK, res.Response)
+}
+
+// stopMonitoring : resquest to monitoring to stop tracing
+func (s *APIService) stopMonitoring(c *gin.Context) {
+
+ xdspvr, err := s._initXdsMonitoring()
+ if err != nil {
+ common.APIError(c, err.Error())
+ return
+ }
+
+ var res aglafb.AfbReply
+ if err = xdspvr.StopTrace(&res); err != nil {
+ common.APIError(c, err.Error())
+ return
+ }
+
+ if res.Request.Status != "success" {
+ common.APIError(c, res.Request.Info)
+ return
+ }
+
+ c.JSON(http.StatusOK, res.Response)
+}
+
+// _initXdsMonitoring .
+func (s *APIService) _initXdsMonitoring() (*XdsMonitoring, error) {
+
+ if s.XdsMonitoring == nil {
+ xs := NewXdsMonitoring(s.Context)
+ if err := xs.Connect(); err != nil {
+ return nil, err
+ }
+ s.XdsMonitoring = xs
+ }
+ return s.XdsMonitoring, nil
+}
+
+//************************* AGL Low Collector *************************
+
+// XdsLowCollectorConfig Configuration structure for ALC
+type XdsLowCollectorConfig struct {
+ Time int `json:"time"`
+}
+
+// StartLowCollector : resquest to Start low collector
+func (s *APIService) StartLowCollector(c *gin.Context) {
+
+ alc, err := s._initXdsLowCollector()
+ if err != nil {
+ common.APIError(c, err.Error())
+ return
+ }
+
+ s.Log.Debugf("Init & config AGL Low Collector")
+
+ if err = alc.Init(); err != nil {
+ common.APIError(c, err.Error())
+ return
+ }
+
+ // // Config is optional, if not set used define settings
+ var cfg XdsLowCollectorConfig
+ c.ShouldBindJSON(&cfg)
+
+ s.Log.Debugf("Start Low Collector cfgArg %v", cfg)
+
+ if err = alc.Start(cfg.Time); err != nil {
+ common.APIError(c, err.Error())
+ return
+ }
+
+ c.JSON(http.StatusOK, "done")
+}
+
+// StopLowCollector : resquest to Stop low collector
+func (s *APIService) StopLowCollector(c *gin.Context) {
+
+ alc, err := s._initXdsLowCollector()
+ if err != nil {
+ common.APIError(c, err.Error())
+ return
+ }
+
+ s.Log.Debugf("Stop AGL Low Collector")
+
+ if err = alc.Stop(); err != nil {
+ common.APIError(c, err.Error())
+ }
+
+ // SEB TODO
+ res := "done"
+ c.JSON(http.StatusOK, res)
+}
+
+// ReadLowCollector : read one data
+func (s *APIService) ReadLowCollector(c *gin.Context) {
+
+ alc, err := s._initXdsLowCollector()
+ if err != nil {
+ common.APIError(c, err.Error())
+ return
+ }
+ plugin := "cpu"
+ s.Log.Debugf("Read data of %s plugin AGL Low Collector", plugin)
+
+ var data interface{}
+ if err = alc.Read(&data); err != nil {
+ common.APIError(c, err.Error())
+ }
+
+ // SEB TODO
+ res := "done"
+ c.JSON(http.StatusOK, res)
+}
+
+// ResetLowCollector : Reset Low Collector
+func (s *APIService) ResetLowCollector(c *gin.Context) {
+ // SEB TODO
+ common.APIError(c, "Not implemented yet")
+}
+
+// _initXdsLowCollector .
+func (s *APIService) _initXdsLowCollector() (*XdsLowCollector, error) {
+
+ if s.XdsLowCollector == nil {
+ alc := NewXdsLowCollector(s.Context)
+ if err := alc.Connect(); err != nil {
+ return nil, err
+ }
+ s.XdsLowCollector = alc
+ }
+ return s.XdsLowCollector, nil
+}
diff --git a/lib/agent/apiv1-supervisor.go b/lib/agent/apiv1-supervisor.go
deleted file mode 100644
index 20b9549..0000000
--- a/lib/agent/apiv1-supervisor.go
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2017-2018 "IoT.bzh"
- * Author Sebastien Douheret <sebastien@iot.bzh>
- *
- * 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.
- */
-
-package agent
-
-import (
- "net/http"
-
- common "gerrit.automotivelinux.org/gerrit/src/xds/xds-common.git"
- "github.com/gin-gonic/gin"
-)
-
-// getSupervisorTopo : return current AGL daemons topology using supervisor
-func (s *APIService) getSupervisorTopo(c *gin.Context) {
-
- xdspvr, err := s._initXdsSupervisor()
- if err != nil {
- common.APIError(c, err.Error())
- return
- }
-
- var res XdsSuperVReply
- if err = xdspvr.GetTopo(&res); err != nil {
- common.APIError(c, err.Error())
- return
- }
-
- if res.Request.Status != "success" {
- common.APIError(c, res.Request.Info)
- return
- }
-
- c.JSON(http.StatusOK, res.Response)
-}
-
-// startSupervisor : resquest to supervisor to start tracing
-func (s *APIService) startSupervisor(c *gin.Context) {
-
- xdspvr, err := s._initXdsSupervisor()
- if err != nil {
- common.APIError(c, err.Error())
- return
- }
-
- var cfg XdsSuperVTraceConfig
- if c.BindJSON(&cfg) != nil {
- common.APIError(c, "Invalid config argument")
- return
- }
- s.Log.Debugf("Start Supervisor cfgArg %v\n", cfg)
-
- var res XdsSuperVReply
- if err = xdspvr.StartTrace(cfg, &res); err != nil {
- common.APIError(c, err.Error())
- return
- }
-
- if res.Request.Status != "success" {
- common.APIError(c, res.Request.Info)
- return
- }
-
- c.JSON(http.StatusOK, res.Response)
-}
-
-// stopSupervisor : resquest to supervisor to stop tracing
-func (s *APIService) stopSupervisor(c *gin.Context) {
-
- xdspvr, err := s._initXdsSupervisor()
- if err != nil {
- common.APIError(c, err.Error())
- return
- }
-
- var res XdsSuperVReply
- if err = xdspvr.StopTrace(&res); err != nil {
- common.APIError(c, err.Error())
- return
- }
-
- if res.Request.Status != "success" {
- common.APIError(c, res.Request.Info)
- return
- }
-
- c.JSON(http.StatusOK, res.Response)
-}
-
-// _initXdsSupervisor .
-func (s *APIService) _initXdsSupervisor() (*XdsSupervisor, error) {
-
- if s.XdsSupervisor == nil {
- xs := NewXdsSupervisor(s.Context)
- if err := xs.Connect(); err != nil {
- return nil, err
- }
- s.XdsSupervisor = xs
- }
- return s.XdsSupervisor, nil
-}
diff --git a/lib/agent/apiv1.go b/lib/agent/apiv1.go
index 4637bc4..ef9704c 100644
--- a/lib/agent/apiv1.go
+++ b/lib/agent/apiv1.go
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017-2018 "IoT.bzh"
+ * Copyright (C) 2017-2019 "IoT.bzh"
* Author Sebastien Douheret <sebastien@iot.bzh>
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -67,9 +67,13 @@ func NewAPIV1(ctx *Context) *APIService {
s.apiRouter.POST("/events/register", s.eventsRegister)
s.apiRouter.POST("/events/unregister", s.eventsUnRegister)
- s.apiRouter.GET("/supervisor/topo", s.getSupervisorTopo)
- s.apiRouter.POST("/supervisor/trace/start", s.startSupervisor)
- s.apiRouter.POST("/supervisor/trace/stop", s.stopSupervisor)
+ s.apiRouter.GET("/monitoring/topo", s.getMonitoringTopo)
+ s.apiRouter.POST("/monitoring/trace/start", s.startMonitoring)
+ s.apiRouter.POST("/monitoring/trace/stop", s.stopMonitoring)
+ s.apiRouter.POST("/monitoring/alc/start", s.StartLowCollector)
+ s.apiRouter.POST("/monitoring/alc/stop", s.StopLowCollector)
+ s.apiRouter.GET("/monitoring/alc/read", s.ReadLowCollector)
+ s.apiRouter.POST("/monitoring/alc/reset", s.ResetLowCollector)
return s
}
diff --git a/lib/agent/xds-low-collector.go b/lib/agent/xds-low-collector.go
new file mode 100644
index 0000000..fdf696d
--- /dev/null
+++ b/lib/agent/xds-low-collector.go
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2019 "IoT.bzh"
+ * Author Sebastien Douheret <sebastien@iot.bzh>
+ *
+ * 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.
+ */
+
+package agent
+
+import (
+ "fmt"
+ "io"
+ "strings"
+ "time"
+
+ "gerrit.automotivelinux.org/gerrit/src/xds/xds-agent.git/lib/aglafb"
+ common "gerrit.automotivelinux.org/gerrit/src/xds/xds-common.git"
+ uuid "github.com/satori/go.uuid"
+)
+
+// XdsLowCollector .
+type XdsLowCollector struct {
+ *Context
+ ID string
+ BaseURL string
+ ConnRetry int
+ Connected bool
+ Disabled bool
+ DefaultPlugins []string
+ DefaultCollectTime int
+ // Private fields
+ client *common.HTTPClient
+ logOut io.Writer
+ cbOnConnect OnConnectedXdsAlcCB
+}
+
+// OnConnectedXdsAlcCB connect callback
+type OnConnectedXdsAlcCB func(svr *XdsLowCollector) error
+
+// NewXdsLowCollector creates an instance of XdsLowCollector
+func NewXdsLowCollector(ctx *Context) *XdsLowCollector {
+ return &XdsLowCollector{
+ Context: ctx,
+ ID: "XdsAlc-" + uuid.NewV1().String(),
+ BaseURL: ctx.Config.FileConf.ProfileConf.XDSLowCollector.URL,
+ ConnRetry: ctx.Config.FileConf.ProfileConf.XDSLowCollector.ConnRetry,
+ Connected: false,
+ Disabled: false,
+ logOut: ctx.Log.Out,
+ DefaultPlugins: []string{
+ "cpu",
+ "memory",
+ // SEB "processes",
+ //"cpufreq",
+ //"thermal",
+ //"systemd_journal",
+ // SEB "systemd_file",
+ },
+ DefaultCollectTime: 5,
+ }
+}
+
+// Connect Establish HTTP connection with XDS Low Collector Dameon
+func (xs *XdsLowCollector) Connect() error {
+ var err error
+ var retry int
+
+ xs.Disabled = false
+ xs.Connected = false
+
+ err = nil
+ for retry = xs.ConnRetry; retry > 0; retry-- {
+ if err = xs._CreateConnectHTTP(); err == nil {
+ break
+ }
+ if retry == xs.ConnRetry {
+ // Notify only on the first conn error
+ // doing that avoid 2 notifs (conn false; conn true) on startup
+ xs._NotifyState()
+ }
+ xs.Log.Infof("Establishing connection to XDS Low Collector daemon (retry %d/%d)", retry, xs.ConnRetry)
+ time.Sleep(time.Second)
+ }
+ if retry == 0 {
+ // FIXME: re-use _Reconnect to wait longer in background
+ return fmt.Errorf("Connection to XDS Low Collector daemon failure")
+ }
+ if err != nil {
+ return err
+ }
+
+ // Check HTTP connection and establish WS connection
+ err = xs._Connect(false)
+
+ return err
+}
+
+// ConnectOn Register a callback on events reception
+func (xs *XdsLowCollector) ConnectOn(f OnConnectedXdsAlcCB) error {
+ xs.cbOnConnect = f
+ return nil
+}
+
+// GetVersion Send Get request to retrieve XDS Low Collector version
+func (xs *XdsLowCollector) GetVersion(res interface{}) error {
+ // FIXME add suffix URLSuffix in common HTTP client lib instead of _BuildURL
+ return xs.client.Get(xs._BuildURL("/version"), &res)
+}
+
+// Init Initialize collector plugins
+func (xs *XdsLowCollector) Init() error {
+ var err error
+
+ // Directly send config in order to init and config plugins
+
+ type alcCfgPluginT struct {
+ Plugin string `json:"plugin"`
+ Config string `json:"config"`
+ }
+
+ cfg := []alcCfgPluginT{}
+
+ for _, p := range xs.DefaultPlugins {
+ cfg = append(cfg, alcCfgPluginT{
+ Plugin: p,
+ Config: "default",
+ })
+ }
+
+ res := aglafb.NewAfbReply()
+ xs.Log.Debugf("Low Collector /config %v", cfg)
+ err = xs.client.Post(xs._BuildURL("/config"), cfg, res)
+
+ if err == nil && !res.Success() {
+ err = res.GetError()
+ }
+
+ return err
+}
+
+// Start data collection
+func (xs *XdsLowCollector) Start(time int) error {
+ var err error
+
+ // TODO - SEB : support start one or multiple plugins
+
+ if time == 0 {
+ time = xs.DefaultCollectTime
+ }
+
+ type alcStartT struct {
+ Plugin string `json:"plugin"`
+ Time int `json:"time"`
+ }
+
+ // TODO SEB : allow to start only 1 plugin
+ allInOne := true
+ if allInOne {
+
+ cfg := []alcStartT{}
+ for _, p := range xs.DefaultPlugins {
+ cfg = append(cfg, alcStartT{Plugin: p, Time: time})
+ }
+
+ res := aglafb.NewAfbReply()
+ xs.Log.Debugf("Low Collector /start %v", cfg)
+ err = xs.client.Post(xs._BuildURL("/start"), cfg, res)
+
+ if err == nil && !res.Success() {
+ err = res.GetError()
+ }
+ } else {
+ for _, p := range xs.DefaultPlugins {
+ cfg := alcStartT{Plugin: p, Time: time}
+
+ res := aglafb.NewAfbReply()
+ xs.Log.Debugf("Low Collector /start %v", cfg)
+ err = xs.client.Post(xs._BuildURL("/start"), cfg, res)
+ if err != nil {
+ return err
+ }
+ if !res.Success() {
+ return res.GetError()
+ }
+ }
+ }
+
+ return err
+}
+
+// Stop data collection
+func (xs *XdsLowCollector) Stop() error {
+
+ // TODO - SEB : support start one or multiple plugins
+
+ type alcStopT struct {
+ Plugin []string `json:"plugin"`
+ }
+
+ cfg := alcStopT{}
+ for _, p := range xs.DefaultPlugins {
+ cfg.Plugin = append(cfg.Plugin, p)
+ }
+
+ res := aglafb.NewAfbReply()
+ xs.Log.Debugf("Low Collector /stop %v", cfg)
+ err := xs.client.Post(xs._BuildURL("/stop"), cfg, res)
+
+ if err == nil && !res.Success() {
+ err = res.GetError()
+ }
+
+ return err
+}
+
+// Read a single data of a specific plugin
+func (xs *XdsLowCollector) Read(data interface{}) error {
+ return fmt.Errorf("No implemented")
+}
+
+/***
+** Private functions
+***/
+
+// _BuildURL .
+func (xs *XdsLowCollector) _BuildURL(url string) string {
+ return url + "?token=HELLO&uuid=magic"
+}
+
+// Create HTTP client
+func (xs *XdsLowCollector) _CreateConnectHTTP() error {
+ var err error
+ // FIXME SEB - Client key not in header but in cookie
+ // temporary workaround: used _BuildURL to append uuid=magic in URL
+ // map[Set-Cookie:[x-afb-uuid-5678=2b185cc3-276b-4097-91fa-d607eaf937e6; Path=/api; Max-Age=32000000; ...
+ //port := strings.Split(xs.BaseURL, ":")[2]
+ //"x-afb-uuid-" + port
+
+ xs.client, err = common.HTTPNewClient(xs.BaseURL,
+ common.HTTPClientConfig{
+ //HeaderClientKeyName: "Xds-Sid",
+ HeaderAPIKeyName: "token",
+ Apikey: "HELLO",
+ URLPrefix: "/api/alc",
+ CsrfDisable: true,
+ LogOut: xs.logOut,
+ LogPrefix: "XDSALC: ",
+ LogLevel: common.HTTPLogLevelWarning,
+ })
+
+ xs.client.SetLogLevel(xs.Log.Level.String())
+
+ if err != nil {
+ msg := ": " + err.Error()
+ if strings.Contains(err.Error(), "connection refused") {
+ msg = fmt.Sprintf("(url: %s)", xs.BaseURL)
+ }
+ return fmt.Errorf("ERROR: cannot connect to XDS Low Collector %s", msg)
+ }
+ if xs.client == nil {
+ return fmt.Errorf("ERROR: cannot connect to XDS Low Collector (null client)")
+ }
+
+ return nil
+}
+
+// _Connect Established HTTP and WS connection
+func (xs *XdsLowCollector) _Connect(reConn bool) error {
+ var res interface{}
+ if err := xs.client.Get(xs._BuildURL("/ping"), &res); err != nil {
+
+ // SEB FIXME tempo Hack
+ time.Sleep(time.Microsecond * 300)
+ if err := xs.client.Get(xs._BuildURL("/ping"), &res); err != nil {
+ // SEB Hack tempo
+ // xs.Connected = false
+ // if !reConn {
+ // xs._NotifyState()
+ // }
+ // return err
+ }
+ }
+
+ xs.Connected = true
+
+ // Call OnConnect callback
+ if xs.cbOnConnect != nil {
+ xs.cbOnConnect(xs)
+ }
+
+ xs._NotifyState()
+ return nil
+}
+
+// _NotifyState Send event to notify changes
+func (xs *XdsLowCollector) _NotifyState() {
+
+ /* TODO
+ evSts := xaapiv1.ServerCfg{
+ ID: xs.ID,
+ URL: xs.BaseURL,
+ APIURL: xs.APIURL,
+ PartialURL: xs.PartialURL,
+ ConnRetry: xs.ConnRetry,
+ Connected: xs.Connected,
+ }
+ if err := xs.events.Emit(xaapiv1.EVTServerConfig, evSts, ""); err != nil {
+ xs.Log.Warningf("Cannot notify XdsServer state change: %v", err)
+ }
+ */
+}
diff --git a/lib/agent/xdssupervior.go b/lib/agent/xdsmonitoring.go
index 48b3f90..42e5324 100644
--- a/lib/agent/xdssupervior.go
+++ b/lib/agent/xdsmonitoring.go
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017-2018 "IoT.bzh"
+ * Copyright (C) 2017-2019 "IoT.bzh"
* Author Sebastien Douheret <sebastien@iot.bzh>
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -27,8 +27,8 @@ import (
uuid "github.com/satori/go.uuid"
)
-// XdsSupervisor .
-type XdsSupervisor struct {
+// XdsMonitoring .
+type XdsMonitoring struct {
*Context
ID string
BaseURL string
@@ -42,19 +42,6 @@ type XdsSupervisor struct {
cbOnConnect OnConnectedXdsSupervCB
}
-// XdsSuperVRequest Resquest field of a reply
-type XdsSuperVRequest struct {
- Status string `json:"status"`
- Info string `json:"info"`
-}
-
-// XdsSuperVReply Reply structure of XDS Supervision Daemon
-type XdsSuperVReply struct {
- JType string `json:"jtype"`
- Request XdsSuperVRequest `json:"request"`
- Response interface{} `json:"response"`
-}
-
// XdsSuperVTraceConfig
type XdsSuperVTraceConfig struct {
Pid int `json:"pid"`
@@ -63,15 +50,15 @@ type XdsSuperVTraceConfig struct {
}
// OnConnectedXdsSupervCB connect callback
-type OnConnectedXdsSupervCB func(svr *XdsSupervisor) error
+type OnConnectedXdsSupervCB func(svr *XdsMonitoring) error
-// NewXdsSupervisor creates an instance of XdsSupervisor
-func NewXdsSupervisor(ctx *Context) *XdsSupervisor {
- return &XdsSupervisor{
+// NewXdsMonitoring creates an instance of XdsMonitoring
+func NewXdsMonitoring(ctx *Context) *XdsMonitoring {
+ return &XdsMonitoring{
Context: ctx,
- ID: "XdsSupervisor-" + uuid.NewV1().String(),
- BaseURL: ctx.Config.FileConf.ProfileConf.XDSBinder.URL,
- ConnRetry: ctx.Config.FileConf.ProfileConf.XDSBinder.ConnRetry,
+ ID: "XdsMonitoring-" + uuid.NewV1().String(),
+ BaseURL: ctx.Config.FileConf.ProfileConf.XDSMonitoring.URL,
+ ConnRetry: ctx.Config.FileConf.ProfileConf.XDSMonitoring.ConnRetry,
Connected: false,
Disabled: false,
@@ -79,8 +66,8 @@ func NewXdsSupervisor(ctx *Context) *XdsSupervisor {
}
}
-// Connect Establish HTTP connection with XDS Supervisor Dameon
-func (xs *XdsSupervisor) Connect() error {
+// Connect Establish HTTP connection with XDS Monitoring Dameon
+func (xs *XdsMonitoring) Connect() error {
var err error
var retry int
@@ -97,12 +84,12 @@ func (xs *XdsSupervisor) Connect() error {
// doing that avoid 2 notifs (conn false; conn true) on startup
xs._NotifyState()
}
- xs.Log.Infof("Establishing connection to XDS Supervisor daemon (retry %d/%d)", retry, xs.ConnRetry)
+ xs.Log.Infof("Establishing connection to XDS Monitoring daemon (retry %d/%d)", retry, xs.ConnRetry)
time.Sleep(time.Second)
}
if retry == 0 {
// FIXME: re-use _Reconnect to wait longer in background
- return fmt.Errorf("Connection to XDS Supervisor daemon failure")
+ return fmt.Errorf("Connection to XDS Monitoring daemon failure")
}
if err != nil {
return err
@@ -115,29 +102,29 @@ func (xs *XdsSupervisor) Connect() error {
}
// ConnectOn Register a callback on events reception
-func (xs *XdsSupervisor) ConnectOn(f OnConnectedXdsSupervCB) error {
+func (xs *XdsMonitoring) ConnectOn(f OnConnectedXdsSupervCB) error {
xs.cbOnConnect = f
return nil
}
-// GetVersion Send Get request to retrieve XDS Supervision version
-func (xs *XdsSupervisor) GetVersion(res interface{}) error {
+// GetVersion Send Get request to retrieve XDS Monitoring version
+func (xs *XdsMonitoring) GetVersion(res interface{}) error {
// FIXME add suffix URLSuffix in common HTTP client lib instead of _BuildURL
return xs.client.Get(xs._BuildURL("/version"), &res)
}
// GetTopo Send Get request to retrieve Services/Daemons topology
-func (xs *XdsSupervisor) GetTopo(res interface{}) error {
+func (xs *XdsMonitoring) GetTopo(res interface{}) error {
return xs.client.Get(xs._BuildURL("/list"), &res)
}
-// StartTrace Send Supervisor config and start tracing
-func (xs *XdsSupervisor) StartTrace(cfg XdsSuperVTraceConfig, res interface{}) error {
+// StartTrace Send Monitoring config and start tracing
+func (xs *XdsMonitoring) StartTrace(cfg XdsSuperVTraceConfig, res interface{}) error {
return xs.client.Post(xs._BuildURL("/trace/start"), cfg, &res)
}
-// StopTrace Send Supervisor stop tracing
-func (xs *XdsSupervisor) StopTrace(res interface{}) error {
+// StopTrace Send Monitoring stop tracing
+func (xs *XdsMonitoring) StopTrace(res interface{}) error {
var cfg interface{}
return xs.client.Post(xs._BuildURL("/trace/stop"), cfg, res)
}
@@ -147,12 +134,12 @@ func (xs *XdsSupervisor) StopTrace(res interface{}) error {
***/
// _BuildURL .
-func (xs *XdsSupervisor) _BuildURL(url string) string {
+func (xs *XdsMonitoring) _BuildURL(url string) string {
return url + "?token=HELLO&uuid=magic"
}
// Create HTTP client
-func (xs *XdsSupervisor) _CreateConnectHTTP() error {
+func (xs *XdsMonitoring) _CreateConnectHTTP() error {
var err error
// FIXME SEB - Client key not in header but in cookie
// temporary workaround: used _BuildURL to append uuid=magic in URL
@@ -179,17 +166,17 @@ func (xs *XdsSupervisor) _CreateConnectHTTP() error {
if strings.Contains(err.Error(), "connection refused") {
msg = fmt.Sprintf("(url: %s)", xs.BaseURL)
}
- return fmt.Errorf("ERROR: cannot connect to XDS Supervisor %s", msg)
+ return fmt.Errorf("ERROR: cannot connect to XDS Monitoring %s", msg)
}
if xs.client == nil {
- return fmt.Errorf("ERROR: cannot connect to XDS Supervisor (null client)")
+ return fmt.Errorf("ERROR: cannot connect to XDS Monitoring (null client)")
}
return nil
}
// _Connect Established HTTP and WS connection
-func (xs *XdsSupervisor) _Connect(reConn bool) error {
+func (xs *XdsMonitoring) _Connect(reConn bool) error {
var res interface{}
if err := xs.client.Get(xs._BuildURL("/ping"), &res); err != nil {
@@ -212,7 +199,7 @@ func (xs *XdsSupervisor) _Connect(reConn bool) error {
}
// _NotifyState Send event to notify changes
-func (xs *XdsSupervisor) _NotifyState() {
+func (xs *XdsMonitoring) _NotifyState() {
/* TODO
evSts := xaapiv1.ServerCfg{
diff --git a/lib/aglafb/afb.go b/lib/aglafb/afb.go
new file mode 100644
index 0000000..85f6686
--- /dev/null
+++ b/lib/aglafb/afb.go
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2019 "IoT.bzh"
+ * Author Sebastien Douheret <sebastien@iot.bzh>
+ *
+ * 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.
+ */
+
+package aglafb
+
+import "fmt"
+
+// AfbRequest Resquest field of a reply
+type AfbRequest struct {
+ Status string `json:"status"`
+ Info string `json:"info"`
+}
+
+// AfbReply Reply structure of XDS Monitoring Daemon
+type AfbReply struct {
+ JType string `json:"jtype"`
+ Request AfbRequest `json:"request"`
+ Response interface{} `json:"response"`
+}
+
+func NewAfbReply() *AfbReply {
+ return &AfbReply{}
+}
+
+func (r *AfbReply) Success() bool {
+ return r.Request.Status == "success"
+}
+
+func (r *AfbReply) Failure() bool {
+ return !r.Success()
+}
+
+func (r *AfbReply) GetError() error {
+ return fmt.Errorf(r.Request.Info)
+}
+
+func (r *AfbReply) GetInfo() string {
+ return r.Request.Info
+}
diff --git a/lib/xdsconfig/config.go b/lib/xdsconfig/config.go
index 93c8f4b..6a5e750 100644
--- a/lib/xdsconfig/config.go
+++ b/lib/xdsconfig/config.go
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017-2018 "IoT.bzh"
+ * Copyright (C) 2017-2019 "IoT.bzh"
* Author Sebastien Douheret <sebastien@iot.bzh>
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -92,10 +92,14 @@ func Init(ctx *cli.Context, log *logrus.Logger) (*Config, error) {
Home: defaultSTHomeDir,
},
ProfileConf: ProfileConfT{
- XDSBinder: XDSBinderConf{
+ XDSMonitoring: XDSMonitoringConf{
URL: "http://localhost:8810",
ConnRetry: 10,
},
+ XDSLowCollector: XDSLowCollectorConf{
+ URL: "http://localhost:8820",
+ ConnRetry: 10,
+ },
},
},
Log: log,
diff --git a/lib/xdsconfig/configfile.go b/lib/xdsconfig/configfile.go
index 7ddb010..85e26bc 100644
--- a/lib/xdsconfig/configfile.go
+++ b/lib/xdsconfig/configfile.go
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017-2018 "IoT.bzh"
+ * Copyright (C) 2017-2019 "IoT.bzh"
* Author Sebastien Douheret <sebastien@iot.bzh>
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -43,13 +43,19 @@ type XDSServerConf struct {
APIPartialURL string `json:"-"`
}
-type XDSBinderConf struct {
+type XDSMonitoringConf struct {
+ URL string `json:"url"`
+ ConnRetry int `json:"connRetry"`
+}
+
+type XDSLowCollectorConf struct {
URL string `json:"url"`
ConnRetry int `json:"connRetry"`
}
type ProfileConfT struct {
- XDSBinder XDSBinderConf `json:"xdsBinder"`
+ XDSMonitoring XDSMonitoringConf `json:"xdsMonitoring"`
+ XDSLowCollector XDSLowCollectorConf `json:"xdsLowCollector"`
}
type FileConfig struct {
diff --git a/webapp/src/app/@core-xds/services/@core-xds-services.module.ts b/webapp/src/app/@core-xds/services/@core-xds-services.module.ts
index 6a4eb3c..b3606ec 100644
--- a/webapp/src/app/@core-xds/services/@core-xds-services.module.ts
+++ b/webapp/src/app/@core-xds/services/@core-xds-services.module.ts
@@ -23,7 +23,7 @@ import { AlertService } from './alert.service';
import { ConfigService } from './config.service';
import { ProjectService } from './project.service';
import { SdkService } from './sdk.service';
-import { SupervisionService } from './supervision.service';
+import { MonitoringService } from './monitoring.service';
import { TargetService } from './target.service';
import { UserService } from './users.service';
import { XDSConfigService } from './xds-config.service';
@@ -34,7 +34,7 @@ const SERVICES = [
ConfigService,
ProjectService,
SdkService,
- SupervisionService,
+ MonitoringService,
TargetService,
UserService,
XDSConfigService,
diff --git a/webapp/src/app/@core-xds/services/monitoring.service.ts b/webapp/src/app/@core-xds/services/monitoring.service.ts
new file mode 100644
index 0000000..a606909
--- /dev/null
+++ b/webapp/src/app/@core-xds/services/monitoring.service.ts
@@ -0,0 +1,106 @@
+/**
+* @license
+* Copyright (C) 2018-2019 "IoT.bzh"
+* Author Sebastien Douheret <sebastien@iot.bzh>
+*
+* 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.
+*/
+
+import { Injectable } from '@angular/core';
+import { Observable } from 'rxjs/Observable';
+
+import { XDSAgentService } from './xdsagent.service';
+import { map } from 'rxjs/operators';
+
+export interface AglTopology {
+ name: string;
+ pid: number;
+ disabled: boolean;
+ isClient: boolean;
+ isServer: boolean;
+ ws_clients: string[];
+ ws_servers: string[];
+ apis: any;
+}
+
+export interface AglLowCollectorConfig {
+ time?: number;
+}
+
+@Injectable()
+export class MonitoringService {
+
+ constructor(private xdsSvr: XDSAgentService) {
+ /*
+ this.xdsSvr.XdsConfig$.subscribe(cfg => {
+ if (!cfg || cfg.servers.length < 1) {
+ return;
+ }
+ });
+ */
+ }
+
+ getTopo(): Observable<AglTopology[]> {
+ return this.xdsSvr.getTopoMonitoring().pipe(
+ map((tp: AglTopology[]) => {
+ // FIXME - move filter on backend side
+ const ignored: string[] = [
+ 'agl-low-collector',
+ 'harvester',
+ ];
+
+ tp.forEach(el => {
+ el.disabled = false;
+ ignored.forEach(iel => {
+ if (el.name.indexOf(iel) !== -1) {
+ el.disabled = true;
+ }
+ });
+
+ // replace unix:/run/xxx/ws by nothing
+ const wsc: string[] = [];
+ el.ws_clients.forEach(s => {
+ s = s.replace('unix:/run/platform/apis/ws/', '');
+ s = s.replace('unix:/run/user/1001/apis/ws/', '');
+ s = s.replace('unix:/run/user/0/apis/ws/', '');
+ wsc.push(s);
+ });
+ el.ws_clients = wsc;
+ // replace sd: by nothing
+ const wss: string[] = [];
+ el.ws_servers.forEach(s => {
+ wss.push(s.replace('sd:', ''));
+ });
+ el.ws_servers = wss;
+ });
+ return tp;
+ })
+ );
+ }
+
+ startTrace(cfg: any): Observable<any> {
+ return this.xdsSvr.startTraceMonitoring(cfg);
+ }
+
+ stopTrace(cfg: any): Observable<any> {
+ return this.xdsSvr.stopTraceMonitoring(cfg);
+ }
+
+ startLowCollector(cfg: AglLowCollectorConfig): Observable<any> {
+ return this.xdsSvr.startLowCollector(cfg);
+ }
+
+ stopLowCollector(): Observable<any> {
+ return this.xdsSvr.stopLowCollector();
+ }
+}
diff --git a/webapp/src/app/@core-xds/services/supervision.service.ts b/webapp/src/app/@core-xds/services/supervision.service.ts
deleted file mode 100644
index 4a9f578..0000000
--- a/webapp/src/app/@core-xds/services/supervision.service.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
-* @license
-* Copyright (C) 2018 "IoT.bzh"
-* Author Sebastien Douheret <sebastien@iot.bzh>
-*
-* 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.
-*/
-
-import { Injectable, SecurityContext, isDevMode } from '@angular/core';
-import { Observable } from 'rxjs/Observable';
-
-import { XDSAgentService } from '../services/xdsagent.service';
-
-export interface AglTopology {
- name: string;
- pid: number;
- isClient: boolean;
- isServer: boolean;
- ws_clients: string[];
- ws_servers: string[];
- apis: any;
-}
-
-@Injectable()
-export class SupervisionService {
-
- private curServerID;
-
- constructor(private xdsSvr: XDSAgentService) {
- /*
- this.xdsSvr.XdsConfig$.subscribe(cfg => {
- if (!cfg || cfg.servers.length < 1) {
- return;
- }
- });
- */
- }
-
- getTopo(): Observable<AglTopology[]> {
- return this.xdsSvr.getTopoSupervisor();
- }
-
- startTrace(cfg: any): Observable<any> {
- return this.xdsSvr.startTraceSupervisor(cfg);
- }
-
- stopTrace(cfg: any): Observable<any> {
- return this.xdsSvr.stopTraceSupervisor(cfg);
- }
-
-}
diff --git a/webapp/src/app/@core-xds/services/xdsagent.service.ts b/webapp/src/app/@core-xds/services/xdsagent.service.ts
index 002c84b..35abe46 100644
--- a/webapp/src/app/@core-xds/services/xdsagent.service.ts
+++ b/webapp/src/app/@core-xds/services/xdsagent.service.ts
@@ -1,6 +1,6 @@
/**
* @license
-* Copyright (C) 2017-2018 "IoT.bzh"
+* Copyright (C) 2017-2019 "IoT.bzh"
* Author Sebastien Douheret <sebastien@iot.bzh>
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -666,18 +666,33 @@ export class XDSAgentService {
}
/***
- ** Supervision
+ ** Monitoring
***/
- getTopoSupervisor(): Observable<any> {
- return this._get('/supervisor/topo');
+ getTopoMonitoring(): Observable<any> {
+ return this._get('/monitoring/topo');
}
- startTraceSupervisor(cfg: any): Observable<any> {
- return this._post('/supervisor/trace/start', cfg);
+ startTraceMonitoring(cfg: any): Observable<any> {
+ return this._post('/monitoring/trace/start', cfg);
}
- stopTraceSupervisor(cfg: any): Observable<any> {
- return this._post('/supervisor/trace/stop', cfg);
+ stopTraceMonitoring(cfg: any): Observable<any> {
+ return this._post('/monitoring/trace/stop', cfg);
+ }
+
+ /***
+ ** AGL Low Collector
+ ***/
+ startLowCollector(cfg: any): Observable<any> {
+ return this._post('/monitoring/alc/start', cfg);
+ }
+
+ stopLowCollector(): Observable<any> {
+ return this._post('/monitoring/alc/stop', {});
+ }
+
+ resetLowCollector(): Observable<any> {
+ return this._post('/monitoring/alc/reset', {});
}
/**
@@ -692,7 +707,7 @@ export class XDSAgentService {
error => {
this.alert.error('ERROR while registering to all events: ' + error);
},
- );
+ );
}
private _getServer(ID: string): IXDServerCfg {
diff --git a/webapp/src/app/pages/config/config-global/config-global.component.html b/webapp/src/app/pages/config/config-global/config-global.component.html
index c3bc8b4..3ae77d9 100644
--- a/webapp/src/app/pages/config/config-global/config-global.component.html
+++ b/webapp/src/app/pages/config/config-global/config-global.component.html
@@ -26,7 +26,7 @@
<div class="col-md-12">
<nb-card>
- <nb-card-header>Supervision Configuration</nb-card-header>
+ <nb-card-header>Monitoring Configuration</nb-card-header>
<nb-card-body>
<form (ngSubmit)="onSubmit()" #ConfigGlobalForm="ngForm">
<div class="form-group row">
diff --git a/webapp/src/app/pages/monitoring/monitoring-config.component.html b/webapp/src/app/pages/monitoring/monitoring-config.component.html
new file mode 100644
index 0000000..ed76dd0
--- /dev/null
+++ b/webapp/src/app/pages/monitoring/monitoring-config.component.html
@@ -0,0 +1,77 @@
+<div class="row col-md-12">
+ <div class="col-md-2" style="display: inherit;">
+ <h3 style="margin-top: auto; margin-bottom: auto">Configuration</h3>
+ </div>
+ <div class="col-md-1">
+ <nb-card-body>
+ <div class="col-md-9">
+ <nb-actions size="small">
+ <nb-action>
+ <button id="refresh-topo" (click)="getAGLTopo()">
+ <i class="fa fa-refresh"></i>
+ </button>
+ </nb-action>
+ </nb-actions>
+ </div>
+ </nb-card-body>
+ </div>
+
+ <div class="col-md-8" style="text-align: right;">
+ <label>Monitoring actions</label>
+ <button id="start-trace" class="btn btn-primary" (click)="onStartTrace()" [disabled]="
+ isStartBtnDisable()">{{ starting ?"Starting... ":"Start" }}
+ <span *ngIf="starting" class="fa fa-gear faa-spin animated fa-size-x2"></span>
+ </button>
+
+ <button id="stop-trace" class="btn btn-primary" (click)="onStopTrace()" [disabled]="
+ isStopBtnDisable()">{{ stopping ?"Stopping... ":"Stop" }}
+ <span *ngIf="stopping" class="fa fa-gear faa-spin animated fa-size-x2"></span>
+ </button>
+
+ <button id="show-graph" class="btn btn-primary" (click)="showGraph()">
+ Show Graph
+ </button>
+ </div>
+</div>
+<div class="row col-md-12">
+ <table class="table table-striped" style="color:black;">
+ <tbody>
+ <tr>
+ <th>Name</th>
+ <th style="width: 6rem;">Pid</th>
+ <th>WS Clients</th>
+ <th>WS Servers</th>
+ <th style="width: 6rem;">Monitor</th>
+ </tr>
+ <ng-container *ngIf="aglTopoInit; else loading">
+ <ng-container *ngIf="daemonCheckboxes?.length; else noItems">
+ <tr *ngFor="let tp of daemonCheckboxes">
+ <td *ngFor="let col of ['name', 'pid', 'ws_clients', 'ws_servers']">
+ {{tp.topo[col]}}
+ </td>
+ <td style="text-align: center;">
+ <ng-container *ngIf="!tp.topo.disabled else disableTopo">
+ <nb-checkbox indeterminate [(ngModel)]="tp.value"></nb-checkbox>
+ </ng-container>
+ <ng-template #disableTopo>
+ <span style="font-size: smaller; color: grey; font-style: italic;">DISABLED
+ </span>
+ </ng-template>
+ </td>
+ </tr>
+ </ng-container>
+ <ng-template #noItems>No Items!</ng-template>
+ <ng-template #loading>loading...</ng-template>
+ </ng-container>
+ <ng-template #loading>loading...</ng-template>
+ </tbody>
+ </table>
+</div>
+
+<div class="row col-md-6" style="display: inherit;">
+ <h3 style="margin-top: auto; margin-bottom: auto">AGL Bindings Topology</h3>
+</div>
+<div class="row col-md-12" style="">
+ <svg id="graph" width="100%" height="800">
+ </svg>
+</div>
diff --git a/webapp/src/app/pages/supervision/supervision-config.component.scss b/webapp/src/app/pages/monitoring/monitoring-config.component.scss
index 7b8d318..614f79d 100644
--- a/webapp/src/app/pages/supervision/supervision-config.component.scss
+++ b/webapp/src/app/pages/monitoring/monitoring-config.component.scss
@@ -101,6 +101,14 @@ button#refresh-topo {
}
}
+table {
+ table-layout: fixed;
+}
+
+td {
+ word-wrap:break-word;
+}
+
button#start-trace {
margin-top: 10px;
margin-left: 10px;
@@ -111,6 +119,11 @@ button#stop-trace {
margin-left: 10px;
}
+button#show-graph {
+ margin-top: 10px;
+ margin-left: 10px;
+}
+
#ws-client {
fill: green;
}
diff --git a/webapp/src/app/pages/supervision/supervision-config.component.ts b/webapp/src/app/pages/monitoring/monitoring-config.component.ts
index e96b936..2a5a84b 100644
--- a/webapp/src/app/pages/supervision/supervision-config.component.ts
+++ b/webapp/src/app/pages/monitoring/monitoring-config.component.ts
@@ -1,6 +1,6 @@
/**
* @license
-* Copyright (C) 2017-2018 "IoT.bzh"
+* Copyright (C) 2017-2019 "IoT.bzh"
* Author Sebastien Douheret <sebastien@iot.bzh>
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,30 +16,33 @@
* limitations under the License.
*/
-import { Component, OnInit, AfterViewInit, ViewEncapsulation } from '@angular/core';
-import { Injectable, Inject } from '@angular/core';
+import { Component, OnInit, AfterViewInit, ViewEncapsulation, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';
import * as d3 from 'd3';
+import { Router } from '@angular/router';
-import { SupervisionService, AglTopology } from '../../@core-xds/services/supervision.service';
+import { MonitoringService, AglTopology } from '../../@core-xds/services/monitoring.service';
import { AlertService } from '../../@core-xds/services/alert.service';
+import { BehaviorSubject } from 'rxjs/BehaviorSubject';
+import { Subscription } from 'rxjs/Subscription';
interface WsCheckbox {
- name: string;
- pid: number;
+ topo: AglTopology;
value: boolean;
- disabled: boolean;
tooltip: string;
}
@Component({
- selector: 'xds-supervision',
- styleUrls: ['./supervision-config.component.scss'],
- templateUrl: './supervision-config.component.html',
+ selector: 'xds-monitoring',
+ styleUrls: ['./monitoring-config.component.scss'],
+ templateUrl: './monitoring-config.component.html',
encapsulation: ViewEncapsulation.None, // workaround about https://github.com/angular/angular/issues/7845
})
-export class SupervisionConfigComponent implements OnInit, AfterViewInit {
+export class MonitoringConfigComponent implements OnInit, AfterViewInit {
+ aglTopoInit = new BehaviorSubject(false);
+ // FIXME: use Map instead of array and use '| keyvalue' for ngfor loop (but angular > 6.1 requested)
+ // daemonCheckboxes: Map<string, WsCheckbox> = new Map<string, WsCheckbox>();
daemonCheckboxes: WsCheckbox[] = [];
starting = false;
stopping = false;
@@ -47,26 +50,32 @@ export class SupervisionConfigComponent implements OnInit, AfterViewInit {
private graph: any;
private svg: any;
private links = [];
+ private _aglTopoSub: Subscription;
constructor(@Inject(DOCUMENT) private document: Document,
- private supervisorSvr: SupervisionService,
+ private router: Router,
+ private monitoringSvr: MonitoringService,
private alert: AlertService,
) {
}
ngOnInit() {
-
}
ngAfterViewInit() {
this.getAGLTopo();
+ this.aglTopoInit.next(true);
}
getAGLTopo() {
- this.supervisorSvr.getTopo().subscribe(topo => {
+ if (this._aglTopoSub !== undefined) {
+ this._aglTopoSub.unsubscribe();
+ }
+
+ this._aglTopoSub = this.monitoringSvr.getTopo().subscribe(topo => {
this.graphAGLBindings(topo);
- this.updateCheckboxes(topo);
+ this.createCheckboxes(topo);
});
}
@@ -74,11 +83,21 @@ export class SupervisionConfigComponent implements OnInit, AfterViewInit {
this.starting = true;
const dmArr = [];
- this.daemonCheckboxes.forEach(dm => dm.value && dmArr.push(dm.pid));
+ this.daemonCheckboxes.forEach(dm => dm.value && dmArr.push(dm.topo.pid));
+
+ this.monitoringSvr.startTrace({ pids: dmArr }).subscribe(res => {
+ // console.log('Trace Started: res', res);
+
+ this.monitoringSvr.startLowCollector(null).subscribe((/*res*/) => {
+ // console.log('Low Collector Started: res', res);
+ this.alert.info('Monitoring successfully started');
+ this.starting = false;
+
+ }, err => {
+ this.starting = false;
+ this.alert.error(err);
+ });
- this.supervisorSvr.startTrace({ pids: dmArr }).subscribe(res => {
- this.starting = false;
- this.alert.info('Monitoring successfully started');
}, err => {
this.starting = false;
this.alert.error(err);
@@ -87,15 +106,29 @@ export class SupervisionConfigComponent implements OnInit, AfterViewInit {
onStopTrace() {
this.stopping = true;
- this.supervisorSvr.stopTrace({}).subscribe(res => {
- this.stopping = false;
- this.alert.info('Monitoring successfully stopped');
+ this.monitoringSvr.stopTrace({}).subscribe(res => {
+ // console.log('Trace Stopped: res', res);
+
+ this.monitoringSvr.stopLowCollector().subscribe((/*res*/) => {
+ // console.log('Low Collector Stopped: res', res);
+ this.alert.info('Monitoring successfully started');
+ this.stopping = false;
+
+ }, err => {
+ this.stopping = false;
+ this.alert.error(err);
+ });
+
}, err => {
this.stopping = false;
this.alert.error(err);
});
}
+ showGraph() {
+ this.router.navigate([`/pages/monitoring/graph`]);
+ }
+
isStartBtnDisable(): boolean {
return this.starting;
}
@@ -104,18 +137,42 @@ export class SupervisionConfigComponent implements OnInit, AfterViewInit {
return this.stopping;
}
- private updateCheckboxes(topo: AglTopology[]) {
- this.daemonCheckboxes = [];
+ isDaemonDisabled(name: string): boolean {
+ let sts = false;
+ // FIXME - better to use map
+ // with Map
+ // if (this.daemonCheckboxes.has(name)) {
+ // sts = this.daemonCheckboxes[name].value;
+ // }
+ this.daemonCheckboxes.forEach(e => {
+ if (e.topo.name === name) {
+ sts = true;
+ }
+ });
+ return sts;
+ }
+
+ private createCheckboxes(topo: AglTopology[]) {
+
+ // let newDaemonChB: Map<string, WsCheckbox> = new Map<string, WsCheckbox>();
+ const newDaemonChB: WsCheckbox[] = [];
+ let prevVal = false;
+ this.daemonCheckboxes.forEach(e => {
+ if (e.topo.name === name) {
+ prevVal = e.value;
+ }
+ });
topo.forEach(elem => {
- this.daemonCheckboxes.push({
- name: elem.name,
- pid: elem.pid,
- value: false,
- disabled: false,
- tooltip: 'Daemon ' + elem.name + ' (pid ' + elem.pid + ')',
+ // with Map
+ // newDaemonChB.set(elem.name, {
+ newDaemonChB.push({
+ topo: Object.assign({}, elem),
+ value: prevVal,
+ tooltip: 'Daemon binding ' + elem.name + ' (pid ' + elem.pid + ')',
});
});
+ this.daemonCheckboxes = newDaemonChB;
}
diff --git a/webapp/src/app/pages/supervision/supervision.component.html b/webapp/src/app/pages/monitoring/monitoring.component.html
index 0db8ec8..c46817f 100644
--- a/webapp/src/app/pages/supervision/supervision.component.html
+++ b/webapp/src/app/pages/monitoring/monitoring.component.html
@@ -64,6 +64,6 @@
<!-- Display mode: using dashboard -->
<div class="row" *ngIf="displayMode==='dashboard'">
<div class="col-md-12">
- <iframe [src]="getDashboard('xds_supervisor')" width="100%" height="800px" frameborder="0"></iframe>
+ <iframe [src]="getDashboard('xds_monitoring')" width="100%" height="800px" frameborder="0"></iframe>
</div>
</div>
diff --git a/webapp/src/app/pages/supervision/supervision.component.scss b/webapp/src/app/pages/monitoring/monitoring.component.scss
index a125e8d..a125e8d 100644
--- a/webapp/src/app/pages/supervision/supervision.component.scss
+++ b/webapp/src/app/pages/monitoring/monitoring.component.scss
diff --git a/webapp/src/app/pages/supervision/supervision.component.ts b/webapp/src/app/pages/monitoring/monitoring.component.ts
index 3fff2b7..ccbe365 100644
--- a/webapp/src/app/pages/supervision/supervision.component.ts
+++ b/webapp/src/app/pages/monitoring/monitoring.component.ts
@@ -1,6 +1,6 @@
/**
* @license
-* Copyright (C) 2017-2018 "IoT.bzh"
+* Copyright (C) 2017-2019 "IoT.bzh"
* Author Sebastien Douheret <sebastien@iot.bzh>
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,13 +17,11 @@
*/
import { Component, OnInit, Input } from '@angular/core';
-import { Observable } from 'rxjs/Observable';
-import { Subject } from 'rxjs/Subject';
import { NbThemeService } from '@nebular/theme';
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
import { ConfigService, IConfig } from '../../@core-xds/services/config.service';
-import { SupervisionService } from '../../@core-xds/services/supervision.service';
+import { MonitoringService } from '../../@core-xds/services/monitoring.service';
import { AlertService } from '../../@core-xds/services/alert.service';
export interface GrafanaDashboard {
@@ -41,12 +39,12 @@ export interface GrafanaPanel {
}
@Component({
- selector: 'xds-supervision',
- styleUrls: ['./supervision.component.scss'],
- templateUrl: './supervision.component.html',
+ selector: 'xds-monitoring',
+ styleUrls: ['./monitoring.component.scss'],
+ templateUrl: './monitoring.component.html',
})
-export class SupervisionComponent implements OnInit {
+export class MonitoringComponent implements OnInit {
/* TODO bind tm_* and refresh in UI */
@Input() theme = 'light';
@@ -59,17 +57,17 @@ export class SupervisionComponent implements OnInit {
displayMode = 'dashboard';
private dashboards: Map<string, GrafanaDashboard> = new Map<string, GrafanaDashboard>([
- ['xds_supervisor', { name: 'AGL XDS Supervisor', shortname: 'agl-xds-supervisor' }],
+ ['xds_monitoring', { name: 'AGL XDS Monitoring', shortname: 'agl-xds-monitoring' }],
]);
private panels: Map<string, GrafanaPanel> = new Map<string, GrafanaPanel>([
- ['table', { name: 'Supervisor traces table', index: '2' }],
+ ['table', { name: 'Monitoring traces table', index: '2' }],
['evt_data_bytes', { name: 'Requests & Events per second', index: '5' }],
['req_evts_per_sec', { name: 'Events Data bytes', index: '12' }],
]);
constructor(
- private supervisionSvr: SupervisionService,
+ private monitoringSvr: MonitoringService,
private alert: AlertService,
private themeService: NbThemeService,
private sanitizer: DomSanitizer,
@@ -129,7 +127,7 @@ export class SupervisionComponent implements OnInit {
}
private _initDashboard() {
- // http://localhost:3000/d/Lbpwc6Iiz/agl-xds-supervisor?from=now-40s&to=now&refresh=5s
+ // http://localhost:3000/d/Lbpwc6Iiz/agl-xds-monitoring?from=now-40s&to=now&refresh=5s
this.dashboards.forEach(dd => {
dd.url = this._buildDashboardUrl(dd.shortname, this.tm_from, this.tm_to, this.refresh, this.theme);
dd.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(dd.url);
@@ -158,7 +156,7 @@ export class SupervisionComponent implements OnInit {
}
private _buildPanelUrl(idx, from, to, refresh, theme: string) {
- let url = 'http://localhost:3000/d-solo/Lbpwc6Iiz/agl-xds-supervisor';
+ let url = 'http://localhost:3000/d-solo/Lbpwc6Iiz/agl-xds-monitoring';
if (this.Config.grafanaDashboardUrl !== '') {
url = this.Config.grafanaDashboardUrl;
}
diff --git a/webapp/src/app/pages/supervision/supervision.module.ts b/webapp/src/app/pages/monitoring/monitoring.module.ts
index 4c1cb0b..0f8331f 100644
--- a/webapp/src/app/pages/supervision/supervision.module.ts
+++ b/webapp/src/app/pages/monitoring/monitoring.module.ts
@@ -19,8 +19,8 @@
import { NgModule } from '@angular/core';
import { ThemeModule } from '../../@theme/theme.module';
-import { SupervisionComponent } from './supervision.component';
-import { SupervisionConfigComponent } from './supervision-config.component';
+import { MonitoringComponent } from './monitoring.component';
+import { MonitoringConfigComponent } from './monitoring-config.component';
@NgModule({
@@ -28,10 +28,10 @@ import { SupervisionConfigComponent } from './supervision-config.component';
ThemeModule,
],
declarations: [
- SupervisionComponent,
- SupervisionConfigComponent,
+ MonitoringComponent,
+ MonitoringConfigComponent,
],
entryComponents: [
],
})
-export class SupervisionModule { }
+export class MonitoringModule { }
diff --git a/webapp/src/app/pages/pages-menu.ts b/webapp/src/app/pages/pages-menu.ts
index 230966d..771c798 100644
--- a/webapp/src/app/pages/pages-menu.ts
+++ b/webapp/src/app/pages/pages-menu.ts
@@ -86,17 +86,17 @@ export const MENU_ITEMS: NbMenuItem[] = [
],
},
{
- title: 'Supervision / Monitoring',
+ title: 'Monitoring',
icon: 'fa fa-bar-chart',
- link: '/pages/supervision',
+ link: '/pages/monitoring',
children: [
{
title: 'Config',
- link: '/pages/supervision/config',
+ link: '/pages/monitoring/config',
},
{
title: 'Graph',
- link: '/pages/supervision/graph',
+ link: '/pages/monitoring/graph',
},
],
},
diff --git a/webapp/src/app/pages/pages-routing.module.ts b/webapp/src/app/pages/pages-routing.module.ts
index ae2ef4a..c63d496 100644
--- a/webapp/src/app/pages/pages-routing.module.ts
+++ b/webapp/src/app/pages/pages-routing.module.ts
@@ -27,8 +27,8 @@ import { SdkManagementComponent } from './sdks/sdk-management/sdk-management.com
import { TargetsComponent } from './targets/targets.component';
import { TerminalsComponent } from './targets/terminals/terminals.component';
import { BuildComponent } from './build/build.component';
-import { SupervisionComponent } from './supervision/supervision.component';
-import { SupervisionConfigComponent } from './supervision/supervision-config.component';
+import { MonitoringComponent } from './monitoring/monitoring.component';
+import { MonitoringConfigComponent } from './monitoring/monitoring-config.component';
const routes: Routes = [{
path: '',
@@ -55,11 +55,11 @@ const routes: Routes = [{
path: 'targets/term',
component: TerminalsComponent,
}, {
- path: 'supervision/config',
- component: SupervisionConfigComponent,
+ path: 'monitoring/config',
+ component: MonitoringConfigComponent,
}, {
- path: 'supervision/graph',
- component: SupervisionComponent,
+ path: 'monitoring/graph',
+ component: MonitoringComponent,
}, {
path: 'config',
loadChildren: './config/config.module#ConfigModule',
diff --git a/webapp/src/app/pages/pages.module.ts b/webapp/src/app/pages/pages.module.ts
index 5ffa8d6..3481599 100644
--- a/webapp/src/app/pages/pages.module.ts
+++ b/webapp/src/app/pages/pages.module.ts
@@ -26,7 +26,7 @@ import { DashboardModule } from './dashboard/dashboard.module';
import { BuildModule } from './build/build.module';
import { ProjectsModule } from './projects/projects.module';
import { SdksModule } from './sdks/sdks.module';
-import { SupervisionModule } from './supervision/supervision.module';
+import { MonitoringModule } from './monitoring/monitoring.module';
import { TargetsModule } from './targets/targets.module';
import { PagesRoutingModule } from './pages-routing.module';
import { NotificationsComponent } from './notifications/notifications.component';
@@ -49,7 +49,7 @@ const PAGES_COMPONENTS = [
SdksModule,
ToasterModule,
TargetsModule,
- SupervisionModule,
+ MonitoringModule,
],
declarations: [
...PAGES_COMPONENTS,
diff --git a/webapp/src/app/pages/supervision/supervision-config.component.html b/webapp/src/app/pages/supervision/supervision-config.component.html
deleted file mode 100644
index 1fbcd70..0000000
--- a/webapp/src/app/pages/supervision/supervision-config.component.html
+++ /dev/null
@@ -1,45 +0,0 @@
-<div class="row">
- <h3 style="margin-top: auto; margin-bottom: auto">Configuration</h3>
-
- <div class="row">
- <div class="col-md-12">
- <nb-card-body>
- <div class="col-md-9">
- <nb-actions size="small">
- <nb-action>
- <button id="refresh-topo" (click)="getAGLTopo()">
- <i class="fa fa-refresh"></i>
- </button>
- </nb-action>
- </nb-actions>
- </div>
- </nb-card-body>
- </div>
- </div>
-</div>
-<div class="row">
- <div class="col-md-10">
- <svg id="graph" width="100%" height="500">
- </svg>
- </div>
- <div class="col-md-2">
- <div>
- <label>Daemons to monitor</label>
- </div>
- <nb-checkbox *ngFor="let wsCkx of daemonCheckboxes" [disabled]="wsCkx.disabled" [(ngModel)]="wsCkx.value">{{wsCkx.name}}
- </nb-checkbox>
- <div style="margin-top: 20px;">
- <div>
- <label>Monitoring actions:</label>
- </div>
- <button id="start-trace" class="btn btn-primary" (click)="onStartTrace()" [disabled]="
- isStartBtnDisable()">{{ starting ?"Starting... ":"Start" }}
- <span *ngIf="starting" class="fa fa-gear faa-spin animated fa-size-x2"></span>
- </button>
- <button id="stop-trace" class="btn btn-primary" (click)="onStopTrace()" [disabled]="
- isStopBtnDisable()">{{ stopping ?"Stopping... ":"Stop" }}
- <span *ngIf="stopping" class="fa fa-gear faa-spin animated fa-size-x2"></span>
- </button>
- </div>
- </div>
-</div>
diff --git a/webapp/tslint.json b/webapp/tslint.json
index 9bfdcb2..7a10b10 100644
--- a/webapp/tslint.json
+++ b/webapp/tslint.json
@@ -6,8 +6,12 @@
"trailing-comma": [
true,
{
- "multiline": "always",
- "singleline": "never"
+ "multiline": {
+ "objects": "ignore",
+ "arrays": "always",
+ "functions": "ignore",
+ "typeLiterals": "ignore"
+ }
}
],
"arrow-return-shorthand": true,
@@ -119,7 +123,10 @@
"component-selector": [
true,
"element",
- ["ngx", "xds"],
+ [
+ "ngx",
+ "xds"
+ ],
"kebab-case"
],
"use-input-property-decorator": true,