mirror of
https://github.com/openziti/zrok.git
synced 2025-01-09 07:28:15 +01:00
parent
7d611fda30
commit
b5b3385b46
@ -34,12 +34,12 @@ func (h *getAccountMetricsHandler) Handle(params metadata.GetAccountMetricsParam
|
|||||||
if params.Duration != nil {
|
if params.Duration != nil {
|
||||||
v, err := time.ParseDuration(*params.Duration)
|
v, err := time.ParseDuration(*params.Duration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("bad duration '%v' for '%v': %v", params.Duration, principal.Email, err)
|
logrus.Errorf("bad duration '%v' for '%v': %v", *params.Duration, principal.Email, err)
|
||||||
return metadata.NewGetAccountMetricsBadRequest()
|
return metadata.NewGetAccountMetricsBadRequest()
|
||||||
}
|
}
|
||||||
duration = v
|
duration = v
|
||||||
}
|
}
|
||||||
slice := duration / 50
|
slice := duration / 30
|
||||||
|
|
||||||
query := fmt.Sprintf("from(bucket: \"%v\")\n", h.cfg.Bucket) +
|
query := fmt.Sprintf("from(bucket: \"%v\")\n", h.cfg.Bucket) +
|
||||||
fmt.Sprintf("|> range(start: -%v)\n", duration) +
|
fmt.Sprintf("|> range(start: -%v)\n", duration) +
|
||||||
@ -108,12 +108,12 @@ func (h *getEnvironmentMetricsHandler) Handle(params metadata.GetEnvironmentMetr
|
|||||||
if params.Duration != nil {
|
if params.Duration != nil {
|
||||||
v, err := time.ParseDuration(*params.Duration)
|
v, err := time.ParseDuration(*params.Duration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("bad duration '%v' for '%v': %v", params.Duration, principal.Email, err)
|
logrus.Errorf("bad duration '%v' for '%v': %v", *params.Duration, principal.Email, err)
|
||||||
return metadata.NewGetAccountMetricsBadRequest()
|
return metadata.NewGetAccountMetricsBadRequest()
|
||||||
}
|
}
|
||||||
duration = v
|
duration = v
|
||||||
}
|
}
|
||||||
slice := duration / 50
|
slice := duration / 30
|
||||||
|
|
||||||
query := fmt.Sprintf("from(bucket: \"%v\")\n", h.cfg.Bucket) +
|
query := fmt.Sprintf("from(bucket: \"%v\")\n", h.cfg.Bucket) +
|
||||||
fmt.Sprintf("|> range(start: -%v)\n", duration) +
|
fmt.Sprintf("|> range(start: -%v)\n", duration) +
|
||||||
@ -188,12 +188,12 @@ func (h *getShareMetricsHandler) Handle(params metadata.GetShareMetricsParams, p
|
|||||||
if params.Duration != nil {
|
if params.Duration != nil {
|
||||||
v, err := time.ParseDuration(*params.Duration)
|
v, err := time.ParseDuration(*params.Duration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("bad duration '%v' for '%v': %v", params.Duration, principal.Email, err)
|
logrus.Errorf("bad duration '%v' for '%v': %v", *params.Duration, principal.Email, err)
|
||||||
return metadata.NewGetAccountMetricsBadRequest()
|
return metadata.NewGetAccountMetricsBadRequest()
|
||||||
}
|
}
|
||||||
duration = v
|
duration = v
|
||||||
}
|
}
|
||||||
slice := duration / 50
|
slice := duration / 30
|
||||||
|
|
||||||
query := fmt.Sprintf("from(bucket: \"%v\")\n", h.cfg.Bucket) +
|
query := fmt.Sprintf("from(bucket: \"%v\")\n", h.cfg.Bucket) +
|
||||||
fmt.Sprintf("|> range(start: -%v)\n", duration) +
|
fmt.Sprintf("|> range(start: -%v)\n", duration) +
|
||||||
|
28
ui/package-lock.json
generated
28
ui/package-lock.json
generated
@ -17,6 +17,7 @@
|
|||||||
"dagre": "^0.8.5",
|
"dagre": "^0.8.5",
|
||||||
"eslint-config-react-app": "^7.0.1",
|
"eslint-config-react-app": "^7.0.1",
|
||||||
"humanize-duration": "^3.27.3",
|
"humanize-duration": "^3.27.3",
|
||||||
|
"moment": "^2.29.4",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-bootstrap": "^2.7.0",
|
"react-bootstrap": "^2.7.0",
|
||||||
"react-data-table-component": "^7.5.2",
|
"react-data-table-component": "^7.5.2",
|
||||||
@ -24,7 +25,7 @@
|
|||||||
"react-force-graph": "^1.43.0",
|
"react-force-graph": "^1.43.0",
|
||||||
"react-router-dom": "^6.4.0",
|
"react-router-dom": "^6.4.0",
|
||||||
"react-sizeme": "^3.0.2",
|
"react-sizeme": "^3.0.2",
|
||||||
"recharts": "^2.5.0",
|
"recharts": "^2.6.1",
|
||||||
"styled-components": "^5.3.5",
|
"styled-components": "^5.3.5",
|
||||||
"svgo": "^3.0.2"
|
"svgo": "^3.0.2"
|
||||||
},
|
},
|
||||||
@ -13651,6 +13652,14 @@
|
|||||||
"mkdirp": "bin/cmd.js"
|
"mkdirp": "bin/cmd.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/moment": {
|
||||||
|
"version": "2.29.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
|
||||||
|
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ms": {
|
"node_modules/ms": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
@ -16545,9 +16554,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/recharts": {
|
"node_modules/recharts": {
|
||||||
"version": "2.5.0",
|
"version": "2.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/recharts/-/recharts-2.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/recharts/-/recharts-2.6.1.tgz",
|
||||||
"integrity": "sha512-0EQYz3iA18r1Uq8VqGZ4dABW52AKBnio37kJgnztIqprELJXpOEsa0SzkqU1vjAhpCXCv52Dx1hiL9119xsqsQ==",
|
"integrity": "sha512-eGNNqQTSg737HB0tfFkPZbPW8ji7Q8joQM0P2yAEkJkB8CO+LJPgLpx/NUxNHJsxoXvSblMFoy5RSVBYfLU+HA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"classnames": "^2.2.5",
|
"classnames": "^2.2.5",
|
||||||
"eventemitter3": "^4.0.1",
|
"eventemitter3": "^4.0.1",
|
||||||
@ -29808,6 +29817,11 @@
|
|||||||
"minimist": "^1.2.6"
|
"minimist": "^1.2.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"moment": {
|
||||||
|
"version": "2.29.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
|
||||||
|
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
|
||||||
|
},
|
||||||
"ms": {
|
"ms": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
@ -31796,9 +31810,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"recharts": {
|
"recharts": {
|
||||||
"version": "2.5.0",
|
"version": "2.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/recharts/-/recharts-2.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/recharts/-/recharts-2.6.1.tgz",
|
||||||
"integrity": "sha512-0EQYz3iA18r1Uq8VqGZ4dABW52AKBnio37kJgnztIqprELJXpOEsa0SzkqU1vjAhpCXCv52Dx1hiL9119xsqsQ==",
|
"integrity": "sha512-eGNNqQTSg737HB0tfFkPZbPW8ji7Q8joQM0P2yAEkJkB8CO+LJPgLpx/NUxNHJsxoXvSblMFoy5RSVBYfLU+HA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"classnames": "^2.2.5",
|
"classnames": "^2.2.5",
|
||||||
"eventemitter3": "^4.0.1",
|
"eventemitter3": "^4.0.1",
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
"dagre": "^0.8.5",
|
"dagre": "^0.8.5",
|
||||||
"eslint-config-react-app": "^7.0.1",
|
"eslint-config-react-app": "^7.0.1",
|
||||||
"humanize-duration": "^3.27.3",
|
"humanize-duration": "^3.27.3",
|
||||||
|
"moment": "^2.29.4",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-bootstrap": "^2.7.0",
|
"react-bootstrap": "^2.7.0",
|
||||||
"react-data-table-component": "^7.5.2",
|
"react-data-table-component": "^7.5.2",
|
||||||
@ -19,7 +20,7 @@
|
|||||||
"react-force-graph": "^1.43.0",
|
"react-force-graph": "^1.43.0",
|
||||||
"react-router-dom": "^6.4.0",
|
"react-router-dom": "^6.4.0",
|
||||||
"react-sizeme": "^3.0.2",
|
"react-sizeme": "^3.0.2",
|
||||||
"recharts": "^2.5.0",
|
"recharts": "^2.6.1",
|
||||||
"styled-components": "^5.3.5",
|
"styled-components": "^5.3.5",
|
||||||
"svgo": "^3.0.2"
|
"svgo": "^3.0.2"
|
||||||
},
|
},
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import {mdiAccountBox} from "@mdi/js";
|
import {mdiAccountBox} from "@mdi/js";
|
||||||
import Icon from "@mdi/react";
|
import Icon from "@mdi/react";
|
||||||
import PropertyTable from "../../PropertyTable";
|
import PropertyTable from "../../PropertyTable";
|
||||||
import {Tab, Tabs, Tooltip} from "react-bootstrap";
|
import {Col, Container, Row, Tab, Tabs, Tooltip} from "react-bootstrap";
|
||||||
import SecretToggle from "../../SecretToggle";
|
import SecretToggle from "../../SecretToggle";
|
||||||
import React, {useEffect, useState} from "react";
|
import React, {useEffect, useState} from "react";
|
||||||
import * as metadata from "../../../api/metadata";
|
import * as metadata from "../../../api/metadata";
|
||||||
import {Area, AreaChart, CartesianGrid, Line, LineChart, ResponsiveContainer, XAxis, YAxis} from "recharts";
|
import { Bar, BarChart, CartesianGrid, ResponsiveContainer, XAxis, YAxis } from "recharts";
|
||||||
|
import moment from "moment";
|
||||||
|
|
||||||
const AccountDetail = (props) => {
|
const AccountDetail = (props) => {
|
||||||
const customProperties = {
|
const customProperties = {
|
||||||
@ -28,14 +29,22 @@ const AccountDetail = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const MetricsTab = (props) => {
|
const MetricsTab = (props) => {
|
||||||
const [metrics, setMetrics] = useState({});
|
const [metrics30, setMetrics30] = useState(buildMetrics([]));
|
||||||
const [tx, setTx] = useState(0);
|
const [metrics7, setMetrics7] = useState(buildMetrics([]));
|
||||||
const [rx, setRx] = useState(0)
|
const [metrics1, setMetrics1] = useState(buildMetrics([]));
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
metadata.getAccountMetrics()
|
metadata.getAccountMetrics()
|
||||||
.then(resp => {
|
.then(resp => {
|
||||||
setMetrics(resp.data);
|
setMetrics30(buildMetrics(resp.data));
|
||||||
|
});
|
||||||
|
metadata.getAccountMetrics({duration: "168h"})
|
||||||
|
.then(resp => {
|
||||||
|
setMetrics7(buildMetrics(resp.data));
|
||||||
|
});
|
||||||
|
metadata.getAccountMetrics({duration: "24h"})
|
||||||
|
.then(resp => {
|
||||||
|
setMetrics1(buildMetrics(resp.data));
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@ -45,50 +54,114 @@ const MetricsTab = (props) => {
|
|||||||
metadata.getAccountMetrics()
|
metadata.getAccountMetrics()
|
||||||
.then(resp => {
|
.then(resp => {
|
||||||
if(mounted) {
|
if(mounted) {
|
||||||
setMetrics(resp.data);
|
setMetrics30(buildMetrics(resp.data));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, 1000);
|
metadata.getAccountMetrics({duration: "168h"})
|
||||||
|
.then(resp => {
|
||||||
|
setMetrics7(buildMetrics(resp.data));
|
||||||
|
});
|
||||||
|
metadata.getAccountMetrics({duration: "24h"})
|
||||||
|
.then(resp => {
|
||||||
|
setMetrics1(buildMetrics(resp.data));
|
||||||
|
});
|
||||||
|
}, 5000);
|
||||||
return () => {
|
return () => {
|
||||||
mounted = false;
|
mounted = false;
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
let txAccum = 0
|
|
||||||
let rxAccum = 0
|
|
||||||
if(metrics.samples) {
|
|
||||||
metrics.samples.forEach(sample => {
|
|
||||||
txAccum += sample.tx
|
|
||||||
rxAccum += sample.rx
|
|
||||||
})
|
|
||||||
}
|
|
||||||
setTx(txAccum);
|
|
||||||
setRx(rxAccum);
|
|
||||||
}, [metrics])
|
|
||||||
|
|
||||||
console.log(metrics);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<Container>
|
||||||
<div>
|
<Row>
|
||||||
<h1>RX: {bytesToSize(rx)}, TX: {bytesToSize(tx)}</h1>
|
<Col>
|
||||||
</div>
|
<h3>Last 30 Days:</h3>
|
||||||
<ResponsiveContainer width={"100%"} height={300}>
|
</Col>
|
||||||
<LineChart data={metrics.samples}>
|
</Row>
|
||||||
<CartesianGrid strokeDasharay={"3 3"} />
|
<Row>
|
||||||
<XAxis dataKey={(v) => new Date(v.timestamp)} />
|
<Col><p>Received: {bytesToSize(metrics30.rx)}</p></Col>
|
||||||
<YAxis />
|
<Col><p>Sent: {bytesToSize(metrics30.tx)}</p></Col>
|
||||||
<Line type={"linear"} stroke={"red"} dataKey={"rx"} activeDot={{ r: 8 }}/>
|
</Row>
|
||||||
<Line type={"linear"} stroke={"green"} dataKey={"tx"} />
|
<Row>
|
||||||
<Tooltip />
|
<Col>
|
||||||
</LineChart>
|
<ResponsiveContainer width={"100%"} height={150}>
|
||||||
</ResponsiveContainer>
|
<BarChart data={metrics30.data}>
|
||||||
</div>
|
<CartesianGrid strokeDasharay={"3 3"} />
|
||||||
|
<XAxis dataKey={(v) => v.timestamp} scale={"time"} tickFormatter={(v) => moment(v).format("MMM DD") } style={{ fontSize: '75%'}}/>
|
||||||
|
<YAxis tickFormatter={(v) => bytesToSize(v)} style={{ fontSize: '75%' }}/>
|
||||||
|
<Bar stroke={"#231069"} fill={"#04adef"} dataKey={"rx"} legendType={"circle"}/>
|
||||||
|
<Bar stroke={"#231069"} fill={"#9BF316"} dataKey={"tx"} />
|
||||||
|
<Tooltip />
|
||||||
|
</BarChart>
|
||||||
|
</ResponsiveContainer>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col>
|
||||||
|
<h3>Last 7 Days:</h3>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col><p>Received: {bytesToSize(metrics7.rx)}</p></Col>
|
||||||
|
<Col><p>Sent: {bytesToSize(metrics7.tx)}</p></Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col>
|
||||||
|
<ResponsiveContainer width={"100%"} height={150}>
|
||||||
|
<BarChart data={metrics7.data}>
|
||||||
|
<CartesianGrid strokeDasharay={"3 3"} />
|
||||||
|
<XAxis dataKey={(v) => v.timestamp} scale={"time"} tickFormatter={(v) => moment(v).format("MMM DD") } style={{ fontSize: '75%'}}/>
|
||||||
|
<YAxis tickFormatter={(v) => bytesToSize(v)} style={{ fontSize: '75%' }}/>
|
||||||
|
<Bar stroke={"#231069"} fill={"#04adef"} dataKey={"rx"} legendType={"circle"}/>
|
||||||
|
<Bar stroke={"#231069"} fill={"#9BF316"} dataKey={"tx"} />
|
||||||
|
<Tooltip />
|
||||||
|
</BarChart>
|
||||||
|
</ResponsiveContainer>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col>
|
||||||
|
<h3>Last 24 Hours:</h3>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col><p>Received: {bytesToSize(metrics1.rx)}</p></Col>
|
||||||
|
<Col><p>Sent: {bytesToSize(metrics1.tx)}</p></Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col>
|
||||||
|
<ResponsiveContainer width={"100%"} height={150}>
|
||||||
|
<BarChart data={metrics1.data}>
|
||||||
|
<CartesianGrid strokeDasharay={"3 3"} />
|
||||||
|
<XAxis dataKey={(v) => v.timestamp} scale={"time"} tickFormatter={(v) => moment(v).format("MMM DD") } style={{ fontSize: '75%'}}/>
|
||||||
|
<YAxis tickFormatter={(v) => bytesToSize(v)} style={{ fontSize: '75%' }}/>
|
||||||
|
<Bar stroke={"#231069"} fill={"#04adef"} dataKey={"rx"} legendType={"circle"}/>
|
||||||
|
<Bar stroke={"#231069"} fill={"#9BF316"} dataKey={"tx"} />
|
||||||
|
<Tooltip />
|
||||||
|
</BarChart>
|
||||||
|
</ResponsiveContainer>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const buildMetrics = (m) => {
|
||||||
|
let metrics = {
|
||||||
|
data: m.samples,
|
||||||
|
rx: 0,
|
||||||
|
tx: 0
|
||||||
|
}
|
||||||
|
if(m.samples) {
|
||||||
|
m.samples.forEach(s => {
|
||||||
|
metrics.rx += s.rx;
|
||||||
|
metrics.tx += s.tx;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return metrics;
|
||||||
|
}
|
||||||
|
|
||||||
const bytesToSize = (sz) => {
|
const bytesToSize = (sz) => {
|
||||||
let absSz = sz;
|
let absSz = sz;
|
||||||
if(absSz < 0) {
|
if(absSz < 0) {
|
||||||
@ -105,7 +178,7 @@ const bytesToSize = (sz) => {
|
|||||||
exp++;
|
exp++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return '' + (sz / div).toFixed(2) + "kMGTPE"[exp];
|
return '' + (sz / div).toFixed(1) + ' ' + "kMGTPE"[exp] + 'B';
|
||||||
}
|
}
|
||||||
|
|
||||||
export default AccountDetail;
|
export default AccountDetail;
|
Loading…
Reference in New Issue
Block a user