Skip to content

Commit b128254

Browse files
committed
feat: adding topology custom metric model and service
1 parent d0dfe44 commit b128254

File tree

6 files changed

+385
-0
lines changed

6 files changed

+385
-0
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { Color } from '@hypertrace/common';
2+
import { BOOLEAN_PROPERTY, Model, ModelProperty, NUMBER_PROPERTY, STRING_PROPERTY } from '@hypertrace/hyperdash';
3+
import { kebabCase, uniqueId } from 'lodash-es';
4+
5+
@Model({
6+
type: 'topology-metric-category'
7+
})
8+
export class TopologyMetricCategoryModel implements TopologyMetricCategoryData {
9+
@ModelProperty({
10+
key: 'name',
11+
required: true,
12+
type: STRING_PROPERTY.type
13+
})
14+
public name!: string;
15+
16+
@ModelProperty({
17+
key: 'minValue',
18+
required: true,
19+
type: NUMBER_PROPERTY.type
20+
})
21+
public minValue!: number;
22+
23+
@ModelProperty({
24+
key: 'maxValue',
25+
required: false,
26+
type: NUMBER_PROPERTY.type
27+
})
28+
public maxValue?: number;
29+
30+
@ModelProperty({
31+
key: 'fillColor',
32+
required: true,
33+
type: STRING_PROPERTY.type
34+
})
35+
public fillColor!: Color;
36+
37+
@ModelProperty({
38+
key: 'strokeColor',
39+
required: true,
40+
type: STRING_PROPERTY.type
41+
})
42+
public strokeColor!: Color;
43+
44+
@ModelProperty({
45+
key: 'focusColor',
46+
required: true,
47+
type: STRING_PROPERTY.type
48+
})
49+
public focusColor!: Color;
50+
51+
@ModelProperty({
52+
key: 'highestPrecedence',
53+
required: false,
54+
type: BOOLEAN_PROPERTY.type
55+
})
56+
public highestPrecedence?: boolean = false;
57+
58+
private readonly id: string = uniqueId();
59+
60+
public getCategoryClassName(): string {
61+
return `${kebabCase(this.name)}-${this.id}`;
62+
}
63+
}
64+
65+
export interface TopologyMetricCategoryData {
66+
name: string;
67+
minValue: number;
68+
maxValue?: number;
69+
fillColor: string;
70+
strokeColor: string;
71+
focusColor: string;
72+
highestPrecedence?: boolean;
73+
getCategoryClassName(): string;
74+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { Dictionary } from '@hypertrace/common';
2+
import { MetricAggregation } from '@hypertrace/distributed-tracing';
3+
import {
4+
ARRAY_PROPERTY,
5+
Model,
6+
ModelModelPropertyTypeInstance,
7+
ModelProperty,
8+
ModelPropertyType
9+
} from '@hypertrace/hyperdash';
10+
import { MetricAggregationSpecificationModel } from '../../specifiers/metric-aggregation-specification.model';
11+
import { MetricAggregationSpecification } from './../../../../../graphql/model/schema/specifications/metric-aggregation-specification';
12+
import { TopologyMetricCategoryData, TopologyMetricCategoryModel } from './topology-metric-category.model';
13+
14+
@Model({
15+
type: 'topology-metric-with-category'
16+
})
17+
export class TopologyMetricWithCategoryModel implements TopologyMetricWithCategoryData {
18+
@ModelProperty({
19+
key: 'specification',
20+
required: true,
21+
// tslint:disable-next-line: no-object-literal-type-assertion
22+
type: {
23+
key: ModelPropertyType.TYPE,
24+
defaultModelClass: MetricAggregationSpecificationModel
25+
} as ModelModelPropertyTypeInstance
26+
})
27+
public specification!: MetricAggregationSpecificationModel;
28+
29+
@ModelProperty({
30+
key: 'categories',
31+
required: false,
32+
type: ARRAY_PROPERTY.type
33+
})
34+
public categories: TopologyMetricCategoryModel[] = [];
35+
36+
public extractAndGetDataCategoryForMetric(data: Dictionary<unknown>): TopologyMetricCategoryData | undefined {
37+
const aggregation = this.extractDataForMetric(data);
38+
39+
return aggregation !== undefined ? this.getDataCategoryForMetric(aggregation.value) : undefined;
40+
}
41+
42+
public extractDataForMetric(data: Dictionary<unknown>): MetricAggregation | undefined {
43+
return data[this.specification.resultAlias()] as MetricAggregation | undefined;
44+
}
45+
46+
private getDataCategoryForMetric(value: number): TopologyMetricCategoryData | undefined {
47+
return this.categories.find(
48+
category => value >= category.minValue && (category.maxValue !== undefined ? value < category.maxValue : true)
49+
);
50+
}
51+
}
52+
53+
export interface TopologyMetricWithCategoryData {
54+
specification: MetricAggregationSpecification;
55+
categories: TopologyMetricCategoryData[];
56+
extractDataForMetric(data: Dictionary<unknown>): MetricAggregation | undefined;
57+
extractAndGetDataCategoryForMetric(data: Dictionary<unknown>): TopologyMetricCategoryData | undefined;
58+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import {
2+
ARRAY_PROPERTY,
3+
Model,
4+
ModelModelPropertyTypeInstance,
5+
ModelProperty,
6+
ModelPropertyType
7+
} from '@hypertrace/hyperdash';
8+
import { TopologyMetricWithCategoryData, TopologyMetricWithCategoryModel } from './topology-metric-with-category.model';
9+
10+
@Model({
11+
type: 'topology-metrics'
12+
})
13+
export class TopologyMetricsModel implements TopologyMetricsData {
14+
@ModelProperty({
15+
key: 'primary',
16+
required: true,
17+
// tslint:disable-next-line: no-object-literal-type-assertion
18+
type: {
19+
key: ModelPropertyType.TYPE,
20+
defaultModelClass: TopologyMetricWithCategoryModel
21+
} as ModelModelPropertyTypeInstance
22+
})
23+
public primary!: TopologyMetricWithCategoryModel;
24+
25+
@ModelProperty({
26+
key: 'secondary',
27+
required: false,
28+
// tslint:disable-next-line: no-object-literal-type-assertion
29+
type: {
30+
key: ModelPropertyType.TYPE,
31+
defaultModelClass: TopologyMetricWithCategoryModel
32+
} as ModelModelPropertyTypeInstance
33+
})
34+
public secondary?: TopologyMetricWithCategoryModel;
35+
36+
@ModelProperty({
37+
key: 'others',
38+
required: false,
39+
type: ARRAY_PROPERTY.type
40+
})
41+
public others?: TopologyMetricWithCategoryModel[];
42+
}
43+
44+
export interface TopologyMetricsData {
45+
primary: TopologyMetricWithCategoryData;
46+
secondary?: TopologyMetricWithCategoryData;
47+
others?: TopologyMetricWithCategoryData[];
48+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import { Color } from '@hypertrace/common';
2+
import { TopologyMetricCategoryData } from '../../../data/graphql/topology/metrics/topology-metric-category.model';
3+
4+
const enum PrimaryEdgeMetricCategoryValueType {
5+
LessThan20 = 'less-than-20',
6+
From20To100 = 'from-20-to-100',
7+
From100To500 = 'from-100-to-500',
8+
From500To1000 = 'from-500-to-1000',
9+
GreaterThanOrEqualTo1000 = 'greater-than-or-equal-to-1000',
10+
NotSpecified = 'not-specified'
11+
}
12+
13+
const enum SecondaryEdgeMetricCategoryValueType {
14+
LessThan5 = 'less-than-5',
15+
GreaterThanOrEqualTo5 = 'greater-than-or-equal-to-5',
16+
NotSpecified = 'not-specified'
17+
}
18+
19+
export const defaultPrimaryEdgeMetricCategories: Omit<TopologyMetricCategoryData, 'getCategoryClassName'>[] = [
20+
{
21+
name: PrimaryEdgeMetricCategoryValueType.LessThan20,
22+
minValue: 0,
23+
maxValue: 20,
24+
fillColor: Color.BlueGray1,
25+
strokeColor: Color.BlueGray1,
26+
focusColor: Color.BlueGray1
27+
},
28+
{
29+
name: PrimaryEdgeMetricCategoryValueType.From20To100,
30+
minValue: 20,
31+
maxValue: 100,
32+
fillColor: Color.BlueGray2,
33+
strokeColor: Color.BlueGray2,
34+
focusColor: Color.BlueGray2
35+
},
36+
{
37+
name: PrimaryEdgeMetricCategoryValueType.From100To500,
38+
minValue: 100,
39+
maxValue: 500,
40+
fillColor: Color.BlueGray3,
41+
strokeColor: Color.BlueGray3,
42+
focusColor: Color.BlueGray3
43+
},
44+
{
45+
name: PrimaryEdgeMetricCategoryValueType.From500To1000,
46+
minValue: 500,
47+
maxValue: 1000,
48+
fillColor: Color.BlueGray4,
49+
strokeColor: Color.BlueGray4,
50+
focusColor: Color.BlueGray4
51+
},
52+
{
53+
name: PrimaryEdgeMetricCategoryValueType.GreaterThanOrEqualTo1000,
54+
minValue: 1000,
55+
maxValue: undefined,
56+
fillColor: Color.BlueGray4,
57+
strokeColor: Color.BlueGray4,
58+
focusColor: Color.BlueGray4
59+
}
60+
];
61+
62+
export const defaultSecondaryEdgeMetricCategories: Omit<TopologyMetricCategoryData, 'getCategoryClassName'>[] = [
63+
{
64+
name: SecondaryEdgeMetricCategoryValueType.LessThan5,
65+
minValue: 0,
66+
maxValue: 5,
67+
fillColor: Color.Gray2,
68+
strokeColor: Color.Gray2,
69+
focusColor: Color.Gray2
70+
},
71+
{
72+
name: SecondaryEdgeMetricCategoryValueType.GreaterThanOrEqualTo5,
73+
minValue: 5,
74+
maxValue: undefined,
75+
fillColor: Color.Red5,
76+
strokeColor: Color.Red5,
77+
focusColor: Color.Red5,
78+
highestPrecedence: true
79+
}
80+
];
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import { Color } from '@hypertrace/common';
2+
import { TopologyMetricCategoryData } from '../../../data/graphql/topology/metrics/topology-metric-category.model';
3+
4+
const enum PrimaryNodeMetricCategoryValueType {
5+
LessThan20 = 'less-than-20',
6+
From20To100 = 'from-20-to-100',
7+
From100To500 = 'from-100-to-500',
8+
From500To1000 = 'from-500-to-1000',
9+
GreaterThanOrEqualTo1000 = 'greater-than-or-equal-to-1000',
10+
NotSpecified = 'not-specified'
11+
}
12+
13+
const enum SecondaryNodeMetricCategoryValueType {
14+
LessThan5 = 'less-than-5',
15+
GreaterThanOrEqualTo5 = 'greater-than-or-equal-to-5',
16+
NotSpecified = 'not-specified'
17+
}
18+
19+
export const defaultPrimaryNodeMetricCategories: Omit<TopologyMetricCategoryData, 'getCategoryClassName'>[] = [
20+
{
21+
name: PrimaryNodeMetricCategoryValueType.LessThan20,
22+
minValue: 0,
23+
maxValue: 20,
24+
fillColor: Color.BlueGray1,
25+
strokeColor: Color.BlueGray1,
26+
focusColor: Color.Blue4
27+
},
28+
{
29+
name: PrimaryNodeMetricCategoryValueType.From20To100,
30+
minValue: 20,
31+
maxValue: 100,
32+
fillColor: Color.BlueGray2,
33+
strokeColor: Color.BlueGray2,
34+
focusColor: Color.Blue4
35+
},
36+
{
37+
name: PrimaryNodeMetricCategoryValueType.From100To500,
38+
minValue: 100,
39+
maxValue: 500,
40+
fillColor: Color.BlueGray3,
41+
strokeColor: Color.BlueGray3,
42+
focusColor: Color.Blue4
43+
},
44+
{
45+
name: PrimaryNodeMetricCategoryValueType.From500To1000,
46+
minValue: 500,
47+
maxValue: 1000,
48+
fillColor: Color.BlueGray4,
49+
strokeColor: Color.BlueGray4,
50+
focusColor: Color.Blue4
51+
},
52+
{
53+
name: PrimaryNodeMetricCategoryValueType.GreaterThanOrEqualTo1000,
54+
minValue: 1000,
55+
maxValue: undefined,
56+
fillColor: Color.BlueGray4,
57+
strokeColor: Color.BlueGray4,
58+
focusColor: Color.Blue4
59+
}
60+
];
61+
62+
export const defaultSecondaryNodeMetricCategories: Omit<TopologyMetricCategoryData, 'getCategoryClassName'>[] = [
63+
{
64+
name: SecondaryNodeMetricCategoryValueType.LessThan5,
65+
minValue: 0,
66+
maxValue: 5,
67+
fillColor: Color.Gray2,
68+
strokeColor: Color.Gray2,
69+
focusColor: Color.Blue4
70+
},
71+
{
72+
name: SecondaryNodeMetricCategoryValueType.GreaterThanOrEqualTo5,
73+
minValue: 5,
74+
maxValue: undefined,
75+
fillColor: Color.Red1,
76+
strokeColor: Color.Red5,
77+
focusColor: Color.Red5,
78+
highestPrecedence: true
79+
}
80+
];
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { Injectable } from '@angular/core';
2+
import { TopologyMetricCategoryData } from '../../data/graphql/topology/metrics/topology-metric-category.model';
3+
import { TopologyMetricWithCategoryData } from '../../data/graphql/topology/metrics/topology-metric-with-category.model';
4+
import { TopologyMetricsData } from '../../data/graphql/topology/metrics/topology-metrics.model';
5+
6+
@Injectable()
7+
export class TopologyDataSourceModelPropertiesService {
8+
private nodeMetrics?: TopologyMetricsData;
9+
private edgeMetrics?: TopologyMetricsData;
10+
11+
public setModelProperties(nodeMetrics: TopologyMetricsData, edgeMetrics: TopologyMetricsData): void {
12+
this.nodeMetrics = nodeMetrics;
13+
this.edgeMetrics = edgeMetrics;
14+
}
15+
16+
public getPrimaryNodeMetric(): TopologyMetricWithCategoryData | undefined {
17+
return this.nodeMetrics?.primary;
18+
}
19+
20+
public getSecondaryNodeMetric(): TopologyMetricWithCategoryData | undefined {
21+
return this.nodeMetrics?.secondary;
22+
}
23+
24+
public getPrimaryEdgeMetric(): TopologyMetricWithCategoryData | undefined {
25+
return this.edgeMetrics?.primary;
26+
}
27+
28+
public getSecondaryEdgeMetric(): TopologyMetricWithCategoryData | undefined {
29+
return this.edgeMetrics?.secondary;
30+
}
31+
32+
public getAllNodeCategories(): TopologyMetricCategoryData[] {
33+
return [this.nodeMetrics?.primary, this.nodeMetrics?.secondary, this.nodeMetrics?.others]
34+
.flat()
35+
.map(categoryData => categoryData?.categories ?? [])
36+
.flat();
37+
}
38+
39+
public getAllEdgeCategories(): TopologyMetricCategoryData[] {
40+
return [this.edgeMetrics?.primary, this.edgeMetrics?.secondary, this.edgeMetrics?.others]
41+
.flat()
42+
.map(categoryData => categoryData?.categories ?? [])
43+
.flat();
44+
}
45+
}

0 commit comments

Comments
 (0)