tweaks to get environment sparklines running (#327)

This commit is contained in:
Michael Quigley 2023-05-12 13:24:29 -04:00
parent 2655eaefc0
commit 8bf2173c49
No known key found for this signature in database
GPG Key ID: 9B60314A9DD20A62
6 changed files with 88 additions and 6 deletions

View File

@ -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
View File

@ -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

View File

@ -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>

View 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;

View File

@ -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);

View File

@ -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,