mirror of
https://github.com/openziti/zrok.git
synced 2024-11-25 17:43:53 +01:00
tweaks to get environment sparklines running (#327)
This commit is contained in:
parent
2655eaefc0
commit
8bf2173c49
@ -4,6 +4,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/openziti/zrok/controller/store"
|
"github.com/openziti/zrok/controller/store"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
func sparkDataForEnvironments(envs []*store.Environment) (rx, tx map[int][]int64, err error) {
|
func sparkDataForEnvironments(envs []*store.Environment) (rx, tx map[int][]int64, err error) {
|
||||||
@ -26,6 +28,7 @@ func sparkDataForEnvironments(envs []*store.Environment) (rx, tx map[int][]int64
|
|||||||
"|> filter(fn: (r) => r[\"_field\"] == \"rx\" or r[\"_field\"] == \"tx\")\n" +
|
"|> filter(fn: (r) => r[\"_field\"] == \"rx\" or r[\"_field\"] == \"tx\")\n" +
|
||||||
"|> filter(fn: (r) => r[\"namespace\"] == \"backend\")\n" +
|
"|> filter(fn: (r) => r[\"namespace\"] == \"backend\")\n" +
|
||||||
envFilter +
|
envFilter +
|
||||||
|
"|> drop(columns: [\"share\", \"acctId\"])\n" +
|
||||||
"|> aggregateWindow(every: 10s, fn: sum, createEmpty: true)\n"
|
"|> aggregateWindow(every: 10s, fn: sum, createEmpty: true)\n"
|
||||||
|
|
||||||
result, err := qapi.Query(context.Background(), query)
|
result, err := qapi.Query(context.Background(), query)
|
||||||
@ -34,7 +37,12 @@ func sparkDataForEnvironments(envs []*store.Environment) (rx, tx map[int][]int64
|
|||||||
}
|
}
|
||||||
|
|
||||||
for result.Next() {
|
for result.Next() {
|
||||||
envId := result.Record().ValueByKey("envId").(int64)
|
envIdS := result.Record().ValueByKey("envId").(string)
|
||||||
|
envId, err := strconv.ParseInt(envIdS, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("error parsing '%v': %v", envIdS, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
switch result.Record().Field() {
|
switch result.Record().Field() {
|
||||||
case "rx":
|
case "rx":
|
||||||
rxV := int64(0)
|
rxV := int64(0)
|
||||||
|
4
go.mod
4
go.mod
@ -1,6 +1,6 @@
|
|||||||
module github.com/openziti/zrok
|
module github.com/openziti/zrok
|
||||||
|
|
||||||
go 1.19
|
go 1.20
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/charmbracelet/bubbles v0.14.0
|
github.com/charmbracelet/bubbles v0.14.0
|
||||||
@ -31,6 +31,7 @@ require (
|
|||||||
github.com/openziti/fabric v0.22.59
|
github.com/openziti/fabric v0.22.59
|
||||||
github.com/openziti/identity v1.0.37
|
github.com/openziti/identity v1.0.37
|
||||||
github.com/openziti/sdk-golang v0.18.61
|
github.com/openziti/sdk-golang v0.18.61
|
||||||
|
github.com/openziti/transport/v2 v2.0.63
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/rabbitmq/amqp091-go v1.7.0
|
github.com/rabbitmq/amqp091-go v1.7.0
|
||||||
github.com/rubenv/sql-migrate v1.1.2
|
github.com/rubenv/sql-migrate v1.1.2
|
||||||
@ -91,7 +92,6 @@ require (
|
|||||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||||
github.com/openziti/foundation/v2 v2.0.17 // indirect
|
github.com/openziti/foundation/v2 v2.0.17 // indirect
|
||||||
github.com/openziti/metrics v1.2.10 // indirect
|
github.com/openziti/metrics v1.2.10 // indirect
|
||||||
github.com/openziti/transport/v2 v2.0.63 // indirect
|
|
||||||
github.com/orcaman/concurrent-map/v2 v2.0.1 // indirect
|
github.com/orcaman/concurrent-map/v2 v2.0.1 // indirect
|
||||||
github.com/parallaxsecond/parsec-client-go v0.0.0-20221025095442-f0a77d263cf9 // indirect
|
github.com/parallaxsecond/parsec-client-go v0.0.0-20221025095442-f0a77d263cf9 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
@ -5,6 +5,7 @@ import {Tab, Tabs} from "react-bootstrap";
|
|||||||
import SecretToggle from "../../SecretToggle";
|
import SecretToggle from "../../SecretToggle";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import MetricsTab from "./MetricsTab";
|
import MetricsTab from "./MetricsTab";
|
||||||
|
import EnvironmentsTab from "./EnvironmentsTab";
|
||||||
|
|
||||||
const AccountDetail = (props) => {
|
const AccountDetail = (props) => {
|
||||||
const customProperties = {
|
const customProperties = {
|
||||||
@ -14,7 +15,10 @@ const AccountDetail = (props) => {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h2><Icon path={mdiAccountBox} size={2} />{" "}{props.user.email}</h2>
|
<h2><Icon path={mdiAccountBox} size={2} />{" "}{props.user.email}</h2>
|
||||||
<Tabs defaultActiveKey={"detail"}>
|
<Tabs defaultActiveKey={"environments"}>
|
||||||
|
<Tab eventKey={"environments"} title={"Environments"}>
|
||||||
|
<EnvironmentsTab />
|
||||||
|
</Tab>
|
||||||
<Tab eventKey={"detail"} title={"Detail"}>
|
<Tab eventKey={"detail"} title={"Detail"}>
|
||||||
<PropertyTable object={props.user} custom={customProperties}/>
|
<PropertyTable object={props.user} custom={customProperties}/>
|
||||||
</Tab>
|
</Tab>
|
||||||
|
71
ui/src/console/detail/account/EnvironmentsTab.js
Normal file
71
ui/src/console/detail/account/EnvironmentsTab.js
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import React, {useEffect, useState} from "react";
|
||||||
|
import * as metadata from "../../../api/metadata";
|
||||||
|
import {Area, AreaChart, ResponsiveContainer} from "recharts";
|
||||||
|
import DataTable from "react-data-table-component";
|
||||||
|
|
||||||
|
const EnvironmentsTab = (props) => {
|
||||||
|
const [detail, setDetail] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
metadata.getAccountDetail()
|
||||||
|
.then(resp => {
|
||||||
|
setDetail(resp.data);
|
||||||
|
});
|
||||||
|
}, [props.selection]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let mounted = true;
|
||||||
|
let interval = setInterval(() => {
|
||||||
|
metadata.getAccountDetail()
|
||||||
|
.then(resp => {
|
||||||
|
if(mounted) {
|
||||||
|
setDetail(resp.data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 5000);
|
||||||
|
return () => {
|
||||||
|
mounted = false;
|
||||||
|
clearInterval(interval);
|
||||||
|
}
|
||||||
|
}, [props.selection]);
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
name: "Description",
|
||||||
|
selector: row => row.description,
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Address",
|
||||||
|
grow: 0.5,
|
||||||
|
selector: row => row.address,
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Activity",
|
||||||
|
grow: 0.5,
|
||||||
|
cell: row => {
|
||||||
|
return <ResponsiveContainer width={"100%"} height={"100%"}>
|
||||||
|
<AreaChart data={row.activity}>
|
||||||
|
<Area type={"basis"} dataKey={(v) => v.rx ? v.rx : 0} stroke={"#231069"} fill={"#04adef"} isAnimationActive={false} dot={false} />
|
||||||
|
<Area type={"basis"} dataKey={(v) => v.tx ? v.tx * -1 : 0} stroke={"#231069"} fill={"#9BF316"} isAnimationActive={false} dot={false} />
|
||||||
|
</AreaChart>
|
||||||
|
</ResponsiveContainer>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={"zrok-datatable"}>
|
||||||
|
<DataTable
|
||||||
|
className={"zrok-datatable"}
|
||||||
|
data={detail}
|
||||||
|
columns={columns}
|
||||||
|
defaultSortField={1}
|
||||||
|
noDataComponent={<p>No environments in account</p>}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EnvironmentsTab;
|
@ -22,7 +22,7 @@ const SharesTab = (props) => {
|
|||||||
setDetail(resp.data);
|
setDetail(resp.data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, 1000);
|
}, 5000);
|
||||||
return () => {
|
return () => {
|
||||||
mounted = false;
|
mounted = false;
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
export const buildMetrics = (m) => {
|
export const buildMetrics = (m) => {
|
||||||
console.log("build", m);
|
|
||||||
let metrics = {
|
let metrics = {
|
||||||
data: m.samples,
|
data: m.samples,
|
||||||
rx: 0,
|
rx: 0,
|
||||||
|
Loading…
Reference in New Issue
Block a user