@oneuptime/common 10.0.72 → 10.0.75
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/DatabaseModels/Project.ts +26 -0
- package/Models/DatabaseModels/Service.ts +2 -2
- package/Server/Infrastructure/Postgres/SchemaMigrations/1777018175127-AddTelemetryRetentionSettings.ts +25 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +2 -0
- package/Server/Services/OpenTelemetryIngestService.ts +36 -5
- package/Server/Services/ServiceService.ts +27 -1
- package/Server/Utils/Monitor/MonitorAlert.ts +0 -78
- package/Server/Utils/Monitor/MonitorIncident.ts +0 -78
- package/Types/AdminDashboard/AdminDashboardLanguage.ts +33 -0
- package/Types/Dashboard/DashboardLanguage.ts +30 -0
- package/Types/StatusPage/StatusPageLanguage.ts +1 -0
- package/build/dist/Models/DatabaseModels/Project.js +27 -0
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Service.js +1 -2
- package/build/dist/Models/DatabaseModels/Service.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1777018175127-AddTelemetryRetentionSettings.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1777018175127-AddTelemetryRetentionSettings.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +2 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/OpenTelemetryIngestService.js +30 -4
- package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
- package/build/dist/Server/Services/ServiceService.js +22 -1
- package/build/dist/Server/Services/ServiceService.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +0 -67
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +0 -67
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Types/AdminDashboard/AdminDashboardLanguage.js +22 -0
- package/build/dist/Types/AdminDashboard/AdminDashboardLanguage.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardLanguage.js +22 -0
- package/build/dist/Types/Dashboard/DashboardLanguage.js.map +1 -0
- package/build/dist/Types/StatusPage/StatusPageLanguage.js +1 -0
- package/build/dist/Types/StatusPage/StatusPageLanguage.js.map +1 -1
- package/package.json +1 -1
|
@@ -2049,6 +2049,32 @@ export default class Project extends TenantModel {
|
|
|
2049
2049
|
})
|
|
2050
2050
|
public defaultMetricCardinalityBudget?: number = undefined;
|
|
2051
2051
|
|
|
2052
|
+
@ColumnAccessControl({
|
|
2053
|
+
create: [],
|
|
2054
|
+
read: [
|
|
2055
|
+
Permission.ProjectOwner,
|
|
2056
|
+
Permission.ProjectAdmin,
|
|
2057
|
+
Permission.ProjectMember,
|
|
2058
|
+
Permission.Viewer,
|
|
2059
|
+
Permission.ReadProject,
|
|
2060
|
+
Permission.ReadAllProjectResources,
|
|
2061
|
+
],
|
|
2062
|
+
update: [Permission.ProjectOwner, Permission.ProjectAdmin],
|
|
2063
|
+
})
|
|
2064
|
+
@TableColumn({
|
|
2065
|
+
type: TableColumnType.Number,
|
|
2066
|
+
required: false,
|
|
2067
|
+
title: "Default Telemetry Data Retention (Days)",
|
|
2068
|
+
description:
|
|
2069
|
+
"Project-wide default number of days to retain telemetry data (logs, traces, metrics). Services without a per-service override use this value.",
|
|
2070
|
+
})
|
|
2071
|
+
@Column({
|
|
2072
|
+
type: ColumnType.Number,
|
|
2073
|
+
nullable: false,
|
|
2074
|
+
default: 15,
|
|
2075
|
+
})
|
|
2076
|
+
public defaultTelemetryRetentionInDays?: number = undefined;
|
|
2077
|
+
|
|
2052
2078
|
@ColumnAccessControl({
|
|
2053
2079
|
create: [],
|
|
2054
2080
|
read: [
|
|
@@ -627,13 +627,13 @@ export default class Service extends BaseModel {
|
|
|
627
627
|
@TableColumn({
|
|
628
628
|
type: TableColumnType.Number,
|
|
629
629
|
title: "Retain Telemetry Data For Days",
|
|
630
|
-
description:
|
|
630
|
+
description:
|
|
631
|
+
"Number of days to retain telemetry data for this service. Leave blank to use the project-wide default.",
|
|
631
632
|
})
|
|
632
633
|
@Column({
|
|
633
634
|
type: ColumnType.Number,
|
|
634
635
|
nullable: true,
|
|
635
636
|
unique: false,
|
|
636
|
-
default: 15,
|
|
637
637
|
})
|
|
638
638
|
public retainTelemetryDataForDays?: number = undefined;
|
|
639
639
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
export class AddTelemetryRetentionSettings1777018175127
|
|
4
|
+
implements MigrationInterface
|
|
5
|
+
{
|
|
6
|
+
public name = "AddTelemetryRetentionSettings1777018175127";
|
|
7
|
+
|
|
8
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
9
|
+
await queryRunner.query(
|
|
10
|
+
`ALTER TABLE "Project" ADD COLUMN IF NOT EXISTS "defaultTelemetryRetentionInDays" integer NOT NULL DEFAULT '15'`,
|
|
11
|
+
);
|
|
12
|
+
await queryRunner.query(
|
|
13
|
+
`ALTER TABLE "Service" ALTER COLUMN "retainTelemetryDataForDays" DROP DEFAULT`,
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
18
|
+
await queryRunner.query(
|
|
19
|
+
`ALTER TABLE "Service" ALTER COLUMN "retainTelemetryDataForDays" SET DEFAULT '15'`,
|
|
20
|
+
);
|
|
21
|
+
await queryRunner.query(
|
|
22
|
+
`ALTER TABLE "Project" DROP COLUMN IF EXISTS "defaultTelemetryRetentionInDays"`,
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -291,6 +291,7 @@ import { MigrationName1776865086264 } from "./1776865086264-MigrationName";
|
|
|
291
291
|
import { DedupeKubernetesClustersAndAddUniqueIndex1776881254913 } from "./1776881254913-DedupeKubernetesClustersAndAddUniqueIndex";
|
|
292
292
|
import { MigrationName1776940714709 } from "./1776940714709-MigrationName";
|
|
293
293
|
import { AddStatusPageLanguageSettings1776971364783 } from "./1776971364783-AddStatusPageLanguageSettings";
|
|
294
|
+
import { AddTelemetryRetentionSettings1777018175127 } from "./1777018175127-AddTelemetryRetentionSettings";
|
|
294
295
|
export default [
|
|
295
296
|
InitialMigration,
|
|
296
297
|
MigrationName1717678334852,
|
|
@@ -585,4 +586,5 @@ export default [
|
|
|
585
586
|
DedupeKubernetesClustersAndAddUniqueIndex1776881254913,
|
|
586
587
|
MigrationName1776940714709,
|
|
587
588
|
AddStatusPageLanguageSettings1776971364783,
|
|
589
|
+
AddTelemetryRetentionSettings1777018175127,
|
|
588
590
|
];
|
|
@@ -4,7 +4,9 @@ import ObjectID from "../../Types/ObjectID";
|
|
|
4
4
|
import Metric, {
|
|
5
5
|
AggregationTemporality,
|
|
6
6
|
} from "../../Models/AnalyticsModels/Metric";
|
|
7
|
+
import Project from "../../Models/DatabaseModels/Project";
|
|
7
8
|
import Service from "../../Models/DatabaseModels/Service";
|
|
9
|
+
import ProjectService from "../../Server/Services/ProjectService";
|
|
8
10
|
import ServiceService from "../../Server/Services/ServiceService";
|
|
9
11
|
import { DEFAULT_RETENTION_IN_DAYS } from "../../Models/DatabaseModels/TelemetryUsageBilling";
|
|
10
12
|
import TelemetryUtil from "../../Server/Utils/Telemetry/Telemetry";
|
|
@@ -22,6 +24,25 @@ export interface TelemetryServiceMetadata {
|
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
export default class OTelIngestService {
|
|
27
|
+
@CaptureSpan()
|
|
28
|
+
private static async getProjectDefaultRetentionInDays(
|
|
29
|
+
projectId: ObjectID,
|
|
30
|
+
): Promise<number> {
|
|
31
|
+
const project: Project | null = await ProjectService.findOneById({
|
|
32
|
+
id: projectId,
|
|
33
|
+
select: {
|
|
34
|
+
defaultTelemetryRetentionInDays: true,
|
|
35
|
+
},
|
|
36
|
+
props: {
|
|
37
|
+
isRoot: true,
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
project?.defaultTelemetryRetentionInDays || DEFAULT_RETENTION_IN_DAYS
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
25
46
|
@CaptureSpan()
|
|
26
47
|
public static async telemetryServiceFromName(data: {
|
|
27
48
|
serviceName: string;
|
|
@@ -45,12 +66,14 @@ export default class OTelIngestService {
|
|
|
45
66
|
});
|
|
46
67
|
|
|
47
68
|
if (!service) {
|
|
69
|
+
const projectDefaultRetention: number =
|
|
70
|
+
await this.getProjectDefaultRetentionInDays(data.projectId);
|
|
71
|
+
|
|
48
72
|
try {
|
|
49
73
|
const newService: Service = new Service();
|
|
50
74
|
newService.projectId = data.projectId;
|
|
51
75
|
newService.name = data.serviceName;
|
|
52
76
|
newService.description = data.serviceName;
|
|
53
|
-
newService.retainTelemetryDataForDays = DEFAULT_RETENTION_IN_DAYS;
|
|
54
77
|
|
|
55
78
|
const createdService: Service = await ServiceService.create({
|
|
56
79
|
data: newService,
|
|
@@ -61,7 +84,7 @@ export default class OTelIngestService {
|
|
|
61
84
|
|
|
62
85
|
return {
|
|
63
86
|
serviceId: createdService.id!,
|
|
64
|
-
dataRententionInDays:
|
|
87
|
+
dataRententionInDays: projectDefaultRetention,
|
|
65
88
|
};
|
|
66
89
|
} catch {
|
|
67
90
|
/*
|
|
@@ -87,7 +110,7 @@ export default class OTelIngestService {
|
|
|
87
110
|
serviceId: existingService.id!,
|
|
88
111
|
dataRententionInDays:
|
|
89
112
|
existingService.retainTelemetryDataForDays ||
|
|
90
|
-
|
|
113
|
+
projectDefaultRetention,
|
|
91
114
|
};
|
|
92
115
|
}
|
|
93
116
|
|
|
@@ -97,10 +120,18 @@ export default class OTelIngestService {
|
|
|
97
120
|
}
|
|
98
121
|
}
|
|
99
122
|
|
|
123
|
+
if (service.retainTelemetryDataForDays) {
|
|
124
|
+
return {
|
|
125
|
+
serviceId: service.id!,
|
|
126
|
+
dataRententionInDays: service.retainTelemetryDataForDays,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
100
130
|
return {
|
|
101
131
|
serviceId: service.id!,
|
|
102
|
-
dataRententionInDays:
|
|
103
|
-
|
|
132
|
+
dataRententionInDays: await this.getProjectDefaultRetentionInDays(
|
|
133
|
+
data.projectId,
|
|
134
|
+
),
|
|
104
135
|
};
|
|
105
136
|
}
|
|
106
137
|
@CaptureSpan()
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import CreateBy from "../Types/Database/CreateBy";
|
|
2
2
|
import { OnCreate } from "../Types/Database/Hooks";
|
|
3
3
|
import DatabaseService from "./DatabaseService";
|
|
4
|
+
import ProjectService from "./ProjectService";
|
|
4
5
|
import ArrayUtil from "../../Utils/Array";
|
|
5
6
|
import { BrightColors } from "../../Types/BrandColors";
|
|
6
7
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
7
8
|
import ObjectID from "../../Types/ObjectID";
|
|
8
9
|
import Model from "../../Models/DatabaseModels/Service";
|
|
10
|
+
import Project from "../../Models/DatabaseModels/Project";
|
|
9
11
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
10
12
|
|
|
13
|
+
const DEFAULT_TELEMETRY_RETENTION_IN_DAYS: number = 15;
|
|
14
|
+
|
|
11
15
|
export class Service extends DatabaseService<Model> {
|
|
12
16
|
public constructor() {
|
|
13
17
|
super(Model);
|
|
@@ -33,6 +37,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
33
37
|
const service: Model | null = await this.findOneById({
|
|
34
38
|
id: serviceId,
|
|
35
39
|
select: {
|
|
40
|
+
projectId: true,
|
|
36
41
|
retainTelemetryDataForDays: true,
|
|
37
42
|
},
|
|
38
43
|
props: {
|
|
@@ -44,7 +49,28 @@ export class Service extends DatabaseService<Model> {
|
|
|
44
49
|
throw new BadDataException("Service not found");
|
|
45
50
|
}
|
|
46
51
|
|
|
47
|
-
|
|
52
|
+
if (service.retainTelemetryDataForDays) {
|
|
53
|
+
return service.retainTelemetryDataForDays;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Fall back to project-level default.
|
|
57
|
+
if (service.projectId) {
|
|
58
|
+
const project: Project | null = await ProjectService.findOneById({
|
|
59
|
+
id: service.projectId,
|
|
60
|
+
select: {
|
|
61
|
+
defaultTelemetryRetentionInDays: true,
|
|
62
|
+
},
|
|
63
|
+
props: {
|
|
64
|
+
isRoot: true,
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
if (project?.defaultTelemetryRetentionInDays) {
|
|
69
|
+
return project.defaultTelemetryRetentionInDays;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return DEFAULT_TELEMETRY_RETENTION_IN_DAYS;
|
|
48
74
|
}
|
|
49
75
|
}
|
|
50
76
|
|
|
@@ -16,9 +16,7 @@ import { TelemetryQuery } from "../../../Types/Telemetry/TelemetryQuery";
|
|
|
16
16
|
import { DisableAutomaticAlertCreation } from "../../EnvironmentConfig";
|
|
17
17
|
import AlertService from "../../Services/AlertService";
|
|
18
18
|
import AlertSeverityService from "../../Services/AlertSeverityService";
|
|
19
|
-
import AlertStateService from "../../Services/AlertStateService";
|
|
20
19
|
import AlertStateTimelineService from "../../Services/AlertStateTimelineService";
|
|
21
|
-
import AlertState from "../../../Models/DatabaseModels/AlertState";
|
|
22
20
|
import logger, { LogAttributes } from "../Logger";
|
|
23
21
|
import CaptureSpan from "../Telemetry/CaptureSpan";
|
|
24
22
|
import DataToProcess from "./DataToProcess";
|
|
@@ -372,82 +370,6 @@ export default class MonitorAlert {
|
|
|
372
370
|
input.openAlert.projectId!,
|
|
373
371
|
);
|
|
374
372
|
|
|
375
|
-
/*
|
|
376
|
-
* Skip the Resolved insert if the alert's timeline is already at or past
|
|
377
|
-
* the Resolved state in the project's workflow order. Two cases:
|
|
378
|
-
* 1. Latest timeline state is Resolved but Alert.currentAlertStateId is
|
|
379
|
-
* stuck on an earlier state (partial-failure from a prior resolve).
|
|
380
|
-
* Re-inserting Resolved would throw "Alert state cannot be same as
|
|
381
|
-
* previous state" from AlertStateTimelineService.onBeforeCreate.
|
|
382
|
-
* 2. The project defines a custom state after Resolved (e.g. Closed) and
|
|
383
|
-
* the alert has moved into it. Inserting Resolved would throw
|
|
384
|
-
* "cannot transition to Resolved from Closed because Resolved is
|
|
385
|
-
* before Closed in the order of alert states."
|
|
386
|
-
* Either failure bubbles up through ingest workers and causes monitors to
|
|
387
|
-
* flap. Reconcile Alert.currentAlertStateId if out of sync with the
|
|
388
|
-
* timeline, then return.
|
|
389
|
-
*/
|
|
390
|
-
const [resolvedState, latestTimeline]: [
|
|
391
|
-
AlertState | null,
|
|
392
|
-
AlertStateTimeline | null,
|
|
393
|
-
] = await Promise.all([
|
|
394
|
-
AlertStateService.findOneBy({
|
|
395
|
-
query: {
|
|
396
|
-
_id: resolvedStateId.toString(),
|
|
397
|
-
},
|
|
398
|
-
select: {
|
|
399
|
-
order: true,
|
|
400
|
-
},
|
|
401
|
-
props: {
|
|
402
|
-
isRoot: true,
|
|
403
|
-
},
|
|
404
|
-
}),
|
|
405
|
-
AlertStateTimelineService.findOneBy({
|
|
406
|
-
query: {
|
|
407
|
-
alertId: input.openAlert.id!,
|
|
408
|
-
},
|
|
409
|
-
sort: {
|
|
410
|
-
startsAt: SortOrder.Descending,
|
|
411
|
-
},
|
|
412
|
-
select: {
|
|
413
|
-
alertStateId: true,
|
|
414
|
-
alertState: {
|
|
415
|
-
order: true,
|
|
416
|
-
},
|
|
417
|
-
},
|
|
418
|
-
props: {
|
|
419
|
-
isRoot: true,
|
|
420
|
-
},
|
|
421
|
-
}),
|
|
422
|
-
]);
|
|
423
|
-
|
|
424
|
-
const latestOrder: number | undefined | null =
|
|
425
|
-
latestTimeline?.alertState?.order;
|
|
426
|
-
const resolvedOrder: number | undefined | null = resolvedState?.order;
|
|
427
|
-
|
|
428
|
-
if (
|
|
429
|
-
latestTimeline?.alertStateId &&
|
|
430
|
-
typeof latestOrder === "number" &&
|
|
431
|
-
typeof resolvedOrder === "number" &&
|
|
432
|
-
latestOrder >= resolvedOrder
|
|
433
|
-
) {
|
|
434
|
-
if (
|
|
435
|
-
input.openAlert.currentAlertStateId?.toString() !==
|
|
436
|
-
latestTimeline.alertStateId.toString()
|
|
437
|
-
) {
|
|
438
|
-
await AlertService.updateOneById({
|
|
439
|
-
id: input.openAlert.id!,
|
|
440
|
-
data: {
|
|
441
|
-
currentAlertStateId: latestTimeline.alertStateId,
|
|
442
|
-
},
|
|
443
|
-
props: {
|
|
444
|
-
isRoot: true,
|
|
445
|
-
},
|
|
446
|
-
});
|
|
447
|
-
}
|
|
448
|
-
return;
|
|
449
|
-
}
|
|
450
|
-
|
|
451
373
|
const alertStateTimeline: AlertStateTimeline = new AlertStateTimeline();
|
|
452
374
|
alertStateTimeline.alertId = input.openAlert.id!;
|
|
453
375
|
alertStateTimeline.alertStateId = resolvedStateId;
|
|
@@ -17,10 +17,8 @@ import { TelemetryQuery } from "../../../Types/Telemetry/TelemetryQuery";
|
|
|
17
17
|
import { DisableAutomaticIncidentCreation } from "../../EnvironmentConfig";
|
|
18
18
|
import IncidentService from "../../Services/IncidentService";
|
|
19
19
|
import IncidentSeverityService from "../../Services/IncidentSeverityService";
|
|
20
|
-
import IncidentStateService from "../../Services/IncidentStateService";
|
|
21
20
|
import IncidentStateTimelineService from "../../Services/IncidentStateTimelineService";
|
|
22
21
|
import IncidentMemberService from "../../Services/IncidentMemberService";
|
|
23
|
-
import IncidentState from "../../../Models/DatabaseModels/IncidentState";
|
|
24
22
|
import logger, { LogAttributes } from "../Logger";
|
|
25
23
|
import CaptureSpan from "../Telemetry/CaptureSpan";
|
|
26
24
|
import DataToProcess from "./DataToProcess";
|
|
@@ -468,82 +466,6 @@ export default class MonitorIncident {
|
|
|
468
466
|
input.openIncident.projectId!,
|
|
469
467
|
);
|
|
470
468
|
|
|
471
|
-
/*
|
|
472
|
-
* Skip the Resolved insert if the incident's timeline is already at or
|
|
473
|
-
* past the Resolved state in the project's workflow order. Two cases:
|
|
474
|
-
* 1. Latest timeline state is Resolved but Incident.currentIncidentStateId
|
|
475
|
-
* is stuck on an earlier state (partial-failure from a prior resolve).
|
|
476
|
-
* Re-inserting Resolved would throw "state cannot be same as previous"
|
|
477
|
-
* from IncidentStateTimelineService.onBeforeCreate.
|
|
478
|
-
* 2. The project defines a custom state after Resolved (e.g. Closed) and
|
|
479
|
-
* the incident has moved into it. Inserting Resolved would throw
|
|
480
|
-
* "cannot transition to Resolved from Closed because Resolved is
|
|
481
|
-
* before Closed in the order of incident states."
|
|
482
|
-
* Either failure bubbles up through ingest workers and causes monitors to
|
|
483
|
-
* flap. Reconcile Incident.currentIncidentStateId if out of sync with the
|
|
484
|
-
* timeline, then return.
|
|
485
|
-
*/
|
|
486
|
-
const [resolvedState, latestTimeline]: [
|
|
487
|
-
IncidentState | null,
|
|
488
|
-
IncidentStateTimeline | null,
|
|
489
|
-
] = await Promise.all([
|
|
490
|
-
IncidentStateService.findOneBy({
|
|
491
|
-
query: {
|
|
492
|
-
_id: resolvedStateId.toString(),
|
|
493
|
-
},
|
|
494
|
-
select: {
|
|
495
|
-
order: true,
|
|
496
|
-
},
|
|
497
|
-
props: {
|
|
498
|
-
isRoot: true,
|
|
499
|
-
},
|
|
500
|
-
}),
|
|
501
|
-
IncidentStateTimelineService.findOneBy({
|
|
502
|
-
query: {
|
|
503
|
-
incidentId: input.openIncident.id!,
|
|
504
|
-
},
|
|
505
|
-
sort: {
|
|
506
|
-
startsAt: SortOrder.Descending,
|
|
507
|
-
},
|
|
508
|
-
select: {
|
|
509
|
-
incidentStateId: true,
|
|
510
|
-
incidentState: {
|
|
511
|
-
order: true,
|
|
512
|
-
},
|
|
513
|
-
},
|
|
514
|
-
props: {
|
|
515
|
-
isRoot: true,
|
|
516
|
-
},
|
|
517
|
-
}),
|
|
518
|
-
]);
|
|
519
|
-
|
|
520
|
-
const latestOrder: number | undefined | null =
|
|
521
|
-
latestTimeline?.incidentState?.order;
|
|
522
|
-
const resolvedOrder: number | undefined | null = resolvedState?.order;
|
|
523
|
-
|
|
524
|
-
if (
|
|
525
|
-
latestTimeline?.incidentStateId &&
|
|
526
|
-
typeof latestOrder === "number" &&
|
|
527
|
-
typeof resolvedOrder === "number" &&
|
|
528
|
-
latestOrder >= resolvedOrder
|
|
529
|
-
) {
|
|
530
|
-
if (
|
|
531
|
-
input.openIncident.currentIncidentStateId?.toString() !==
|
|
532
|
-
latestTimeline.incidentStateId.toString()
|
|
533
|
-
) {
|
|
534
|
-
await IncidentService.updateOneById({
|
|
535
|
-
id: input.openIncident.id!,
|
|
536
|
-
data: {
|
|
537
|
-
currentIncidentStateId: latestTimeline.incidentStateId,
|
|
538
|
-
},
|
|
539
|
-
props: {
|
|
540
|
-
isRoot: true,
|
|
541
|
-
},
|
|
542
|
-
});
|
|
543
|
-
}
|
|
544
|
-
return;
|
|
545
|
-
}
|
|
546
|
-
|
|
547
469
|
const incidentStateTimeline: IncidentStateTimeline =
|
|
548
470
|
new IncidentStateTimeline();
|
|
549
471
|
incidentStateTimeline.incidentId = input.openIncident.id!;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface AdminDashboardLanguage {
|
|
2
|
+
code: string;
|
|
3
|
+
nativeName: string;
|
|
4
|
+
englishName: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export const DEFAULT_ADMIN_DASHBOARD_LANGUAGE: string = "en";
|
|
8
|
+
|
|
9
|
+
export const SUPPORTED_ADMIN_DASHBOARD_LANGUAGES: Array<AdminDashboardLanguage> =
|
|
10
|
+
[
|
|
11
|
+
{ code: "en", nativeName: "English", englishName: "English" },
|
|
12
|
+
{ code: "de", nativeName: "Deutsch", englishName: "German" },
|
|
13
|
+
{ code: "fr", nativeName: "Français", englishName: "French" },
|
|
14
|
+
{ code: "es", nativeName: "Español", englishName: "Spanish" },
|
|
15
|
+
{ code: "it", nativeName: "Italiano", englishName: "Italian" },
|
|
16
|
+
{ code: "pt", nativeName: "Português", englishName: "Portuguese" },
|
|
17
|
+
{ code: "nl", nativeName: "Nederlands", englishName: "Dutch" },
|
|
18
|
+
{ code: "da", nativeName: "Dansk", englishName: "Danish" },
|
|
19
|
+
{ code: "no", nativeName: "Norsk", englishName: "Norwegian" },
|
|
20
|
+
{ code: "sv", nativeName: "Svenska", englishName: "Swedish" },
|
|
21
|
+
{ code: "ru", nativeName: "Русский", englishName: "Russian" },
|
|
22
|
+
{ code: "ja", nativeName: "日本語", englishName: "Japanese" },
|
|
23
|
+
{ code: "ko", nativeName: "한국어", englishName: "Korean" },
|
|
24
|
+
{ code: "zh", nativeName: "中文", englishName: "Chinese" },
|
|
25
|
+
{ code: "hi", nativeName: "हिन्दी", englishName: "Hindi" },
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
export const SUPPORTED_ADMIN_DASHBOARD_LANGUAGE_CODES: Array<string> =
|
|
29
|
+
SUPPORTED_ADMIN_DASHBOARD_LANGUAGES.map(
|
|
30
|
+
(language: AdminDashboardLanguage) => {
|
|
31
|
+
return language.code;
|
|
32
|
+
},
|
|
33
|
+
);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface DashboardLanguage {
|
|
2
|
+
code: string;
|
|
3
|
+
nativeName: string;
|
|
4
|
+
englishName: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export const DEFAULT_DASHBOARD_LANGUAGE: string = "en";
|
|
8
|
+
|
|
9
|
+
export const SUPPORTED_DASHBOARD_LANGUAGES: Array<DashboardLanguage> = [
|
|
10
|
+
{ code: "en", nativeName: "English", englishName: "English" },
|
|
11
|
+
{ code: "de", nativeName: "Deutsch", englishName: "German" },
|
|
12
|
+
{ code: "fr", nativeName: "Français", englishName: "French" },
|
|
13
|
+
{ code: "es", nativeName: "Español", englishName: "Spanish" },
|
|
14
|
+
{ code: "it", nativeName: "Italiano", englishName: "Italian" },
|
|
15
|
+
{ code: "pt", nativeName: "Português", englishName: "Portuguese" },
|
|
16
|
+
{ code: "nl", nativeName: "Nederlands", englishName: "Dutch" },
|
|
17
|
+
{ code: "da", nativeName: "Dansk", englishName: "Danish" },
|
|
18
|
+
{ code: "no", nativeName: "Norsk", englishName: "Norwegian" },
|
|
19
|
+
{ code: "sv", nativeName: "Svenska", englishName: "Swedish" },
|
|
20
|
+
{ code: "ru", nativeName: "Русский", englishName: "Russian" },
|
|
21
|
+
{ code: "ja", nativeName: "日本語", englishName: "Japanese" },
|
|
22
|
+
{ code: "ko", nativeName: "한국어", englishName: "Korean" },
|
|
23
|
+
{ code: "zh", nativeName: "中文", englishName: "Chinese" },
|
|
24
|
+
{ code: "hi", nativeName: "हिन्दी", englishName: "Hindi" },
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
export const SUPPORTED_DASHBOARD_LANGUAGE_CODES: Array<string> =
|
|
28
|
+
SUPPORTED_DASHBOARD_LANGUAGES.map((language: DashboardLanguage) => {
|
|
29
|
+
return language.code;
|
|
30
|
+
});
|
|
@@ -21,6 +21,7 @@ export const SUPPORTED_STATUS_PAGE_LANGUAGES: Array<StatusPageLanguage> = [
|
|
|
21
21
|
{ code: "ja", nativeName: "日本語", englishName: "Japanese" },
|
|
22
22
|
{ code: "ko", nativeName: "한국어", englishName: "Korean" },
|
|
23
23
|
{ code: "zh", nativeName: "中文", englishName: "Chinese" },
|
|
24
|
+
{ code: "hi", nativeName: "हिन्दी", englishName: "Hindi" },
|
|
24
25
|
];
|
|
25
26
|
|
|
26
27
|
export const SUPPORTED_STATUS_PAGE_LANGUAGE_CODES: Array<string> =
|
|
@@ -126,6 +126,7 @@ let Project = class Project extends TenantModel {
|
|
|
126
126
|
// GitHub App Installation ID for this project
|
|
127
127
|
this.gitHubAppInstallationId = undefined;
|
|
128
128
|
this.defaultMetricCardinalityBudget = undefined;
|
|
129
|
+
this.defaultTelemetryRetentionInDays = undefined;
|
|
129
130
|
this.defaultMetricDownsamplingRetentionDays = undefined;
|
|
130
131
|
this.enableAuditLogs = undefined;
|
|
131
132
|
this.auditLogsRetentionInDays = undefined;
|
|
@@ -2141,6 +2142,32 @@ __decorate([
|
|
|
2141
2142
|
}),
|
|
2142
2143
|
__metadata("design:type", Number)
|
|
2143
2144
|
], Project.prototype, "defaultMetricCardinalityBudget", void 0);
|
|
2145
|
+
__decorate([
|
|
2146
|
+
ColumnAccessControl({
|
|
2147
|
+
create: [],
|
|
2148
|
+
read: [
|
|
2149
|
+
Permission.ProjectOwner,
|
|
2150
|
+
Permission.ProjectAdmin,
|
|
2151
|
+
Permission.ProjectMember,
|
|
2152
|
+
Permission.Viewer,
|
|
2153
|
+
Permission.ReadProject,
|
|
2154
|
+
Permission.ReadAllProjectResources,
|
|
2155
|
+
],
|
|
2156
|
+
update: [Permission.ProjectOwner, Permission.ProjectAdmin],
|
|
2157
|
+
}),
|
|
2158
|
+
TableColumn({
|
|
2159
|
+
type: TableColumnType.Number,
|
|
2160
|
+
required: false,
|
|
2161
|
+
title: "Default Telemetry Data Retention (Days)",
|
|
2162
|
+
description: "Project-wide default number of days to retain telemetry data (logs, traces, metrics). Services without a per-service override use this value.",
|
|
2163
|
+
}),
|
|
2164
|
+
Column({
|
|
2165
|
+
type: ColumnType.Number,
|
|
2166
|
+
nullable: false,
|
|
2167
|
+
default: 15,
|
|
2168
|
+
}),
|
|
2169
|
+
__metadata("design:type", Number)
|
|
2170
|
+
], Project.prototype, "defaultTelemetryRetentionInDays", void 0);
|
|
2144
2171
|
__decorate([
|
|
2145
2172
|
ColumnAccessControl({
|
|
2146
2173
|
create: [],
|