Merge traffic stats endpoints to one and add auto interval logic (#1174)

This commit is contained in:
gadotroee 2022-07-04 10:01:49 +03:00 committed by GitHub
parent 57078517a4
commit d6944d467c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 138 additions and 130 deletions

View File

@ -9,6 +9,7 @@ import (
"github.com/op/go-logging" "github.com/op/go-logging"
basenine "github.com/up9inc/basenine/client/go" basenine "github.com/up9inc/basenine/client/go"
"github.com/up9inc/mizu/agent/pkg/api" "github.com/up9inc/mizu/agent/pkg/api"
"github.com/up9inc/mizu/agent/pkg/providers"
"github.com/up9inc/mizu/agent/pkg/utils" "github.com/up9inc/mizu/agent/pkg/utils"
"github.com/up9inc/mizu/logger" "github.com/up9inc/mizu/logger"
tapApi "github.com/up9inc/mizu/tap/api" tapApi "github.com/up9inc/mizu/tap/api"
@ -81,6 +82,7 @@ func LoadExtensions() {
}) })
api.InitMaps(ExtensionsMap, ProtocolsMap) api.InitMaps(ExtensionsMap, ProtocolsMap)
providers.InitProtocolToColor(ProtocolsMap)
} }
func ConfigureBasenineServer(host string, port string, dbSize int64, logLevel logging.Level, insertionFilter string) { func ConfigureBasenineServer(host string, port string, dbSize int64, logLevel logging.Level, insertionFilter string) {

View File

@ -79,13 +79,8 @@ func GetGeneralStats(c *gin.Context) {
c.JSON(http.StatusOK, providers.GetGeneralStats()) c.JSON(http.StatusOK, providers.GetGeneralStats())
} }
func GetAccumulativeStats(c *gin.Context) { func GetTrafficStats(c *gin.Context) {
c.JSON(http.StatusOK, providers.GetAccumulativeStats()) c.JSON(http.StatusOK, providers.GetTrafficStats())
}
func GetAccumulativeStatsTiming(c *gin.Context) {
// for now hardcoded 10 bars of 5 minutes interval
c.JSON(http.StatusOK, providers.GetAccumulativeStatsTiming(300, 10))
} }
func GetCurrentResolvingInformation(c *gin.Context) { func GetCurrentResolvingInformation(c *gin.Context) {

View File

@ -2,6 +2,7 @@ package providers
import ( import (
"reflect" "reflect"
"strings"
"sync" "sync"
"time" "time"
@ -26,7 +27,6 @@ type TimeFrameStatsValue struct {
type ProtocolStats struct { type ProtocolStats struct {
MethodsStats map[string]*SizeAndEntriesCount `json:"methods"` MethodsStats map[string]*SizeAndEntriesCount `json:"methods"`
Color string `json:"color"`
} }
type SizeAndEntriesCount struct { type SizeAndEntriesCount struct {
@ -51,46 +51,103 @@ type AccumulativeStatsProtocolTime struct {
Time int64 `json:"timestamp"` Time int64 `json:"timestamp"`
} }
type TrafficStatsResponse struct {
PieStats []*AccumulativeStatsProtocol `json:"pie"`
TimelineStats []*AccumulativeStatsProtocolTime `json:"timeline"`
}
var ( var (
generalStats = GeneralStats{} generalStats = GeneralStats{}
bucketsStats = BucketStats{} bucketsStats = BucketStats{}
bucketStatsLocker = sync.Mutex{} bucketStatsLocker = sync.Mutex{}
protocolToColor = map[string]string{}
) )
const ( const (
InternalBucketThreshold = time.Minute * 1 InternalBucketThreshold = time.Minute * 1
MaxNumberOfBars = 30
) )
func ResetGeneralStats() { func ResetGeneralStats() {
generalStats = GeneralStats{} generalStats = GeneralStats{}
} }
func GetGeneralStats() GeneralStats { func GetGeneralStats() *GeneralStats {
return generalStats return &generalStats
} }
func GetAccumulativeStats() []*AccumulativeStatsProtocol { func InitProtocolToColor(protocolMap map[string]*api.Protocol) {
bucketStatsCopy := getBucketStatsCopy() for item, value := range protocolMap {
if len(bucketStatsCopy) == 0 { protocolToColor[strings.Split(item, "/")[2]] = value.BackgroundColor
}
}
func GetTrafficStats() *TrafficStatsResponse {
bucketsStatsCopy := getBucketStatsCopy()
interval := calculateInterval(bucketsStatsCopy[0].BucketTime.Unix(), bucketsStatsCopy[len(bucketsStatsCopy)-1].BucketTime.Unix()) // in seconds
return &TrafficStatsResponse{
PieStats: getAccumulativeStats(bucketsStatsCopy),
TimelineStats: getAccumulativeStatsTiming(bucketsStatsCopy, interval),
}
}
func calculateInterval(firstTimestamp int64, lastTimestamp int64) time.Duration {
validDurations := []time.Duration{
time.Minute,
time.Minute * 2,
time.Minute * 3,
time.Minute * 5,
time.Minute * 10,
time.Minute * 15,
time.Minute * 20,
time.Minute * 30,
time.Minute * 45,
time.Minute * 60,
time.Minute * 75,
time.Minute * 90, // 1.5 minutes
time.Minute * 120, // 2 hours
time.Minute * 150, // 2.5 hours
time.Minute * 180, // 3 hours
time.Minute * 240, // 4 hours
time.Minute * 300, // 5 hours
time.Minute * 360, // 6 hours
time.Minute * 420, // 7 hours
time.Minute * 480, // 8 hours
time.Minute * 540, // 9 hours
time.Minute * 600, // 10 hours
time.Minute * 660, // 11 hours
time.Minute * 720, // 12 hours
time.Minute * 1440, // 24 hours
}
duration := time.Duration(lastTimestamp-firstTimestamp) * time.Second / time.Duration(MaxNumberOfBars)
for _, validDuration := range validDurations {
if validDuration-duration >= 0 {
return validDuration
}
}
return duration.Round(validDurations[len(validDurations)-1])
}
func getAccumulativeStats(stats BucketStats) []*AccumulativeStatsProtocol {
if len(stats) == 0 {
return make([]*AccumulativeStatsProtocol, 0) return make([]*AccumulativeStatsProtocol, 0)
} }
methodsPerProtocolAggregated, protocolToColor := getAggregatedStatsAllTime(bucketStatsCopy) methodsPerProtocolAggregated := getAggregatedStats(stats)
return convertAccumulativeStatsDictToArray(methodsPerProtocolAggregated, protocolToColor) return convertAccumulativeStatsDictToArray(methodsPerProtocolAggregated)
} }
func GetAccumulativeStatsTiming(intervalSeconds int, numberOfBars int) []*AccumulativeStatsProtocolTime { func getAccumulativeStatsTiming(stats BucketStats, interval time.Duration) []*AccumulativeStatsProtocolTime {
bucketStatsCopy := getBucketStatsCopy() if len(stats) == 0 {
if len(bucketStatsCopy) == 0 {
return make([]*AccumulativeStatsProtocolTime, 0) return make([]*AccumulativeStatsProtocolTime, 0)
} }
firstBucketTime := getFirstBucketTime(time.Now().UTC(), intervalSeconds, numberOfBars) methodsPerProtocolPerTimeAggregated := getAggregatedResultTiming(interval, stats)
methodsPerProtocolPerTimeAggregated, protocolToColor := getAggregatedResultTimingFromSpecificTime(intervalSeconds, bucketStatsCopy, firstBucketTime) return convertAccumulativeStatsTimelineDictToArray(methodsPerProtocolPerTimeAggregated)
return convertAccumulativeStatsTimelineDictToArray(methodsPerProtocolPerTimeAggregated, protocolToColor)
} }
func EntryAdded(size int, summery *api.BaseEntry) { func EntryAdded(size int, summery *api.BaseEntry) {
@ -128,7 +185,6 @@ func addToBucketStats(size int, summery *api.BaseEntry) {
if _, found := bucketOfEntry.ProtocolStats[summery.Protocol.Abbreviation]; !found { if _, found := bucketOfEntry.ProtocolStats[summery.Protocol.Abbreviation]; !found {
bucketOfEntry.ProtocolStats[summery.Protocol.Abbreviation] = ProtocolStats{ bucketOfEntry.ProtocolStats[summery.Protocol.Abbreviation] = ProtocolStats{
MethodsStats: map[string]*SizeAndEntriesCount{}, MethodsStats: map[string]*SizeAndEntriesCount{},
Color: summery.Protocol.BackgroundColor,
} }
} }
if _, found := bucketOfEntry.ProtocolStats[summery.Protocol.Abbreviation].MethodsStats[summery.Method]; !found { if _, found := bucketOfEntry.ProtocolStats[summery.Protocol.Abbreviation].MethodsStats[summery.Method]; !found {
@ -147,13 +203,7 @@ func getBucketFromTimeStamp(timestamp int64) time.Time {
return entryTimeStampAsTime.Add(-1 * InternalBucketThreshold / 2).Round(InternalBucketThreshold) return entryTimeStampAsTime.Add(-1 * InternalBucketThreshold / 2).Round(InternalBucketThreshold)
} }
func getFirstBucketTime(endTime time.Time, intervalSeconds int, numberOfBars int) time.Time { func convertAccumulativeStatsTimelineDictToArray(methodsPerProtocolPerTimeAggregated map[time.Time]map[string]map[string]*AccumulativeStatsCounter) []*AccumulativeStatsProtocolTime {
lastBucketTime := endTime.Add(-1 * time.Second * time.Duration(intervalSeconds) / 2).Round(time.Second * time.Duration(intervalSeconds))
firstBucketTime := lastBucketTime.Add(-1 * time.Second * time.Duration(intervalSeconds*(numberOfBars-1)))
return firstBucketTime
}
func convertAccumulativeStatsTimelineDictToArray(methodsPerProtocolPerTimeAggregated map[time.Time]map[string]map[string]*AccumulativeStatsCounter, protocolToColor map[string]string) []*AccumulativeStatsProtocolTime {
finalResult := make([]*AccumulativeStatsProtocolTime, 0) finalResult := make([]*AccumulativeStatsProtocolTime, 0)
for timeKey, item := range methodsPerProtocolPerTimeAggregated { for timeKey, item := range methodsPerProtocolPerTimeAggregated {
protocolsData := make([]*AccumulativeStatsProtocol, 0) protocolsData := make([]*AccumulativeStatsProtocol, 0)
@ -184,7 +234,7 @@ func convertAccumulativeStatsTimelineDictToArray(methodsPerProtocolPerTimeAggreg
return finalResult return finalResult
} }
func convertAccumulativeStatsDictToArray(methodsPerProtocolAggregated map[string]map[string]*AccumulativeStatsCounter, protocolToColor map[string]string) []*AccumulativeStatsProtocol { func convertAccumulativeStatsDictToArray(methodsPerProtocolAggregated map[string]map[string]*AccumulativeStatsCounter) []*AccumulativeStatsProtocol {
protocolsData := make([]*AccumulativeStatsProtocol, 0) protocolsData := make([]*AccumulativeStatsProtocol, 0)
for protocolName, value := range methodsPerProtocolAggregated { for protocolName, value := range methodsPerProtocolAggregated {
entriesCount := 0 entriesCount := 0
@ -219,55 +269,44 @@ func getBucketStatsCopy() BucketStats {
return bucketStatsCopy return bucketStatsCopy
} }
func getAggregatedResultTimingFromSpecificTime(intervalSeconds int, bucketStats BucketStats, firstBucketTime time.Time) (map[time.Time]map[string]map[string]*AccumulativeStatsCounter, map[string]string) { func getAggregatedResultTiming(interval time.Duration, stats BucketStats) map[time.Time]map[string]map[string]*AccumulativeStatsCounter {
protocolToColor := map[string]string{}
methodsPerProtocolPerTimeAggregated := map[time.Time]map[string]map[string]*AccumulativeStatsCounter{} methodsPerProtocolPerTimeAggregated := map[time.Time]map[string]map[string]*AccumulativeStatsCounter{}
bucketStatsIndex := len(bucketStats) - 1 bucketStatsIndex := len(stats) - 1
for bucketStatsIndex >= 0 { for bucketStatsIndex >= 0 {
currentBucketTime := bucketStats[bucketStatsIndex].BucketTime currentBucketTime := stats[bucketStatsIndex].BucketTime
if currentBucketTime.After(firstBucketTime) || currentBucketTime.Equal(firstBucketTime) { resultBucketRoundedKey := currentBucketTime.Add(-1 * interval / 2).Round(interval)
resultBucketRoundedKey := currentBucketTime.Add(-1 * time.Second * time.Duration(intervalSeconds) / 2).Round(time.Second * time.Duration(intervalSeconds))
for protocolName, data := range bucketStats[bucketStatsIndex].ProtocolStats { for protocolName, data := range stats[bucketStatsIndex].ProtocolStats {
if _, ok := protocolToColor[protocolName]; !ok { for methodName, dataOfMethod := range data.MethodsStats {
protocolToColor[protocolName] = data.Color
if _, ok := methodsPerProtocolPerTimeAggregated[resultBucketRoundedKey]; !ok {
methodsPerProtocolPerTimeAggregated[resultBucketRoundedKey] = map[string]map[string]*AccumulativeStatsCounter{}
} }
if _, ok := methodsPerProtocolPerTimeAggregated[resultBucketRoundedKey][protocolName]; !ok {
for methodName, dataOfMethod := range data.MethodsStats { methodsPerProtocolPerTimeAggregated[resultBucketRoundedKey][protocolName] = map[string]*AccumulativeStatsCounter{}
if _, ok := methodsPerProtocolPerTimeAggregated[resultBucketRoundedKey]; !ok {
methodsPerProtocolPerTimeAggregated[resultBucketRoundedKey] = map[string]map[string]*AccumulativeStatsCounter{}
}
if _, ok := methodsPerProtocolPerTimeAggregated[resultBucketRoundedKey][protocolName]; !ok {
methodsPerProtocolPerTimeAggregated[resultBucketRoundedKey][protocolName] = map[string]*AccumulativeStatsCounter{}
}
if _, ok := methodsPerProtocolPerTimeAggregated[resultBucketRoundedKey][protocolName][methodName]; !ok {
methodsPerProtocolPerTimeAggregated[resultBucketRoundedKey][protocolName][methodName] = &AccumulativeStatsCounter{
Name: methodName,
EntriesCount: 0,
VolumeSizeBytes: 0,
}
}
methodsPerProtocolPerTimeAggregated[resultBucketRoundedKey][protocolName][methodName].EntriesCount += dataOfMethod.EntriesCount
methodsPerProtocolPerTimeAggregated[resultBucketRoundedKey][protocolName][methodName].VolumeSizeBytes += dataOfMethod.VolumeInBytes
} }
if _, ok := methodsPerProtocolPerTimeAggregated[resultBucketRoundedKey][protocolName][methodName]; !ok {
methodsPerProtocolPerTimeAggregated[resultBucketRoundedKey][protocolName][methodName] = &AccumulativeStatsCounter{
Name: methodName,
EntriesCount: 0,
VolumeSizeBytes: 0,
}
}
methodsPerProtocolPerTimeAggregated[resultBucketRoundedKey][protocolName][methodName].EntriesCount += dataOfMethod.EntriesCount
methodsPerProtocolPerTimeAggregated[resultBucketRoundedKey][protocolName][methodName].VolumeSizeBytes += dataOfMethod.VolumeInBytes
} }
} }
bucketStatsIndex-- bucketStatsIndex--
} }
return methodsPerProtocolPerTimeAggregated, protocolToColor return methodsPerProtocolPerTimeAggregated
} }
func getAggregatedStatsAllTime(bucketStatsCopy BucketStats) (map[string]map[string]*AccumulativeStatsCounter, map[string]string) { func getAggregatedStats(bucketStatsCopy BucketStats) map[string]map[string]*AccumulativeStatsCounter {
protocolToColor := make(map[string]string, 0)
methodsPerProtocolAggregated := make(map[string]map[string]*AccumulativeStatsCounter, 0) methodsPerProtocolAggregated := make(map[string]map[string]*AccumulativeStatsCounter, 0)
for _, countersOfTimeFrame := range bucketStatsCopy { for _, countersOfTimeFrame := range bucketStatsCopy {
for protocolName, value := range countersOfTimeFrame.ProtocolStats { for protocolName, value := range countersOfTimeFrame.ProtocolStats {
if _, ok := protocolToColor[protocolName]; !ok {
protocolToColor[protocolName] = value.Color
}
for method, countersValue := range value.MethodsStats { for method, countersValue := range value.MethodsStats {
if _, found := methodsPerProtocolAggregated[protocolName]; !found { if _, found := methodsPerProtocolAggregated[protocolName]; !found {
methodsPerProtocolAggregated[protocolName] = map[string]*AccumulativeStatsCounter{} methodsPerProtocolAggregated[protocolName] = map[string]*AccumulativeStatsCounter{}
@ -284,5 +323,5 @@ func getAggregatedStatsAllTime(bucketStatsCopy BucketStats) (map[string]map[stri
} }
} }
} }
return methodsPerProtocolAggregated, protocolToColor return methodsPerProtocolAggregated
} }

View File

@ -26,38 +26,6 @@ func TestGetBucketOfTimeStamp(t *testing.T) {
} }
} }
type DataForBucketBorderFunction struct {
EndTime time.Time
IntervalInSeconds int
NumberOfBars int
}
func TestGetBucketBorders(t *testing.T) {
tests := map[DataForBucketBorderFunction]time.Time{
DataForBucketBorderFunction{
time.Date(2022, time.Month(1), 1, 10, 34, 45, 0, time.UTC),
300,
10,
}: time.Date(2022, time.Month(1), 1, 9, 45, 0, 0, time.UTC),
DataForBucketBorderFunction{
time.Date(2022, time.Month(1), 1, 10, 35, 45, 0, time.UTC),
60,
5,
}: time.Date(2022, time.Month(1), 1, 10, 31, 00, 0, time.UTC),
}
for key, value := range tests {
t.Run(fmt.Sprintf("%v", key), func(t *testing.T) {
actual := getFirstBucketTime(key.EndTime, key.IntervalInSeconds, key.NumberOfBars)
if actual != value {
t.Errorf("unexpected result - expected: %v, actual: %v", value, actual)
}
})
}
}
func TestGetAggregatedStatsAllTime(t *testing.T) { func TestGetAggregatedStatsAllTime(t *testing.T) {
bucketStatsForTest := BucketStats{ bucketStatsForTest := BucketStats{
&TimeFrameStatsValue{ &TimeFrameStatsValue{
@ -140,7 +108,7 @@ func TestGetAggregatedStatsAllTime(t *testing.T) {
}, },
}, },
} }
actual, _ := getAggregatedStatsAllTime(bucketStatsForTest) actual := getAggregatedStats(bucketStatsForTest)
if !reflect.DeepEqual(actual, expected) { if !reflect.DeepEqual(actual, expected) {
t.Errorf("unexpected result - expected: %v, actual: %v", 3, len(actual)) t.Errorf("unexpected result - expected: %v, actual: %v", 3, len(actual))
@ -227,7 +195,7 @@ func TestGetAggregatedStatsFromSpecificTime(t *testing.T) {
}, },
}, },
} }
actual, _ := getAggregatedResultTimingFromSpecificTime(300, bucketStatsForTest, time.Date(2022, time.Month(1), 1, 10, 00, 00, 0, time.UTC)) actual := getAggregatedResultTiming(time.Minute*5, bucketStatsForTest)
if !reflect.DeepEqual(actual, expected) { if !reflect.DeepEqual(actual, expected) {
t.Errorf("unexpected result - expected: %v, actual: %v", 3, len(actual)) t.Errorf("unexpected result - expected: %v, actual: %v", 3, len(actual))
@ -323,7 +291,7 @@ func TestGetAggregatedStatsFromSpecificTimeMultipleBuckets(t *testing.T) {
}, },
}, },
} }
actual, _ := getAggregatedResultTimingFromSpecificTime(60, bucketStatsForTest, time.Date(2022, time.Month(1), 1, 10, 00, 00, 0, time.UTC)) actual := getAggregatedResultTiming(time.Minute, bucketStatsForTest)
if !reflect.DeepEqual(actual, expected) { if !reflect.DeepEqual(actual, expected) {
t.Errorf("unexpected result - expected: %v, actual: %v", 3, len(actual)) t.Errorf("unexpected result - expected: %v, actual: %v", 3, len(actual))

View File

@ -15,9 +15,8 @@ func StatusRoutes(ginApp *gin.Engine) {
routeGroup.GET("/connectedTappersCount", controllers.GetConnectedTappersCount) routeGroup.GET("/connectedTappersCount", controllers.GetConnectedTappersCount)
routeGroup.GET("/tap", controllers.GetTappingStatus) routeGroup.GET("/tap", controllers.GetTappingStatus)
routeGroup.GET("/general", controllers.GetGeneralStats) // get general stats about entries in DB routeGroup.GET("/general", controllers.GetGeneralStats)
routeGroup.GET("/accumulative", controllers.GetAccumulativeStats) routeGroup.GET("/trafficStats", controllers.GetTrafficStats)
routeGroup.GET("/accumulativeTiming", controllers.GetAccumulativeStatsTiming)
routeGroup.GET("/resolving", controllers.GetCurrentResolvingInformation) routeGroup.GET("/resolving", controllers.GetCurrentResolvingInformation)
} }

View File

@ -26,7 +26,7 @@ export const TimelineBarChart: React.FC<TimelineBarChartProps> = ({ timeLineBarC
if (!data) return; if (!data) return;
const protocolsBarsData = []; const protocolsBarsData = [];
const prtcNames = []; const prtcNames = [];
data.forEach(protocolObj => { data.sort((a, b) => a.timestamp < b.timestamp ? -1 : 1).forEach(protocolObj => {
let newProtocolbj: { [k: string]: any } = {}; let newProtocolbj: { [k: string]: any } = {};
newProtocolbj.timestamp = Utils.getHoursAndMinutes(protocolObj.timestamp); newProtocolbj.timestamp = Utils.getHoursAndMinutes(protocolObj.timestamp);
protocolObj.protocols.forEach(protocol => { protocolObj.protocols.forEach(protocol => {
@ -36,7 +36,6 @@ export const TimelineBarChart: React.FC<TimelineBarChartProps> = ({ timeLineBarC
protocolsBarsData.push(newProtocolbj); protocolsBarsData.push(newProtocolbj);
}) })
const uniqueObjArray = Utils.creatUniqueObjArrayByProp(prtcNames, "name") const uniqueObjArray = Utils.creatUniqueObjArrayByProp(prtcNames, "name")
protocolsBarsData.sort((a, b) => a.timestamp < b.timestamp ? -1 : 1);
setProtocolStats(protocolsBarsData); setProtocolStats(protocolsBarsData);
setProtocolsNamesAndColors(uniqueObjArray); setProtocolsNamesAndColors(uniqueObjArray);
}, [data, timeLineBarChartMode]) }, [data, timeLineBarChartMode])
@ -49,7 +48,7 @@ export const TimelineBarChart: React.FC<TimelineBarChartProps> = ({ timeLineBarC
} }
const commandsNames = []; const commandsNames = [];
const protocolsCommands = []; const protocolsCommands = [];
data.forEach(protocolObj => { data.sort((a, b) => a.timestamp < b.timestamp ? -1 : 1).forEach(protocolObj => {
let newCommandlbj: { [k: string]: any } = {}; let newCommandlbj: { [k: string]: any } = {};
newCommandlbj.timestamp = Utils.getHoursAndMinutes(protocolObj.timestamp); newCommandlbj.timestamp = Utils.getHoursAndMinutes(protocolObj.timestamp);
protocolObj.protocols.find(protocol => protocol.name === selectedProtocol)?.methods.forEach(command => { protocolObj.protocols.find(protocol => protocol.name === selectedProtocol)?.methods.forEach(command => {
@ -59,21 +58,33 @@ export const TimelineBarChart: React.FC<TimelineBarChartProps> = ({ timeLineBarC
}) })
protocolsCommands.push(newCommandlbj); protocolsCommands.push(newCommandlbj);
}) })
protocolsCommands.sort((a, b) => a.timestamp < b.timestamp ? -1 : 1);
setcommandNames(commandsNames); setcommandNames(commandsNames);
setCommandStats(protocolsCommands); setCommandStats(protocolsCommands);
}, [data, timeLineBarChartMode, selectedProtocol]) }, [data, timeLineBarChartMode, selectedProtocol])
const bars = useMemo(() => (commandNames || protocolsNamesAndColors).map((entry) => { const bars = useMemo(() => (commandNames || protocolsNamesAndColors).map((entry) => {
return <Bar key={entry.name || entry} dataKey={entry.name || entry} stackId="a" fill={entry.color || Utils.stringToColor(entry)} /> return <Bar key={entry.name || entry} dataKey={entry.name || entry} stackId="a" fill={entry.color || Utils.stringToColor(entry)} barSize={30} />
}), [protocolsNamesAndColors, commandNames]) }), [protocolsNamesAndColors, commandNames])
const renderTick = (tickProps) => {
const { x, y, payload } = tickProps;
const { index, value } = payload;
if (index % 3 === 0) {
return <text x={x} y={y + 10} textAnchor="end">{`${value}`}</text>;
}
return null;
};
return ( return (
<div className={styles.barChartContainer}> <div className={styles.barChartContainer}>
{protocolStats.length > 0 && <BarChart {protocolStats.length > 0 && <BarChart
width={730} width={750}
height={250} height={250}
data={commandStats || protocolStats} data={commandStats || protocolStats}
barCategoryGap={0}
barSize={30}
margin={{ margin={{
top: 20, top: 20,
right: 30, right: 30,
@ -81,7 +92,7 @@ export const TimelineBarChart: React.FC<TimelineBarChartProps> = ({ timeLineBarC
bottom: 5 bottom: 5
}} }}
> >
<XAxis dataKey="timestamp" /> <XAxis dataKey="timestamp" tick={renderTick} tickLine={false} />
<YAxis tickFormatter={(value) => timeLineBarChartMode === "VOLUME" ? Utils.humanFileSize(value) : value} /> <YAxis tickFormatter={(value) => timeLineBarChartMode === "VOLUME" ? Utils.humanFileSize(value) : value} />
<Tooltip formatter={(value) => timeLineBarChartMode === "VOLUME" ? Utils.humanFileSize(value) : value + " Requests"} /> <Tooltip formatter={(value) => timeLineBarChartMode === "VOLUME" ? Utils.humanFileSize(value) : value + " Requests"} />
{bars} {bars}

View File

@ -13,7 +13,7 @@ const modalStyle = {
top: '6%', top: '6%',
left: '50%', left: '50%',
transform: 'translate(-50%, 0%)', transform: 'translate(-50%, 0%)',
width: '50vw', width: '60vw',
height: '82vh', height: '82vh',
bgcolor: 'background.paper', bgcolor: 'background.paper',
borderRadius: '5px', borderRadius: '5px',
@ -30,14 +30,14 @@ export enum StatsMode {
interface TrafficStatsModalProps { interface TrafficStatsModalProps {
isOpen: boolean; isOpen: boolean;
onClose: () => void; onClose: () => void;
getPieStatsDataApi: () => Promise<any> getTrafficStatsDataApi: () => Promise<any>
getTimelineStatsDataApi: () => Promise<any>
} }
export const PROTOCOLS = ["ALL", "gRPC", "REDIS", "HTTP", "GQL", "AMQP", "KFAKA"];
export const PROTOCOLS = ["ALL", "gRPC", "REDIS", "HTTP", "GQL", "AMQP", "KAFKA"];
export const ALL_PROTOCOLS = PROTOCOLS[0]; export const ALL_PROTOCOLS = PROTOCOLS[0];
export const TrafficStatsModal: React.FC<TrafficStatsModalProps> = ({ isOpen, onClose, getPieStatsDataApi, getTimelineStatsDataApi }) => { export const TrafficStatsModal: React.FC<TrafficStatsModalProps> = ({ isOpen, onClose, getTrafficStatsDataApi }) => {
const modes = Object.keys(StatsMode).filter(x => !(parseInt(x) >= 0)); const modes = Object.keys(StatsMode).filter(x => !(parseInt(x) >= 0));
const [statsMode, setStatsMode] = useState(modes[0]); const [statsMode, setStatsMode] = useState(modes[0]);
@ -48,14 +48,13 @@ export const TrafficStatsModal: React.FC<TrafficStatsModalProps> = ({ isOpen, on
const commonClasses = useCommonStyles(); const commonClasses = useCommonStyles();
const getTrafficStats = useCallback(async () => { const getTrafficStats = useCallback(async () => {
if (isOpen && getPieStatsDataApi) { if (isOpen && getTrafficStatsDataApi) {
(async () => { (async () => {
try { try {
setIsLoading(true); setIsLoading(true);
const pieData = await getPieStatsDataApi(); const statsData = await getTrafficStatsDataApi();
setPieStatsData(pieData); setPieStatsData(statsData.pie);
const timelineData = await getTimelineStatsDataApi(); setTimelineStatsData(statsData.timeline);
setTimelineStatsData(timelineData);
} catch (e) { } catch (e) {
console.error(e) console.error(e)
} finally { } finally {
@ -63,7 +62,7 @@ export const TrafficStatsModal: React.FC<TrafficStatsModalProps> = ({ isOpen, on
} }
})() })()
} }
}, [isOpen, getPieStatsDataApi, getTimelineStatsDataApi, setPieStatsData, setTimelineStatsData]) }, [isOpen, getTrafficStatsDataApi, setPieStatsData, setTimelineStatsData])
useEffect(() => { useEffect(() => {
getTrafficStats(); getTrafficStats();

View File

@ -36,7 +36,7 @@ const App = () => {
openModal={oasModalOpen} openModal={oasModalOpen}
handleCloseModal={() => setOasModalOpen(false)} handleCloseModal={() => setOasModalOpen(false)}
/>} />}
<TrafficStatsModal isOpen={trafficStatsModalOpen} onClose={() => setTrafficStatsModalOpen(false)} getPieStatsDataApi={api.getPieStats} getTimelineStatsDataApi={api.getTimelineStats}/> <TrafficStatsModal isOpen={trafficStatsModalOpen} onClose={() => setTrafficStatsModalOpen(false)} getTrafficStatsDataApi={api.getTrafficStats}/>
</div> </div>
</ThemeProvider> </ThemeProvider>
</StyledEngineProvider> </StyledEngineProvider>

View File

@ -116,13 +116,8 @@ export default class Api {
}); });
} }
getPieStats = async () => { getTrafficStats = async () => {
const response = await client.get("/status/accumulative"); const response = await client.get("/status/trafficStats");
return response.data;
}
getTimelineStats = async () => {
const response = await client.get("/status/accumulativeTiming");
return response.data; return response.data;
} }
} }