diff --git a/client/src/api/metrics.jsx b/client/src/api/metrics.jsx index 7219be7..1b34d4f 100644 --- a/client/src/api/metrics.jsx +++ b/client/src/api/metrics.jsx @@ -9,6 +9,16 @@ function get() { })) } +function reset() { + return wrap(fetch('/cosmos/api/reset-metrics', { + method: 'GET', + headers: { + 'Content-Type': 'application/json' + }, + })) +} + export { get, + reset, }; \ No newline at end of file diff --git a/client/src/components/confirmModal.jsx b/client/src/components/confirmModal.jsx index 81bf673..f76c1b5 100644 --- a/client/src/components/confirmModal.jsx +++ b/client/src/components/confirmModal.jsx @@ -9,7 +9,7 @@ import DialogTitle from '@mui/material/DialogTitle'; import * as React from 'react'; import { useEffect, useState } from 'react'; -const ConfirmModal = ({ callback, label, content }) => { +const ConfirmModal = ({ callback, label, content, startIcon }) => { const [openModal, setOpenModal] = useState(false); return <> @@ -36,6 +36,7 @@ const ConfirmModal = ({ callback, label, content }) => { disableElevation variant="outlined" color="warning" + startIcon={startIcon} onClick={() => { setOpenModal(true); }} diff --git a/client/src/pages/config/users/configman.jsx b/client/src/pages/config/users/configman.jsx index 670207a..4b9db37 100644 --- a/client/src/pages/config/users/configman.jsx +++ b/client/src/pages/config/users/configman.jsx @@ -19,7 +19,7 @@ import { Skeleton, } from '@mui/material'; import RestartModal from './restart'; -import { SyncOutlined } from '@ant-design/icons'; +import { DeleteOutlined, SyncOutlined } from '@ant-design/icons'; import { CosmosCheckbox, CosmosFormDivider, CosmosInputPassword, CosmosInputText, CosmosSelect } from './formShortcuts'; import CountrySelect from '../../../components/countrySelect'; import { DnsChallengeComp } from '../../../utils/dns-challenge-comp'; @@ -32,6 +32,7 @@ import { TwitterPicker // TODO: Remove circular deps import {SetPrimaryColor, SetSecondaryColor} from '../../../App'; import { useClientInfos } from '../../../utils/hooks'; +import ConfirmModal from '../../../components/confirmModal'; const ConfigManagement = () => { const [config, setConfig] = React.useState(null); @@ -68,12 +69,21 @@ const ConfigManagement = () => { {isAdmin && } + + } callback={() => { + API.metrics.reset().then((res) => { + refresh(); + }); + }} + label={'Purge Metrics Dashboard'} + content={'Are you sure you want to purge all the metrics data from the dashboards?'} /> {config && <> + { const refreshMetrics = () => { API.metrics.get().then((res) => { let finalMetrics = {}; - res.data.forEach((metric) => { - finalMetrics[metric.Key] = metric; - }); - setMetrics(finalMetrics); + if(res.data) { + res.data.forEach((metric) => { + finalMetrics[metric.Key] = metric; + }); + setMetrics(finalMetrics); + } setTimeout(refreshMetrics, 10000); }); }; @@ -149,6 +152,19 @@ const DashboardDefault = () => { {/* */} + {!metrics && + + } {metrics &&
diff --git a/package.json b/package.json index 7e7353e..69a95aa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cosmos-server", - "version": "0.12.0-unstable18", + "version": "0.12.0-unstable19", "description": "", "main": "test-server.js", "bugs": { diff --git a/src/httpServer.go b/src/httpServer.go index 3654c1f..623ee29 100644 --- a/src/httpServer.go +++ b/src/httpServer.go @@ -341,6 +341,7 @@ func InitServer() *mux.Router { srapi.HandleFunc("/api/constellation/block", constellation.DeviceBlock) srapi.HandleFunc("/api/metrics", metrics.API_GetMetrics) + srapi.HandleFunc("/api/reset-metrics", metrics.API_ResetMetrics) if(!config.HTTPConfig.AcceptAllInsecureHostname) { srapi.Use(utils.EnsureHostname) diff --git a/src/metrics/aggl.go b/src/metrics/aggl.go index 60311d6..2ba9b63 100644 --- a/src/metrics/aggl.go +++ b/src/metrics/aggl.go @@ -158,8 +158,11 @@ func AggloMetrics() []DataDefDB { } func CommitAggl(metrics []DataDefDB) { - utils.Log("Metrics: Agglomeration done. Saving to DB") + lock <- true + defer func() { <-lock }() + utils.Log("Metrics: Agglomeration done. Saving to DB") + c, errCo := utils.GetCollection(utils.GetRootAppId(), "metrics") if errCo != nil { utils.Error("Metrics - Database Connect", errCo) diff --git a/src/metrics/api.go b/src/metrics/api.go index 7a3f6fc..1ee0fd7 100644 --- a/src/metrics/api.go +++ b/src/metrics/api.go @@ -17,6 +17,37 @@ func API_GetMetrics(w http.ResponseWriter, req *http.Request) { "status": "OK", "data": AggloMetrics(), }) + } else { + utils.Error("MetricsGet: Method not allowed" + req.Method, nil) + utils.HTTPError(w, "Method not allowed", http.StatusMethodNotAllowed, "HTTP001") + return + } +} + +func API_ResetMetrics(w http.ResponseWriter, req *http.Request) { + if utils.AdminOnly(w, req) != nil { + return + } + + c, errCo := utils.GetCollection(utils.GetRootAppId(), "metrics") + if errCo != nil { + utils.Error("MetricsReset: Database error" , errCo) + utils.HTTPError(w, "Database error ", http.StatusMethodNotAllowed, "HTTP001") + return + } + + // delete all metrics from database + _, err := c.DeleteMany(nil, map[string]interface{}{}) + if err != nil { + utils.Error("MetricsReset: Database error ", err) + utils.HTTPError(w, "Database error ", http.StatusMethodNotAllowed, "HTTP001") + return + } + + if(req.Method == "GET") { + json.NewEncoder(w).Encode(map[string]interface{}{ + "status": "OK", + }) } else { utils.Error("SettingGet: Method not allowed" + req.Method, nil) utils.HTTPError(w, "Method not allowed", http.StatusMethodNotAllowed, "HTTP001") diff --git a/src/metrics/index.go b/src/metrics/index.go index 74d49ae..04f0a0b 100644 --- a/src/metrics/index.go +++ b/src/metrics/index.go @@ -185,6 +185,7 @@ func Run() { func Init() { InitAggl() - //GetSystemMetrics() Run() + + go GetSystemMetrics() } \ No newline at end of file