mirror of
https://github.com/openziti/zrok.git
synced 2026-09-24 07:35:05 -05:00
roughed in environment sparklines backend (#327)
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/openziti/zrok/rest_model_zrok"
|
||||
"github.com/openziti/zrok/rest_server_zrok/operations/metadata"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type accountDetailHandler struct{}
|
||||
|
||||
func newAccountDetailHandler() *accountDetailHandler {
|
||||
return &accountDetailHandler{}
|
||||
}
|
||||
|
||||
func (h *accountDetailHandler) Handle(params metadata.GetAccountDetailParams, principal *rest_model_zrok.Principal) middleware.Responder {
|
||||
trx, err := str.Begin()
|
||||
if err != nil {
|
||||
logrus.Errorf("error stasrting transaction for '%v': %v", principal.Email, err)
|
||||
return metadata.NewGetAccountDetailInternalServerError()
|
||||
}
|
||||
defer func() { _ = trx.Rollback() }()
|
||||
envs, err := str.FindEnvironmentsForAccount(int(principal.ID), trx)
|
||||
if err != nil {
|
||||
logrus.Errorf("error retrieving environments for '%v': %v", principal.Email, err)
|
||||
return metadata.NewGetAccountDetailInternalServerError()
|
||||
}
|
||||
sparkRx := make(map[int][]int64)
|
||||
sparkTx := make(map[int][]int64)
|
||||
if cfg.Metrics != nil && cfg.Metrics.Influx != nil {
|
||||
sparkRx, sparkTx, err = sparkDataForEnvironments(envs)
|
||||
if err != nil {
|
||||
logrus.Errorf("error querying spark data for environments for '%v': %v", principal.Email, err)
|
||||
}
|
||||
} else {
|
||||
logrus.Debug("skipping spark data for environments; no influx configuration")
|
||||
}
|
||||
var payload []*rest_model_zrok.Environment
|
||||
for _, env := range envs {
|
||||
var sparkData []*rest_model_zrok.SparkDataSample
|
||||
for i := 0; i < len(sparkRx[env.Id]) && i < len(sparkTx[env.Id]); i++ {
|
||||
sparkData = append(sparkData, &rest_model_zrok.SparkDataSample{Rx: float64(sparkRx[env.Id][i]), Tx: float64(sparkTx[env.Id][i])})
|
||||
}
|
||||
payload = append(payload, &rest_model_zrok.Environment{
|
||||
Activity: sparkData,
|
||||
Address: env.Address,
|
||||
CreatedAt: env.CreatedAt.UnixMilli(),
|
||||
Description: env.Description,
|
||||
Host: env.Host,
|
||||
UpdatedAt: env.UpdatedAt.UnixMilli(),
|
||||
ZID: env.ZId,
|
||||
})
|
||||
}
|
||||
return metadata.NewGetAccountDetailOK().WithPayload(payload)
|
||||
}
|
||||
@@ -46,6 +46,7 @@ func Run(inCfg *config.Config) error {
|
||||
api.AdminUpdateFrontendHandler = newUpdateFrontendHandler()
|
||||
api.EnvironmentEnableHandler = newEnableHandler()
|
||||
api.EnvironmentDisableHandler = newDisableHandler()
|
||||
api.MetadataGetAccountDetailHandler = newAccountDetailHandler()
|
||||
api.MetadataConfigurationHandler = newConfigurationHandler(cfg)
|
||||
if cfg.Metrics != nil && cfg.Metrics.Influx != nil {
|
||||
api.MetadataGetAccountMetricsHandler = newGetAccountMetricsHandler(cfg.Metrics.Influx)
|
||||
|
||||
+67
-20
@@ -6,13 +6,79 @@ import (
|
||||
"github.com/openziti/zrok/controller/store"
|
||||
)
|
||||
|
||||
func sparkDataForEnvironments(envs []*store.Environment) (rx, tx map[int][]int64, err error) {
|
||||
rx = make(map[int][]int64)
|
||||
tx = make(map[int][]int64)
|
||||
if len(envs) > 0 {
|
||||
qapi := idb.QueryAPI(cfg.Metrics.Influx.Org)
|
||||
|
||||
envFilter := "|> filter(fn: (r) =>"
|
||||
for i, env := range envs {
|
||||
if i > 0 {
|
||||
envFilter += " or"
|
||||
}
|
||||
envFilter += fmt.Sprintf(" r[\"envId\"] == \"%d\"", env.Id)
|
||||
}
|
||||
envFilter += ")"
|
||||
query := fmt.Sprintf("from(bucket: \"%v\")\n", cfg.Metrics.Influx.Bucket) +
|
||||
"|> range(start: -5m)\n" +
|
||||
"|> filter(fn: (r) => r[\"_measurement\"] == \"xfer\")\n" +
|
||||
"|> filter(fn: (r) => r[\"_field\"] == \"rx\" or r[\"_field\"] == \"tx\")\n" +
|
||||
"|> filter(fn: (r) => r[\"namespace\"] == \"backend\")\n" +
|
||||
envFilter +
|
||||
"|> aggregateWindow(every: 10s, fn: sum, createEmpty: true)\n"
|
||||
|
||||
result, err := qapi.Query(context.Background(), query)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
for result.Next() {
|
||||
envId := result.Record().ValueByKey("envId").(int64)
|
||||
switch result.Record().Field() {
|
||||
case "rx":
|
||||
rxV := int64(0)
|
||||
if v, ok := result.Record().Value().(int64); ok {
|
||||
rxV = v
|
||||
}
|
||||
rxData := append(rx[int(envId)], rxV)
|
||||
rx[int(envId)] = rxData
|
||||
|
||||
case "tx":
|
||||
txV := int64(0)
|
||||
if v, ok := result.Record().Value().(int64); ok {
|
||||
txV = v
|
||||
}
|
||||
txData := append(tx[int(envId)], txV)
|
||||
tx[int(envId)] = txData
|
||||
}
|
||||
}
|
||||
}
|
||||
return rx, tx, nil
|
||||
}
|
||||
|
||||
func sparkDataForShares(shrs []*store.Share) (rx, tx map[string][]int64, err error) {
|
||||
rx = make(map[string][]int64)
|
||||
tx = make(map[string][]int64)
|
||||
if len(shrs) > 0 {
|
||||
qapi := idb.QueryAPI(cfg.Metrics.Influx.Org)
|
||||
|
||||
query := sparkFluxQuery(shrs, cfg.Metrics.Influx.Bucket)
|
||||
shrFilter := "|> filter(fn: (r) =>"
|
||||
for i, shr := range shrs {
|
||||
if i > 0 {
|
||||
shrFilter += " or"
|
||||
}
|
||||
shrFilter += fmt.Sprintf(" r[\"share\"] == \"%v\"", shr.Token)
|
||||
}
|
||||
shrFilter += ")"
|
||||
query := fmt.Sprintf("from(bucket: \"%v\")\n", cfg.Metrics.Influx.Bucket) +
|
||||
"|> range(start: -5m)\n" +
|
||||
"|> filter(fn: (r) => r[\"_measurement\"] == \"xfer\")\n" +
|
||||
"|> filter(fn: (r) => r[\"_field\"] == \"rx\" or r[\"_field\"] == \"tx\")\n" +
|
||||
"|> filter(fn: (r) => r[\"namespace\"] == \"backend\")\n" +
|
||||
shrFilter +
|
||||
"|> aggregateWindow(every: 10s, fn: sum, createEmpty: true)\n"
|
||||
|
||||
result, err := qapi.Query(context.Background(), query)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -41,22 +107,3 @@ func sparkDataForShares(shrs []*store.Share) (rx, tx map[string][]int64, err err
|
||||
}
|
||||
return rx, tx, nil
|
||||
}
|
||||
|
||||
func sparkFluxQuery(shrs []*store.Share, bucket string) string {
|
||||
shrFilter := "|> filter(fn: (r) =>"
|
||||
for i, shr := range shrs {
|
||||
if i > 0 {
|
||||
shrFilter += " or"
|
||||
}
|
||||
shrFilter += fmt.Sprintf(" r[\"share\"] == \"%v\"", shr.Token)
|
||||
}
|
||||
shrFilter += ")"
|
||||
query := fmt.Sprintf("from(bucket: \"%v\")\n", bucket) +
|
||||
"|> range(start: -5m)\n" +
|
||||
"|> filter(fn: (r) => r[\"_measurement\"] == \"xfer\")\n" +
|
||||
"|> filter(fn: (r) => r[\"_field\"] == \"rx\" or r[\"_field\"] == \"tx\")\n" +
|
||||
"|> filter(fn: (r) => r[\"namespace\"] == \"backend\")" +
|
||||
shrFilter +
|
||||
"|> aggregateWindow(every: 10s, fn: sum, createEmpty: true)\n"
|
||||
return query
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user