@oneuptime/common 11.3.9 → 11.3.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/AnalyticsModels/MutableMetric.ts +333 -0
- package/Server/Services/AlertService.ts +167 -206
- package/Server/Services/AlertStateTimelineService.ts +121 -1
- package/Server/Services/AnalyticsDatabaseService.ts +19 -23
- package/Server/Services/IncidentService.ts +179 -252
- package/Server/Services/IncidentStateTimelineService.ts +120 -1
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/MetricAggregationService.ts +73 -3
- package/Server/Services/MetricService.ts +228 -0
- package/Server/Services/MutableMetricService.ts +275 -0
- package/Server/Services/TelemetryAttributeService.ts +183 -1
- package/Server/Utils/AnalyticsDatabase/ClusterConfig.ts +2 -0
- package/Server/Utils/AnalyticsDatabase/Statement.ts +2 -0
- package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +143 -0
- package/Tests/Types/Monitor/MonitorStepEntityScope.test.ts +0 -56
- package/Types/AnalyticsDatabase/AnalyticsTableEngine.ts +1 -0
- package/Types/AnalyticsDatabase/AnalyticsTableName.ts +1 -0
- package/Types/Monitor/MonitorStepMetricMonitor.ts +0 -27
- package/build/dist/Models/AnalyticsModels/MutableMetric.js +275 -0
- package/build/dist/Models/AnalyticsModels/MutableMetric.js.map +1 -0
- package/build/dist/Server/Services/AlertService.js +133 -170
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/AlertStateTimelineService.js +97 -0
- package/build/dist/Server/Services/AlertStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +16 -15
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +142 -207
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentStateTimelineService.js +97 -0
- package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +2 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/MetricAggregationService.js +49 -3
- package/build/dist/Server/Services/MetricAggregationService.js.map +1 -1
- package/build/dist/Server/Services/MetricService.js +155 -0
- package/build/dist/Server/Services/MetricService.js.map +1 -1
- package/build/dist/Server/Services/MutableMetricService.js +182 -0
- package/build/dist/Server/Services/MutableMetricService.js.map +1 -0
- package/build/dist/Server/Services/TelemetryAttributeService.js +131 -6
- package/build/dist/Server/Services/TelemetryAttributeService.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/ClusterConfig.js +2 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/ClusterConfig.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js +2 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js.map +1 -1
- package/build/dist/Types/AnalyticsDatabase/AnalyticsTableEngine.js +1 -0
- package/build/dist/Types/AnalyticsDatabase/AnalyticsTableEngine.js.map +1 -1
- package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js +1 -0
- package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepMetricMonitor.js +0 -13
- package/build/dist/Types/Monitor/MonitorStepMetricMonitor.js.map +1 -1
- package/package.json +1 -1
|
@@ -13,6 +13,8 @@ import TableColumnType from "../../../Types/AnalyticsDatabase/TableColumnType";
|
|
|
13
13
|
import AggregationType from "../../../Types/BaseDatabase/AggregationType";
|
|
14
14
|
import BadDataException from "../../../Types/Exception/BadDataException";
|
|
15
15
|
import GenericObject from "../../../Types/GenericObject";
|
|
16
|
+
import ObjectID from "../../../Types/ObjectID";
|
|
17
|
+
import OneUptimeDate from "../../../Types/Date";
|
|
16
18
|
import {
|
|
17
19
|
describe,
|
|
18
20
|
expect,
|
|
@@ -379,6 +381,147 @@ describe("AnalyticsDatabaseService", () => {
|
|
|
379
381
|
* ids per call. Must be strictly additive: option-less calls keep the
|
|
380
382
|
* exact pre-existing exec/query payload.
|
|
381
383
|
*/
|
|
384
|
+
/*
|
|
385
|
+
* Required-field validation. A required column is satisfied by any present
|
|
386
|
+
* value (including the boolean `false`); only null/undefined triggers a
|
|
387
|
+
* default-fill or a "<field> is required" error. This is regression coverage
|
|
388
|
+
* for the boolean branch that previously rejected every required Boolean
|
|
389
|
+
* column (both true and false), which made models like MutableMetric — whose
|
|
390
|
+
* `isDeleted` tombstone flag is a required Boolean — impossible to insert.
|
|
391
|
+
*/
|
|
392
|
+
describe("checkRequiredFields", () => {
|
|
393
|
+
class RequiredFieldsModel extends AnalyticsBaseModel {
|
|
394
|
+
public constructor() {
|
|
395
|
+
super({
|
|
396
|
+
tableName: "<required-fields-table>",
|
|
397
|
+
singularName: "<singular-name>",
|
|
398
|
+
pluralName: "<plural-name>",
|
|
399
|
+
tableColumns: [
|
|
400
|
+
new AnalyticsTableColumn({
|
|
401
|
+
key: "requiredText",
|
|
402
|
+
title: "<title>",
|
|
403
|
+
description: "<description>",
|
|
404
|
+
required: true,
|
|
405
|
+
type: TableColumnType.Text,
|
|
406
|
+
}),
|
|
407
|
+
new AnalyticsTableColumn({
|
|
408
|
+
key: "requiredBoolWithDefault",
|
|
409
|
+
title: "<title>",
|
|
410
|
+
description: "<description>",
|
|
411
|
+
required: true,
|
|
412
|
+
type: TableColumnType.Boolean,
|
|
413
|
+
defaultValue: false,
|
|
414
|
+
}),
|
|
415
|
+
],
|
|
416
|
+
crudApiPath: new Route("route"),
|
|
417
|
+
primaryKeys: ["requiredText"],
|
|
418
|
+
sortKeys: ["requiredText"],
|
|
419
|
+
partitionKey: "requiredText",
|
|
420
|
+
tableEngine: AnalyticsTableEngine.MergeTree,
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// checkRequiredFields reads columns via property accessors, so the model
|
|
425
|
+
// must expose getters/setters that delegate to get/setColumnValue (real
|
|
426
|
+
// analytics models do the same for every column).
|
|
427
|
+
public get requiredText(): string | undefined {
|
|
428
|
+
return this.getColumnValue("requiredText") as string | undefined;
|
|
429
|
+
}
|
|
430
|
+
public set requiredText(v: string | undefined) {
|
|
431
|
+
this.setColumnValue("requiredText", v);
|
|
432
|
+
}
|
|
433
|
+
public get requiredBoolWithDefault(): boolean | undefined {
|
|
434
|
+
return this.getColumnValue("requiredBoolWithDefault") as
|
|
435
|
+
| boolean
|
|
436
|
+
| undefined;
|
|
437
|
+
}
|
|
438
|
+
public set requiredBoolWithDefault(v: boolean | undefined) {
|
|
439
|
+
this.setColumnValue("requiredBoolWithDefault", v);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
let requiredFieldsService: AnalyticsDatabaseService<RequiredFieldsModel>;
|
|
444
|
+
|
|
445
|
+
beforeEach(() => {
|
|
446
|
+
requiredFieldsService = new AnalyticsDatabaseService({
|
|
447
|
+
modelType: RequiredFieldsModel,
|
|
448
|
+
});
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
// Build a model with every required column satisfied except as overridden.
|
|
452
|
+
const buildModel: (
|
|
453
|
+
overrides?: (model: RequiredFieldsModel) => void,
|
|
454
|
+
) => RequiredFieldsModel = (
|
|
455
|
+
overrides?: (model: RequiredFieldsModel) => void,
|
|
456
|
+
): RequiredFieldsModel => {
|
|
457
|
+
const model: RequiredFieldsModel = new RequiredFieldsModel();
|
|
458
|
+
// _id and createdAt are required on the base model and carry no default.
|
|
459
|
+
model.setColumnValue("_id", ObjectID.generate());
|
|
460
|
+
model.setColumnValue("createdAt", OneUptimeDate.getCurrentDate());
|
|
461
|
+
model.setColumnValue("requiredText", "value");
|
|
462
|
+
if (overrides) {
|
|
463
|
+
overrides(model);
|
|
464
|
+
}
|
|
465
|
+
return model;
|
|
466
|
+
};
|
|
467
|
+
|
|
468
|
+
const check: (model: RequiredFieldsModel) => RequiredFieldsModel = (
|
|
469
|
+
model: RequiredFieldsModel,
|
|
470
|
+
): RequiredFieldsModel => {
|
|
471
|
+
return (requiredFieldsService as any).checkRequiredFields(model);
|
|
472
|
+
};
|
|
473
|
+
|
|
474
|
+
test("accepts a required boolean set to false (regression)", () => {
|
|
475
|
+
const model: RequiredFieldsModel = buildModel(
|
|
476
|
+
(m: RequiredFieldsModel): void => {
|
|
477
|
+
m.setColumnValue("requiredBoolWithDefault", false);
|
|
478
|
+
},
|
|
479
|
+
);
|
|
480
|
+
|
|
481
|
+
expect(() => {
|
|
482
|
+
return check(model);
|
|
483
|
+
}).not.toThrow();
|
|
484
|
+
expect(model.getColumnValue("requiredBoolWithDefault")).toBe(false);
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
test("accepts a required boolean set to true", () => {
|
|
488
|
+
const model: RequiredFieldsModel = buildModel(
|
|
489
|
+
(m: RequiredFieldsModel): void => {
|
|
490
|
+
m.setColumnValue("requiredBoolWithDefault", true);
|
|
491
|
+
},
|
|
492
|
+
);
|
|
493
|
+
|
|
494
|
+
expect(() => {
|
|
495
|
+
return check(model);
|
|
496
|
+
}).not.toThrow();
|
|
497
|
+
expect(model.getColumnValue("requiredBoolWithDefault")).toBe(true);
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
test("fills the default when a required boolean is unset", () => {
|
|
501
|
+
const model: RequiredFieldsModel = buildModel();
|
|
502
|
+
|
|
503
|
+
expect(() => {
|
|
504
|
+
return check(model);
|
|
505
|
+
}).not.toThrow();
|
|
506
|
+
expect(model.getColumnValue("requiredBoolWithDefault")).toBe(false);
|
|
507
|
+
});
|
|
508
|
+
|
|
509
|
+
test("throws when a required column without a default is missing", () => {
|
|
510
|
+
const model: RequiredFieldsModel = new RequiredFieldsModel();
|
|
511
|
+
model.setColumnValue("_id", ObjectID.generate());
|
|
512
|
+
model.setColumnValue("createdAt", OneUptimeDate.getCurrentDate());
|
|
513
|
+
model.setColumnValue("requiredBoolWithDefault", false);
|
|
514
|
+
// requiredText (required, no default) intentionally left unset.
|
|
515
|
+
|
|
516
|
+
expect(() => {
|
|
517
|
+
return check(model);
|
|
518
|
+
}).toThrow(BadDataException);
|
|
519
|
+
expect(() => {
|
|
520
|
+
return check(model);
|
|
521
|
+
}).toThrow("requiredText is required");
|
|
522
|
+
});
|
|
523
|
+
});
|
|
524
|
+
|
|
382
525
|
describe("execute / executeQuery per-call options", () => {
|
|
383
526
|
let exec: ReturnType<typeof jest.fn>;
|
|
384
527
|
let query: ReturnType<typeof jest.fn>;
|
|
@@ -4,7 +4,6 @@ import Log from "../../../Models/AnalyticsModels/Log";
|
|
|
4
4
|
import Span from "../../../Models/AnalyticsModels/Span";
|
|
5
5
|
import ExceptionInstance from "../../../Models/AnalyticsModels/ExceptionInstance";
|
|
6
6
|
import Profile from "../../../Models/AnalyticsModels/Profile";
|
|
7
|
-
import Metric from "../../../Models/AnalyticsModels/Metric";
|
|
8
7
|
import MonitorStepLogMonitor, {
|
|
9
8
|
MonitorStepLogMonitorUtil,
|
|
10
9
|
} from "../../../Types/Monitor/MonitorStepLogMonitor";
|
|
@@ -17,9 +16,6 @@ import MonitorStepExceptionMonitor, {
|
|
|
17
16
|
import MonitorStepProfileMonitor, {
|
|
18
17
|
MonitorStepProfileMonitorUtil,
|
|
19
18
|
} from "../../../Types/Monitor/MonitorStepProfileMonitor";
|
|
20
|
-
import MonitorStepMetricMonitor, {
|
|
21
|
-
MonitorStepMetricMonitorUtil,
|
|
22
|
-
} from "../../../Types/Monitor/MonitorStepMetricMonitor";
|
|
23
19
|
import { JSONObject } from "../../../Types/JSON";
|
|
24
20
|
|
|
25
21
|
/*
|
|
@@ -221,55 +217,3 @@ describe("MonitorStepProfileMonitorUtil.toQuery entity scoping", () => {
|
|
|
221
217
|
expectIncludes(query.entityKeys, TWO_KEYS);
|
|
222
218
|
});
|
|
223
219
|
});
|
|
224
|
-
|
|
225
|
-
describe("MonitorStepMetricMonitorUtil.applyEntityScopeToQuery", () => {
|
|
226
|
-
test("is a no-op when entityKeys is undefined (pre-existing saved monitors)", () => {
|
|
227
|
-
const step: MonitorStepMetricMonitor =
|
|
228
|
-
MonitorStepMetricMonitorUtil.getDefault();
|
|
229
|
-
delete step.entityKeys;
|
|
230
|
-
|
|
231
|
-
const query: Query<Metric> = {};
|
|
232
|
-
MonitorStepMetricMonitorUtil.applyEntityScopeToQuery(query, step);
|
|
233
|
-
|
|
234
|
-
expect(query.entityKeys).toBeUndefined();
|
|
235
|
-
expect(Object.keys(query)).toHaveLength(0);
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
test("is a no-op when entityKeys is an empty array", () => {
|
|
239
|
-
const step: MonitorStepMetricMonitor =
|
|
240
|
-
MonitorStepMetricMonitorUtil.getDefault();
|
|
241
|
-
step.entityKeys = [];
|
|
242
|
-
|
|
243
|
-
const query: Query<Metric> = {};
|
|
244
|
-
MonitorStepMetricMonitorUtil.applyEntityScopeToQuery(query, step);
|
|
245
|
-
|
|
246
|
-
expect(query.entityKeys).toBeUndefined();
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
test("stamps an Includes on entityKeys for two keys and preserves other predicates", () => {
|
|
250
|
-
const step: MonitorStepMetricMonitor =
|
|
251
|
-
MonitorStepMetricMonitorUtil.getDefault();
|
|
252
|
-
step.entityKeys = TWO_KEYS;
|
|
253
|
-
|
|
254
|
-
const query: Query<Metric> = { name: "cpu.usage" };
|
|
255
|
-
const returned: Query<Metric> =
|
|
256
|
-
MonitorStepMetricMonitorUtil.applyEntityScopeToQuery(query, step);
|
|
257
|
-
|
|
258
|
-
expect(returned).toBe(query);
|
|
259
|
-
expect(query.name).toBe("cpu.usage");
|
|
260
|
-
expectIncludes(query.entityKeys, TWO_KEYS);
|
|
261
|
-
});
|
|
262
|
-
|
|
263
|
-
test("fromJSON preserves entityKeys (pass-through serialization)", () => {
|
|
264
|
-
const step: MonitorStepMetricMonitor =
|
|
265
|
-
MonitorStepMetricMonitorUtil.getDefault();
|
|
266
|
-
step.entityKeys = TWO_KEYS;
|
|
267
|
-
|
|
268
|
-
const roundTripped: MonitorStepMetricMonitor =
|
|
269
|
-
MonitorStepMetricMonitorUtil.fromJSON(
|
|
270
|
-
MonitorStepMetricMonitorUtil.toJSON(step),
|
|
271
|
-
);
|
|
272
|
-
|
|
273
|
-
expect(roundTripped.entityKeys).toEqual(TWO_KEYS);
|
|
274
|
-
});
|
|
275
|
-
});
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import Metric from "../../Models/AnalyticsModels/Metric";
|
|
2
|
-
import Includes from "../BaseDatabase/Includes";
|
|
3
|
-
import Query from "../BaseDatabase/Query";
|
|
4
1
|
import { JSONObject } from "../JSON";
|
|
5
2
|
import MetricsViewConfig from "../Metrics/MetricsViewConfig";
|
|
6
3
|
import RollingTime from "../RollingTime/RollingTime";
|
|
@@ -8,13 +5,6 @@ import RollingTime from "../RollingTime/RollingTime";
|
|
|
8
5
|
export default interface MonitorStepMetricMonitor {
|
|
9
6
|
metricViewConfig: MetricsViewConfig;
|
|
10
7
|
rollingTime: RollingTime;
|
|
11
|
-
/*
|
|
12
|
-
* Stable telemetry entity keys (host / pod / container / ...) — scopes
|
|
13
|
-
* every metric query in this step to rows carrying any of these in their
|
|
14
|
-
* entityKeys column. Optional: monitors saved before this field existed
|
|
15
|
-
* have it undefined.
|
|
16
|
-
*/
|
|
17
|
-
entityKeys?: Array<string> | undefined;
|
|
18
8
|
}
|
|
19
9
|
|
|
20
10
|
export class MonitorStepMetricMonitorUtil {
|
|
@@ -25,26 +15,9 @@ export class MonitorStepMetricMonitorUtil {
|
|
|
25
15
|
formulaConfigs: [],
|
|
26
16
|
},
|
|
27
17
|
rollingTime: RollingTime.Past1Minute,
|
|
28
|
-
entityKeys: [],
|
|
29
18
|
};
|
|
30
19
|
}
|
|
31
20
|
|
|
32
|
-
/*
|
|
33
|
-
* Stamps the step's entity scope onto a per-queryConfig Query<Metric>.
|
|
34
|
-
* Compiles to hasAny(entityKeys, [...]) server-side. Undefined/empty is
|
|
35
|
-
* a no-op so monitors saved before the field existed are unaffected.
|
|
36
|
-
*/
|
|
37
|
-
public static applyEntityScopeToQuery(
|
|
38
|
-
query: Query<Metric>,
|
|
39
|
-
monitor: MonitorStepMetricMonitor,
|
|
40
|
-
): Query<Metric> {
|
|
41
|
-
if (monitor.entityKeys && monitor.entityKeys.length > 0) {
|
|
42
|
-
query.entityKeys = new Includes(monitor.entityKeys);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return query;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
21
|
public static fromJSON(json: JSONObject): MonitorStepMetricMonitor {
|
|
49
22
|
return json as any as MonitorStepMetricMonitor;
|
|
50
23
|
}
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import AnalyticsBaseModel from "./AnalyticsBaseModel/AnalyticsBaseModel";
|
|
2
|
+
import AnalyticsTableEngine from "../../Types/AnalyticsDatabase/AnalyticsTableEngine";
|
|
3
|
+
import AnalyticsTableName from "../../Types/AnalyticsDatabase/AnalyticsTableName";
|
|
4
|
+
import AnalyticsTableColumn, { SkipIndexType, } from "../../Types/AnalyticsDatabase/TableColumn";
|
|
5
|
+
import TableColumnType from "../../Types/AnalyticsDatabase/TableColumnType";
|
|
6
|
+
export default class MutableMetric extends AnalyticsBaseModel {
|
|
7
|
+
constructor() {
|
|
8
|
+
const projectIdColumn = new AnalyticsTableColumn({
|
|
9
|
+
key: "projectId",
|
|
10
|
+
title: "Project ID",
|
|
11
|
+
description: "ID of project",
|
|
12
|
+
required: true,
|
|
13
|
+
type: TableColumnType.ObjectID,
|
|
14
|
+
isTenantId: true,
|
|
15
|
+
});
|
|
16
|
+
const primaryEntityIdColumn = new AnalyticsTableColumn({
|
|
17
|
+
key: "primaryEntityId",
|
|
18
|
+
title: "Primary Entity ID",
|
|
19
|
+
description: "ID of the incident, alert, or other entity.",
|
|
20
|
+
required: true,
|
|
21
|
+
type: TableColumnType.ObjectID,
|
|
22
|
+
});
|
|
23
|
+
const primaryEntityTypeColumn = new AnalyticsTableColumn({
|
|
24
|
+
key: "primaryEntityType",
|
|
25
|
+
isLowCardinality: true,
|
|
26
|
+
title: "Primary Entity Type",
|
|
27
|
+
description: "Type of the primary entity.",
|
|
28
|
+
required: true,
|
|
29
|
+
type: TableColumnType.Text,
|
|
30
|
+
skipIndex: {
|
|
31
|
+
name: "idx_mutable_metric_entity_type",
|
|
32
|
+
type: SkipIndexType.Set,
|
|
33
|
+
params: [10],
|
|
34
|
+
granularity: 4,
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
const nameColumn = new AnalyticsTableColumn({
|
|
38
|
+
key: "name",
|
|
39
|
+
codec: { codec: "ZSTD", level: 1 },
|
|
40
|
+
title: "Name",
|
|
41
|
+
description: "Name of the metric.",
|
|
42
|
+
required: true,
|
|
43
|
+
type: TableColumnType.Text,
|
|
44
|
+
skipIndex: {
|
|
45
|
+
name: "idx_mutable_metric_name",
|
|
46
|
+
type: SkipIndexType.BloomFilter,
|
|
47
|
+
params: [0.01],
|
|
48
|
+
granularity: 1,
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
const metricPointIdColumn = new AnalyticsTableColumn({
|
|
52
|
+
key: "metricPointId",
|
|
53
|
+
codec: { codec: "ZSTD", level: 1 },
|
|
54
|
+
title: "Metric Point ID",
|
|
55
|
+
description: "Stable identity for the mutable metric point within its entity and metric name.",
|
|
56
|
+
required: true,
|
|
57
|
+
type: TableColumnType.Text,
|
|
58
|
+
});
|
|
59
|
+
const metricPointTypeColumn = new AnalyticsTableColumn({
|
|
60
|
+
key: "metricPointType",
|
|
61
|
+
isLowCardinality: true,
|
|
62
|
+
title: "Metric Point Type",
|
|
63
|
+
description: "Metric point type.",
|
|
64
|
+
required: false,
|
|
65
|
+
type: TableColumnType.Text,
|
|
66
|
+
skipIndex: {
|
|
67
|
+
name: "idx_mutable_metric_point_type",
|
|
68
|
+
type: SkipIndexType.Set,
|
|
69
|
+
params: [5],
|
|
70
|
+
granularity: 4,
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
const timeColumn = new AnalyticsTableColumn({
|
|
74
|
+
key: "time",
|
|
75
|
+
codec: [{ codec: "DoubleDelta" }, { codec: "ZSTD", level: 1 }],
|
|
76
|
+
title: "Time",
|
|
77
|
+
description: "When this metric point happened.",
|
|
78
|
+
required: true,
|
|
79
|
+
type: TableColumnType.DateTime64,
|
|
80
|
+
});
|
|
81
|
+
const timeUnixNanoColumn = new AnalyticsTableColumn({
|
|
82
|
+
key: "timeUnixNano",
|
|
83
|
+
codec: [{ codec: "DoubleDelta" }, { codec: "ZSTD", level: 1 }],
|
|
84
|
+
title: "Time (in Unix Nano)",
|
|
85
|
+
description: "When this metric point happened.",
|
|
86
|
+
required: true,
|
|
87
|
+
type: TableColumnType.UInt64,
|
|
88
|
+
});
|
|
89
|
+
const attributesColumn = new AnalyticsTableColumn({
|
|
90
|
+
key: "attributes",
|
|
91
|
+
codec: { codec: "ZSTD", level: 3 },
|
|
92
|
+
title: "Attributes",
|
|
93
|
+
description: "Metric attributes.",
|
|
94
|
+
required: true,
|
|
95
|
+
type: TableColumnType.MapStringString,
|
|
96
|
+
defaultValue: {},
|
|
97
|
+
mapKeysColumn: "attributeKeys",
|
|
98
|
+
});
|
|
99
|
+
const attributeKeysColumn = new AnalyticsTableColumn({
|
|
100
|
+
key: "attributeKeys",
|
|
101
|
+
codec: { codec: "ZSTD", level: 3 },
|
|
102
|
+
title: "Attribute Keys",
|
|
103
|
+
description: "Attribute keys extracted from attributes.",
|
|
104
|
+
required: true,
|
|
105
|
+
defaultValue: [],
|
|
106
|
+
type: TableColumnType.ArrayText,
|
|
107
|
+
skipIndex: {
|
|
108
|
+
name: "idx_mutable_metric_attribute_keys",
|
|
109
|
+
type: SkipIndexType.BloomFilter,
|
|
110
|
+
params: [0.01],
|
|
111
|
+
granularity: 1,
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
const valueColumn = new AnalyticsTableColumn({
|
|
115
|
+
key: "value",
|
|
116
|
+
codec: [{ codec: "Gorilla" }, { codec: "ZSTD", level: 1 }],
|
|
117
|
+
title: "Value",
|
|
118
|
+
description: "Metric value.",
|
|
119
|
+
required: false,
|
|
120
|
+
type: TableColumnType.Decimal,
|
|
121
|
+
});
|
|
122
|
+
const versionColumn = new AnalyticsTableColumn({
|
|
123
|
+
key: "version",
|
|
124
|
+
codec: [{ codec: "DoubleDelta" }, { codec: "ZSTD", level: 1 }],
|
|
125
|
+
title: "Version",
|
|
126
|
+
description: "Monotonic version for ReplacingMergeTree and version-aware reads.",
|
|
127
|
+
required: true,
|
|
128
|
+
type: TableColumnType.UInt64,
|
|
129
|
+
});
|
|
130
|
+
const isDeletedColumn = new AnalyticsTableColumn({
|
|
131
|
+
key: "isDeleted",
|
|
132
|
+
title: "Is Deleted",
|
|
133
|
+
description: "Tombstone marker for this metric point identity.",
|
|
134
|
+
required: true,
|
|
135
|
+
type: TableColumnType.Boolean,
|
|
136
|
+
defaultValue: false,
|
|
137
|
+
});
|
|
138
|
+
const retentionDateColumn = new AnalyticsTableColumn({
|
|
139
|
+
key: "retentionDate",
|
|
140
|
+
codec: [{ codec: "DoubleDelta" }, { codec: "ZSTD", level: 1 }],
|
|
141
|
+
title: "Retention Date",
|
|
142
|
+
description: "Date after which this row is eligible for TTL deletion.",
|
|
143
|
+
required: true,
|
|
144
|
+
type: TableColumnType.Date,
|
|
145
|
+
});
|
|
146
|
+
super({
|
|
147
|
+
tableName: AnalyticsTableName.MutableMetric,
|
|
148
|
+
tableEngine: AnalyticsTableEngine.ReplacingMergeTree,
|
|
149
|
+
singularName: "Mutable Metric",
|
|
150
|
+
pluralName: "Mutable Metrics",
|
|
151
|
+
tableDescription: "Versioned derived metric points for lifecycle metrics that can be corrected after initial emission.",
|
|
152
|
+
tableColumns: [
|
|
153
|
+
projectIdColumn,
|
|
154
|
+
primaryEntityIdColumn,
|
|
155
|
+
primaryEntityTypeColumn,
|
|
156
|
+
nameColumn,
|
|
157
|
+
metricPointIdColumn,
|
|
158
|
+
metricPointTypeColumn,
|
|
159
|
+
timeColumn,
|
|
160
|
+
timeUnixNanoColumn,
|
|
161
|
+
attributesColumn,
|
|
162
|
+
attributeKeysColumn,
|
|
163
|
+
valueColumn,
|
|
164
|
+
versionColumn,
|
|
165
|
+
isDeletedColumn,
|
|
166
|
+
retentionDateColumn,
|
|
167
|
+
],
|
|
168
|
+
projections: [],
|
|
169
|
+
sortKeys: [
|
|
170
|
+
"projectId",
|
|
171
|
+
"name",
|
|
172
|
+
"primaryEntityType",
|
|
173
|
+
"primaryEntityId",
|
|
174
|
+
"metricPointId",
|
|
175
|
+
],
|
|
176
|
+
primaryKeys: [
|
|
177
|
+
"projectId",
|
|
178
|
+
"name",
|
|
179
|
+
"primaryEntityType",
|
|
180
|
+
"primaryEntityId",
|
|
181
|
+
"metricPointId",
|
|
182
|
+
],
|
|
183
|
+
partitionKey: "toYYYYMM(retentionDate)",
|
|
184
|
+
shardingKey: "cityHash64(projectId, name, primaryEntityType, primaryEntityId, metricPointId)",
|
|
185
|
+
tableSettings: "ttl_only_drop_parts = 1, non_replicated_deduplication_window = 10000",
|
|
186
|
+
ttlExpression: "retentionDate DELETE",
|
|
187
|
+
defaultSortColumn: "time",
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
get projectId() {
|
|
191
|
+
return this.getColumnValue("projectId");
|
|
192
|
+
}
|
|
193
|
+
set projectId(v) {
|
|
194
|
+
this.setColumnValue("projectId", v);
|
|
195
|
+
}
|
|
196
|
+
get primaryEntityId() {
|
|
197
|
+
return this.getColumnValue("primaryEntityId");
|
|
198
|
+
}
|
|
199
|
+
set primaryEntityId(v) {
|
|
200
|
+
this.setColumnValue("primaryEntityId", v);
|
|
201
|
+
}
|
|
202
|
+
get primaryEntityType() {
|
|
203
|
+
return this.getColumnValue("primaryEntityType");
|
|
204
|
+
}
|
|
205
|
+
set primaryEntityType(v) {
|
|
206
|
+
this.setColumnValue("primaryEntityType", v);
|
|
207
|
+
}
|
|
208
|
+
get name() {
|
|
209
|
+
return this.getColumnValue("name");
|
|
210
|
+
}
|
|
211
|
+
set name(v) {
|
|
212
|
+
this.setColumnValue("name", v);
|
|
213
|
+
}
|
|
214
|
+
get metricPointId() {
|
|
215
|
+
return this.getColumnValue("metricPointId");
|
|
216
|
+
}
|
|
217
|
+
set metricPointId(v) {
|
|
218
|
+
this.setColumnValue("metricPointId", v);
|
|
219
|
+
}
|
|
220
|
+
get metricPointType() {
|
|
221
|
+
return this.getColumnValue("metricPointType");
|
|
222
|
+
}
|
|
223
|
+
set metricPointType(v) {
|
|
224
|
+
this.setColumnValue("metricPointType", v);
|
|
225
|
+
}
|
|
226
|
+
get time() {
|
|
227
|
+
return this.getColumnValue("time");
|
|
228
|
+
}
|
|
229
|
+
set time(v) {
|
|
230
|
+
this.setColumnValue("time", v);
|
|
231
|
+
}
|
|
232
|
+
get timeUnixNano() {
|
|
233
|
+
return this.getColumnValue("timeUnixNano");
|
|
234
|
+
}
|
|
235
|
+
set timeUnixNano(v) {
|
|
236
|
+
this.setColumnValue("timeUnixNano", v);
|
|
237
|
+
}
|
|
238
|
+
get attributes() {
|
|
239
|
+
return this.getColumnValue("attributes");
|
|
240
|
+
}
|
|
241
|
+
set attributes(v) {
|
|
242
|
+
this.setColumnValue("attributes", v);
|
|
243
|
+
}
|
|
244
|
+
get attributeKeys() {
|
|
245
|
+
return this.getColumnValue("attributeKeys");
|
|
246
|
+
}
|
|
247
|
+
set attributeKeys(v) {
|
|
248
|
+
this.setColumnValue("attributeKeys", v);
|
|
249
|
+
}
|
|
250
|
+
get value() {
|
|
251
|
+
return this.getColumnValue("value");
|
|
252
|
+
}
|
|
253
|
+
set value(v) {
|
|
254
|
+
this.setColumnValue("value", v);
|
|
255
|
+
}
|
|
256
|
+
get version() {
|
|
257
|
+
return this.getColumnValue("version");
|
|
258
|
+
}
|
|
259
|
+
set version(v) {
|
|
260
|
+
this.setColumnValue("version", v);
|
|
261
|
+
}
|
|
262
|
+
get isDeleted() {
|
|
263
|
+
return this.getColumnValue("isDeleted");
|
|
264
|
+
}
|
|
265
|
+
set isDeleted(v) {
|
|
266
|
+
this.setColumnValue("isDeleted", v);
|
|
267
|
+
}
|
|
268
|
+
get retentionDate() {
|
|
269
|
+
return this.getColumnValue("retentionDate");
|
|
270
|
+
}
|
|
271
|
+
set retentionDate(v) {
|
|
272
|
+
this.setColumnValue("retentionDate", v);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
//# sourceMappingURL=MutableMetric.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MutableMetric.js","sourceRoot":"","sources":["../../../../Models/AnalyticsModels/MutableMetric.ts"],"names":[],"mappings":"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"}
|