mirror of
https://github.com/OneUptime/oneuptime
synced 2024-11-21 22:59:07 +00:00
refactor: Add TelemetryExceptionStatusService to handle telemetry exception status in the database
This commit is contained in:
parent
a6a5f189c3
commit
2f3dbebe9a
@ -6,12 +6,13 @@ import TableColumnType from "../../Types/AnalyticsDatabase/TableColumnType";
|
|||||||
import ObjectID from "../../Types/ObjectID";
|
import ObjectID from "../../Types/ObjectID";
|
||||||
import Permission from "../../Types/Permission";
|
import Permission from "../../Types/Permission";
|
||||||
|
|
||||||
export default class Exception extends AnalyticsBaseModel {
|
export default class ExceptionInstance extends AnalyticsBaseModel {
|
||||||
public constructor() {
|
public constructor() {
|
||||||
super({
|
super({
|
||||||
tableName: "ExceptionTelemetry",
|
tableName: "ExceptionInstanceTelemetry",
|
||||||
tableEngine: AnalyticsTableEngine.MergeTree,
|
tableEngine: AnalyticsTableEngine.MergeTree,
|
||||||
singularName: "Exception",
|
singularName: "Exception",
|
||||||
|
pluralName: "Exceptions",
|
||||||
enableRealtimeEventsOn: {
|
enableRealtimeEventsOn: {
|
||||||
create: true,
|
create: true,
|
||||||
},
|
},
|
@ -4,7 +4,7 @@ import Metric from "./Metric";
|
|||||||
import MonitorMetricsByMinute from "./MonitorMetricsByMinute";
|
import MonitorMetricsByMinute from "./MonitorMetricsByMinute";
|
||||||
import Span from "./Span";
|
import Span from "./Span";
|
||||||
import TelemetryAttribute from "./TelemetryAttribute";
|
import TelemetryAttribute from "./TelemetryAttribute";
|
||||||
import Exception from "./Exception";
|
import ExceptionInstance from "./ExceptionInstance";
|
||||||
|
|
||||||
const AnalyticsModels: Array<typeof AnalyticsBaseModel> = [
|
const AnalyticsModels: Array<typeof AnalyticsBaseModel> = [
|
||||||
Log,
|
Log,
|
||||||
@ -12,7 +12,7 @@ const AnalyticsModels: Array<typeof AnalyticsBaseModel> = [
|
|||||||
Metric,
|
Metric,
|
||||||
MonitorMetricsByMinute,
|
MonitorMetricsByMinute,
|
||||||
TelemetryAttribute,
|
TelemetryAttribute,
|
||||||
Exception,
|
ExceptionInstance,
|
||||||
];
|
];
|
||||||
|
|
||||||
export default AnalyticsModels;
|
export default AnalyticsModels;
|
||||||
|
@ -135,7 +135,7 @@ import UserTwoFactorAuth from "./UserTwoFactorAuth";
|
|||||||
|
|
||||||
import TelemetryIngestionKey from "./TelemetryIngestionKey";
|
import TelemetryIngestionKey from "./TelemetryIngestionKey";
|
||||||
|
|
||||||
import TelemetryExceptionStatus from "./TelemetryExceptionStatus";
|
import TelemetryException from "./TelemetryException";
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
User,
|
User,
|
||||||
@ -292,5 +292,5 @@ export default [
|
|||||||
|
|
||||||
TelemetryIngestionKey,
|
TelemetryIngestionKey,
|
||||||
|
|
||||||
TelemetryExceptionStatus
|
TelemetryException,
|
||||||
];
|
];
|
||||||
|
@ -53,17 +53,17 @@ import TelemetryService from "./TelemetryService";
|
|||||||
})
|
})
|
||||||
@CrudApiEndpoint(new Route("/telemetry-exception-status"))
|
@CrudApiEndpoint(new Route("/telemetry-exception-status"))
|
||||||
@TableMetadata({
|
@TableMetadata({
|
||||||
tableName: "TelemetryExceptionStatus",
|
tableName: "TelemetryException",
|
||||||
singularName: "TelemetryExceptionStatus",
|
singularName: "TelemetryException",
|
||||||
pluralName: "TelemetryExceptionsStatus",
|
pluralName: "TelemetryExceptionsStatus",
|
||||||
icon: IconProp.Error,
|
icon: IconProp.Error,
|
||||||
tableDescription:
|
tableDescription:
|
||||||
"List of all Telemetry Exceptions created for the telemetry service for this OneUptime project and it's status.",
|
"List of all Telemetry Exceptions created for the telemetry service for this OneUptime project and it's status.",
|
||||||
})
|
})
|
||||||
@Entity({
|
@Entity({
|
||||||
name: "TelemetryExceptionStatus",
|
name: "TelemetryException",
|
||||||
})
|
})
|
||||||
export default class TelemetryExceptionStatus extends DatabaseBaseModel {
|
export default class TelemetryException extends DatabaseBaseModel {
|
||||||
@ColumnAccessControl({
|
@ColumnAccessControl({
|
||||||
create: [
|
create: [
|
||||||
Permission.ProjectOwner,
|
Permission.ProjectOwner,
|
||||||
@ -128,7 +128,6 @@ export default class TelemetryExceptionStatus extends DatabaseBaseModel {
|
|||||||
})
|
})
|
||||||
public projectId?: ObjectID = undefined;
|
public projectId?: ObjectID = undefined;
|
||||||
|
|
||||||
|
|
||||||
@ColumnAccessControl({
|
@ColumnAccessControl({
|
||||||
create: [
|
create: [
|
||||||
Permission.ProjectOwner,
|
Permission.ProjectOwner,
|
||||||
@ -233,7 +232,6 @@ export default class TelemetryExceptionStatus extends DatabaseBaseModel {
|
|||||||
})
|
})
|
||||||
public message?: string = undefined;
|
public message?: string = undefined;
|
||||||
|
|
||||||
|
|
||||||
@ColumnAccessControl({
|
@ColumnAccessControl({
|
||||||
create: [
|
create: [
|
||||||
Permission.ProjectOwner,
|
Permission.ProjectOwner,
|
||||||
@ -257,7 +255,8 @@ export default class TelemetryExceptionStatus extends DatabaseBaseModel {
|
|||||||
type: TableColumnType.LongText,
|
type: TableColumnType.LongText,
|
||||||
canReadOnRelationQuery: false,
|
canReadOnRelationQuery: false,
|
||||||
title: "Stack Trace",
|
title: "Stack Trace",
|
||||||
description: "Stack trace of the exception that was thrown by the telemetry service",
|
description:
|
||||||
|
"Stack trace of the exception that was thrown by the telemetry service",
|
||||||
})
|
})
|
||||||
@Column({
|
@Column({
|
||||||
nullable: true,
|
nullable: true,
|
||||||
@ -265,7 +264,6 @@ export default class TelemetryExceptionStatus extends DatabaseBaseModel {
|
|||||||
})
|
})
|
||||||
public stackTrace?: string = undefined;
|
public stackTrace?: string = undefined;
|
||||||
|
|
||||||
|
|
||||||
@ColumnAccessControl({
|
@ColumnAccessControl({
|
||||||
create: [
|
create: [
|
||||||
Permission.ProjectOwner,
|
Permission.ProjectOwner,
|
||||||
@ -289,7 +287,8 @@ export default class TelemetryExceptionStatus extends DatabaseBaseModel {
|
|||||||
type: TableColumnType.LongText,
|
type: TableColumnType.LongText,
|
||||||
canReadOnRelationQuery: false,
|
canReadOnRelationQuery: false,
|
||||||
title: "Exception Type",
|
title: "Exception Type",
|
||||||
description: "Type of the exception that was thrown by the telemetry service",
|
description:
|
||||||
|
"Type of the exception that was thrown by the telemetry service",
|
||||||
})
|
})
|
||||||
@Column({
|
@Column({
|
||||||
nullable: true,
|
nullable: true,
|
||||||
@ -297,6 +296,7 @@ export default class TelemetryExceptionStatus extends DatabaseBaseModel {
|
|||||||
})
|
})
|
||||||
public exceptionType?: string = undefined;
|
public exceptionType?: string = undefined;
|
||||||
|
|
||||||
|
@Index()
|
||||||
@ColumnAccessControl({
|
@ColumnAccessControl({
|
||||||
create: [
|
create: [
|
||||||
Permission.ProjectOwner,
|
Permission.ProjectOwner,
|
||||||
@ -320,14 +320,15 @@ export default class TelemetryExceptionStatus extends DatabaseBaseModel {
|
|||||||
type: TableColumnType.ShortText,
|
type: TableColumnType.ShortText,
|
||||||
canReadOnRelationQuery: false,
|
canReadOnRelationQuery: false,
|
||||||
title: "Finger Print",
|
title: "Finger Print",
|
||||||
description: "Finger print of the exception that was thrown by the telemetry service",
|
description:
|
||||||
|
"Finger print of the exception that was thrown by the telemetry service",
|
||||||
})
|
})
|
||||||
@Column({
|
@Column({
|
||||||
nullable: true,
|
nullable: true,
|
||||||
type: ColumnType.ShortText,
|
type: ColumnType.ShortText,
|
||||||
length: ColumnLength.ShortText,
|
length: ColumnLength.ShortText,
|
||||||
})
|
})
|
||||||
public fingerPrint?: string = undefined;
|
public fingerprint?: string = undefined;
|
||||||
|
|
||||||
@ColumnAccessControl({
|
@ColumnAccessControl({
|
||||||
create: [
|
create: [
|
||||||
@ -393,14 +394,22 @@ export default class TelemetryExceptionStatus extends DatabaseBaseModel {
|
|||||||
public createdByUserId?: ObjectID = undefined;
|
public createdByUserId?: ObjectID = undefined;
|
||||||
|
|
||||||
@ColumnAccessControl({
|
@ColumnAccessControl({
|
||||||
create: [],
|
create: [
|
||||||
|
Permission.ProjectOwner,
|
||||||
|
Permission.ProjectAdmin,
|
||||||
|
Permission.CreateTelemetryException,
|
||||||
|
],
|
||||||
read: [
|
read: [
|
||||||
Permission.ProjectOwner,
|
Permission.ProjectOwner,
|
||||||
Permission.ProjectAdmin,
|
Permission.ProjectAdmin,
|
||||||
Permission.ProjectMember,
|
Permission.ProjectMember,
|
||||||
Permission.ReadTelemetryException,
|
Permission.ReadTelemetryException,
|
||||||
],
|
],
|
||||||
update: [],
|
update: [
|
||||||
|
Permission.ProjectOwner,
|
||||||
|
Permission.ProjectAdmin,
|
||||||
|
Permission.EditTelemetryException,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
@TableColumn({
|
@TableColumn({
|
||||||
manyToOneRelationColumn: "deletedByUserId",
|
manyToOneRelationColumn: "deletedByUserId",
|
||||||
@ -425,14 +434,22 @@ export default class TelemetryExceptionStatus extends DatabaseBaseModel {
|
|||||||
public deletedByUser?: User = undefined;
|
public deletedByUser?: User = undefined;
|
||||||
|
|
||||||
@ColumnAccessControl({
|
@ColumnAccessControl({
|
||||||
create: [],
|
create: [
|
||||||
|
Permission.ProjectOwner,
|
||||||
|
Permission.ProjectAdmin,
|
||||||
|
Permission.CreateTelemetryException,
|
||||||
|
],
|
||||||
read: [
|
read: [
|
||||||
Permission.ProjectOwner,
|
Permission.ProjectOwner,
|
||||||
Permission.ProjectAdmin,
|
Permission.ProjectAdmin,
|
||||||
Permission.ProjectMember,
|
Permission.ProjectMember,
|
||||||
Permission.ReadTelemetryException,
|
Permission.ReadTelemetryException,
|
||||||
],
|
],
|
||||||
update: [],
|
update: [
|
||||||
|
Permission.ProjectOwner,
|
||||||
|
Permission.ProjectAdmin,
|
||||||
|
Permission.EditTelemetryException,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
@TableColumn({
|
@TableColumn({
|
||||||
type: TableColumnType.ObjectID,
|
type: TableColumnType.ObjectID,
|
||||||
@ -447,19 +464,23 @@ export default class TelemetryExceptionStatus extends DatabaseBaseModel {
|
|||||||
})
|
})
|
||||||
public deletedByUserId?: ObjectID = undefined;
|
public deletedByUserId?: ObjectID = undefined;
|
||||||
|
|
||||||
@ColumnAccessControl({
|
@ColumnAccessControl({
|
||||||
create: [
|
create: [
|
||||||
Permission.ProjectOwner,
|
Permission.ProjectOwner,
|
||||||
Permission.ProjectAdmin,
|
Permission.ProjectAdmin,
|
||||||
Permission.CreateProjectTeam,
|
Permission.CreateTelemetryException,
|
||||||
Permission.InviteProjectTeamMembers,
|
|
||||||
],
|
],
|
||||||
read: [
|
read: [
|
||||||
Permission.ProjectOwner,
|
Permission.ProjectOwner,
|
||||||
Permission.ProjectAdmin,
|
Permission.ProjectAdmin,
|
||||||
Permission.ReadProjectTeam,
|
Permission.ProjectMember,
|
||||||
|
Permission.ReadTelemetryException,
|
||||||
|
],
|
||||||
|
update: [
|
||||||
|
Permission.ProjectOwner,
|
||||||
|
Permission.ProjectAdmin,
|
||||||
|
Permission.EditTelemetryException,
|
||||||
],
|
],
|
||||||
update: [Permission.CurrentUser],
|
|
||||||
})
|
})
|
||||||
@TableColumn({
|
@TableColumn({
|
||||||
required: false,
|
required: false,
|
||||||
@ -474,21 +495,23 @@ export default class TelemetryExceptionStatus extends DatabaseBaseModel {
|
|||||||
})
|
})
|
||||||
public markedAsResolvedAt?: Date = undefined;
|
public markedAsResolvedAt?: Date = undefined;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ColumnAccessControl({
|
@ColumnAccessControl({
|
||||||
create: [
|
create: [
|
||||||
Permission.ProjectOwner,
|
Permission.ProjectOwner,
|
||||||
Permission.ProjectAdmin,
|
Permission.ProjectAdmin,
|
||||||
Permission.CreateProjectTeam,
|
Permission.CreateTelemetryException,
|
||||||
Permission.InviteProjectTeamMembers,
|
|
||||||
],
|
],
|
||||||
read: [
|
read: [
|
||||||
Permission.ProjectOwner,
|
Permission.ProjectOwner,
|
||||||
Permission.ProjectAdmin,
|
Permission.ProjectAdmin,
|
||||||
Permission.ReadProjectTeam,
|
Permission.ProjectMember,
|
||||||
|
Permission.ReadTelemetryException,
|
||||||
|
],
|
||||||
|
update: [
|
||||||
|
Permission.ProjectOwner,
|
||||||
|
Permission.ProjectAdmin,
|
||||||
|
Permission.EditTelemetryException,
|
||||||
],
|
],
|
||||||
update: [Permission.CurrentUser],
|
|
||||||
})
|
})
|
||||||
@TableColumn({
|
@TableColumn({
|
||||||
required: false,
|
required: false,
|
||||||
@ -503,20 +526,23 @@ export default class TelemetryExceptionStatus extends DatabaseBaseModel {
|
|||||||
})
|
})
|
||||||
public markedAsMutedAt?: Date = undefined;
|
public markedAsMutedAt?: Date = undefined;
|
||||||
|
|
||||||
|
|
||||||
@ColumnAccessControl({
|
@ColumnAccessControl({
|
||||||
create: [
|
create: [
|
||||||
Permission.ProjectOwner,
|
Permission.ProjectOwner,
|
||||||
Permission.ProjectAdmin,
|
Permission.ProjectAdmin,
|
||||||
Permission.CreateProjectTeam,
|
Permission.CreateTelemetryException,
|
||||||
Permission.InviteProjectTeamMembers,
|
|
||||||
],
|
],
|
||||||
read: [
|
read: [
|
||||||
Permission.ProjectOwner,
|
Permission.ProjectOwner,
|
||||||
Permission.ProjectAdmin,
|
Permission.ProjectAdmin,
|
||||||
Permission.ReadProjectTeam,
|
Permission.ProjectMember,
|
||||||
|
Permission.ReadTelemetryException,
|
||||||
|
],
|
||||||
|
update: [
|
||||||
|
Permission.ProjectOwner,
|
||||||
|
Permission.ProjectAdmin,
|
||||||
|
Permission.EditTelemetryException,
|
||||||
],
|
],
|
||||||
update: [Permission.CurrentUser],
|
|
||||||
})
|
})
|
||||||
@TableColumn({
|
@TableColumn({
|
||||||
required: false,
|
required: false,
|
||||||
@ -535,15 +561,19 @@ export default class TelemetryExceptionStatus extends DatabaseBaseModel {
|
|||||||
create: [
|
create: [
|
||||||
Permission.ProjectOwner,
|
Permission.ProjectOwner,
|
||||||
Permission.ProjectAdmin,
|
Permission.ProjectAdmin,
|
||||||
Permission.CreateProjectTeam,
|
Permission.CreateTelemetryException,
|
||||||
Permission.InviteProjectTeamMembers,
|
|
||||||
],
|
],
|
||||||
read: [
|
read: [
|
||||||
Permission.ProjectOwner,
|
Permission.ProjectOwner,
|
||||||
Permission.ProjectAdmin,
|
Permission.ProjectAdmin,
|
||||||
Permission.ReadProjectTeam,
|
Permission.ProjectMember,
|
||||||
|
Permission.ReadTelemetryException,
|
||||||
|
],
|
||||||
|
update: [
|
||||||
|
Permission.ProjectOwner,
|
||||||
|
Permission.ProjectAdmin,
|
||||||
|
Permission.EditTelemetryException,
|
||||||
],
|
],
|
||||||
update: [Permission.CurrentUser],
|
|
||||||
})
|
})
|
||||||
@TableColumn({
|
@TableColumn({
|
||||||
required: false,
|
required: false,
|
||||||
@ -558,24 +588,30 @@ export default class TelemetryExceptionStatus extends DatabaseBaseModel {
|
|||||||
})
|
})
|
||||||
public lastSeenAt?: Date = undefined;
|
public lastSeenAt?: Date = undefined;
|
||||||
|
|
||||||
|
|
||||||
// assign to.
|
// assign to.
|
||||||
@ColumnAccessControl({
|
@ColumnAccessControl({
|
||||||
create: [],
|
create: [
|
||||||
|
Permission.ProjectOwner,
|
||||||
|
Permission.ProjectAdmin,
|
||||||
|
Permission.CreateTelemetryException,
|
||||||
|
],
|
||||||
read: [
|
read: [
|
||||||
Permission.ProjectOwner,
|
Permission.ProjectOwner,
|
||||||
Permission.ProjectAdmin,
|
Permission.ProjectAdmin,
|
||||||
Permission.ProjectMember,
|
Permission.ProjectMember,
|
||||||
Permission.ReadTelemetryException,
|
Permission.ReadTelemetryException,
|
||||||
],
|
],
|
||||||
update: [],
|
update: [
|
||||||
|
Permission.ProjectOwner,
|
||||||
|
Permission.ProjectAdmin,
|
||||||
|
Permission.EditTelemetryException,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
@TableColumn({
|
@TableColumn({
|
||||||
manyToOneRelationColumn: "assignToUserId",
|
manyToOneRelationColumn: "assignToUserId",
|
||||||
type: TableColumnType.Entity,
|
type: TableColumnType.Entity,
|
||||||
title: "Assign to User",
|
title: "Assign to User",
|
||||||
description:
|
description: "Relation to User who this exception is assigned to.",
|
||||||
"Relation to User who this exception is assigned to.",
|
|
||||||
})
|
})
|
||||||
@ManyToOne(
|
@ManyToOne(
|
||||||
() => {
|
() => {
|
||||||
@ -593,20 +629,27 @@ export default class TelemetryExceptionStatus extends DatabaseBaseModel {
|
|||||||
public assignToUser?: User = undefined;
|
public assignToUser?: User = undefined;
|
||||||
|
|
||||||
@ColumnAccessControl({
|
@ColumnAccessControl({
|
||||||
create: [],
|
create: [
|
||||||
|
Permission.ProjectOwner,
|
||||||
|
Permission.ProjectAdmin,
|
||||||
|
Permission.CreateTelemetryException,
|
||||||
|
],
|
||||||
read: [
|
read: [
|
||||||
Permission.ProjectOwner,
|
Permission.ProjectOwner,
|
||||||
Permission.ProjectAdmin,
|
Permission.ProjectAdmin,
|
||||||
Permission.ProjectMember,
|
Permission.ProjectMember,
|
||||||
Permission.ReadTelemetryException,
|
Permission.ReadTelemetryException,
|
||||||
],
|
],
|
||||||
update: [],
|
update: [
|
||||||
|
Permission.ProjectOwner,
|
||||||
|
Permission.ProjectAdmin,
|
||||||
|
Permission.EditTelemetryException,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
@TableColumn({
|
@TableColumn({
|
||||||
type: TableColumnType.ObjectID,
|
type: TableColumnType.ObjectID,
|
||||||
title: "Assign to User ID",
|
title: "Assign to User ID",
|
||||||
description:
|
description: "User ID who this exception is assigned to.",
|
||||||
"User ID who this exception is assigned to.",
|
|
||||||
})
|
})
|
||||||
@Column({
|
@Column({
|
||||||
type: ColumnType.ObjectID,
|
type: ColumnType.ObjectID,
|
||||||
@ -615,27 +658,32 @@ export default class TelemetryExceptionStatus extends DatabaseBaseModel {
|
|||||||
})
|
})
|
||||||
public assignToUserId?: ObjectID = undefined;
|
public assignToUserId?: ObjectID = undefined;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// assign to team.
|
// assign to team.
|
||||||
|
|
||||||
// assign to.
|
// assign to.
|
||||||
@ColumnAccessControl({
|
@ColumnAccessControl({
|
||||||
create: [],
|
create: [
|
||||||
|
Permission.ProjectOwner,
|
||||||
|
Permission.ProjectAdmin,
|
||||||
|
Permission.CreateTelemetryException,
|
||||||
|
],
|
||||||
read: [
|
read: [
|
||||||
Permission.ProjectOwner,
|
Permission.ProjectOwner,
|
||||||
Permission.ProjectAdmin,
|
Permission.ProjectAdmin,
|
||||||
Permission.ProjectMember,
|
Permission.ProjectMember,
|
||||||
Permission.ReadTelemetryException,
|
Permission.ReadTelemetryException,
|
||||||
],
|
],
|
||||||
update: [],
|
update: [
|
||||||
|
Permission.ProjectOwner,
|
||||||
|
Permission.ProjectAdmin,
|
||||||
|
Permission.EditTelemetryException,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
@TableColumn({
|
@TableColumn({
|
||||||
manyToOneRelationColumn: "assignToTeamId",
|
manyToOneRelationColumn: "assignToTeamId",
|
||||||
type: TableColumnType.Entity,
|
type: TableColumnType.Entity,
|
||||||
title: "Assign to Team",
|
title: "Assign to Team",
|
||||||
description:
|
description: "Relation to Team who this exception is assigned to.",
|
||||||
"Relation to Team who this exception is assigned to.",
|
|
||||||
})
|
})
|
||||||
@ManyToOne(
|
@ManyToOne(
|
||||||
() => {
|
() => {
|
||||||
@ -653,20 +701,27 @@ export default class TelemetryExceptionStatus extends DatabaseBaseModel {
|
|||||||
public assignToTeam?: Team = undefined;
|
public assignToTeam?: Team = undefined;
|
||||||
|
|
||||||
@ColumnAccessControl({
|
@ColumnAccessControl({
|
||||||
create: [],
|
create: [
|
||||||
|
Permission.ProjectOwner,
|
||||||
|
Permission.ProjectAdmin,
|
||||||
|
Permission.CreateTelemetryException,
|
||||||
|
],
|
||||||
read: [
|
read: [
|
||||||
Permission.ProjectOwner,
|
Permission.ProjectOwner,
|
||||||
Permission.ProjectAdmin,
|
Permission.ProjectAdmin,
|
||||||
Permission.ProjectMember,
|
Permission.ProjectMember,
|
||||||
Permission.ReadTelemetryException,
|
Permission.ReadTelemetryException,
|
||||||
],
|
],
|
||||||
update: [],
|
update: [
|
||||||
|
Permission.ProjectOwner,
|
||||||
|
Permission.ProjectAdmin,
|
||||||
|
Permission.EditTelemetryException,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
@TableColumn({
|
@TableColumn({
|
||||||
type: TableColumnType.ObjectID,
|
type: TableColumnType.ObjectID,
|
||||||
title: "Assign to Team ID",
|
title: "Assign to Team ID",
|
||||||
description:
|
description: "Team ID who this exception is assigned to.",
|
||||||
"Team ID who this exception is assigned to.",
|
|
||||||
})
|
})
|
||||||
@Column({
|
@Column({
|
||||||
type: ColumnType.ObjectID,
|
type: ColumnType.ObjectID,
|
||||||
@ -675,18 +730,25 @@ export default class TelemetryExceptionStatus extends DatabaseBaseModel {
|
|||||||
})
|
})
|
||||||
public assignToTeamId?: ObjectID = undefined;
|
public assignToTeamId?: ObjectID = undefined;
|
||||||
|
|
||||||
|
|
||||||
// mark as resolved by.
|
// mark as resolved by.
|
||||||
|
|
||||||
@ColumnAccessControl({
|
@ColumnAccessControl({
|
||||||
create: [],
|
create: [
|
||||||
|
Permission.ProjectOwner,
|
||||||
|
Permission.ProjectAdmin,
|
||||||
|
Permission.CreateTelemetryException,
|
||||||
|
],
|
||||||
read: [
|
read: [
|
||||||
Permission.ProjectOwner,
|
Permission.ProjectOwner,
|
||||||
Permission.ProjectAdmin,
|
Permission.ProjectAdmin,
|
||||||
Permission.ProjectMember,
|
Permission.ProjectMember,
|
||||||
Permission.ReadTelemetryException,
|
Permission.ReadTelemetryException,
|
||||||
],
|
],
|
||||||
update: [],
|
update: [
|
||||||
|
Permission.ProjectOwner,
|
||||||
|
Permission.ProjectAdmin,
|
||||||
|
Permission.EditTelemetryException,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
@TableColumn({
|
@TableColumn({
|
||||||
manyToOneRelationColumn: "markedAsResolvedByUserId",
|
manyToOneRelationColumn: "markedAsResolvedByUserId",
|
||||||
@ -711,20 +773,27 @@ export default class TelemetryExceptionStatus extends DatabaseBaseModel {
|
|||||||
public markedAsResolvedByUser?: User = undefined;
|
public markedAsResolvedByUser?: User = undefined;
|
||||||
|
|
||||||
@ColumnAccessControl({
|
@ColumnAccessControl({
|
||||||
create: [],
|
create: [
|
||||||
|
Permission.ProjectOwner,
|
||||||
|
Permission.ProjectAdmin,
|
||||||
|
Permission.CreateTelemetryException,
|
||||||
|
],
|
||||||
read: [
|
read: [
|
||||||
Permission.ProjectOwner,
|
Permission.ProjectOwner,
|
||||||
Permission.ProjectAdmin,
|
Permission.ProjectAdmin,
|
||||||
Permission.ProjectMember,
|
Permission.ProjectMember,
|
||||||
Permission.ReadTelemetryException,
|
Permission.ReadTelemetryException,
|
||||||
],
|
],
|
||||||
update: [],
|
update: [
|
||||||
|
Permission.ProjectOwner,
|
||||||
|
Permission.ProjectAdmin,
|
||||||
|
Permission.EditTelemetryException,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
@TableColumn({
|
@TableColumn({
|
||||||
type: TableColumnType.ObjectID,
|
type: TableColumnType.ObjectID,
|
||||||
title: "Marked as Resolved By User ID",
|
title: "Marked as Resolved By User ID",
|
||||||
description:
|
description: "User ID who marked this exception as resolved.",
|
||||||
"User ID who marked this exception as resolved.",
|
|
||||||
})
|
})
|
||||||
@Column({
|
@Column({
|
||||||
type: ColumnType.ObjectID,
|
type: ColumnType.ObjectID,
|
||||||
@ -733,26 +802,31 @@ export default class TelemetryExceptionStatus extends DatabaseBaseModel {
|
|||||||
})
|
})
|
||||||
public markedAsResolvedByUserId?: ObjectID = undefined;
|
public markedAsResolvedByUserId?: ObjectID = undefined;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Mark as muted by.
|
// Mark as muted by.
|
||||||
|
|
||||||
@ColumnAccessControl({
|
@ColumnAccessControl({
|
||||||
create: [],
|
create: [
|
||||||
|
Permission.ProjectOwner,
|
||||||
|
Permission.ProjectAdmin,
|
||||||
|
Permission.CreateTelemetryException,
|
||||||
|
],
|
||||||
read: [
|
read: [
|
||||||
Permission.ProjectOwner,
|
Permission.ProjectOwner,
|
||||||
Permission.ProjectAdmin,
|
Permission.ProjectAdmin,
|
||||||
Permission.ProjectMember,
|
Permission.ProjectMember,
|
||||||
Permission.ReadTelemetryException,
|
Permission.ReadTelemetryException,
|
||||||
],
|
],
|
||||||
update: [],
|
update: [
|
||||||
|
Permission.ProjectOwner,
|
||||||
|
Permission.ProjectAdmin,
|
||||||
|
Permission.EditTelemetryException,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
@TableColumn({
|
@TableColumn({
|
||||||
manyToOneRelationColumn: "markedAsMutedByUserId",
|
manyToOneRelationColumn: "markedAsMutedByUserId",
|
||||||
type: TableColumnType.Entity,
|
type: TableColumnType.Entity,
|
||||||
title: "Mark as Muted By User",
|
title: "Mark as Muted By User",
|
||||||
description:
|
description: "Mark as muted by User",
|
||||||
"Mark as muted by User",
|
|
||||||
})
|
})
|
||||||
@ManyToOne(
|
@ManyToOne(
|
||||||
() => {
|
() => {
|
||||||
@ -770,20 +844,27 @@ export default class TelemetryExceptionStatus extends DatabaseBaseModel {
|
|||||||
public markedAsMutedByUser?: User = undefined;
|
public markedAsMutedByUser?: User = undefined;
|
||||||
|
|
||||||
@ColumnAccessControl({
|
@ColumnAccessControl({
|
||||||
create: [],
|
create: [
|
||||||
|
Permission.ProjectOwner,
|
||||||
|
Permission.ProjectAdmin,
|
||||||
|
Permission.CreateTelemetryException,
|
||||||
|
],
|
||||||
read: [
|
read: [
|
||||||
Permission.ProjectOwner,
|
Permission.ProjectOwner,
|
||||||
Permission.ProjectAdmin,
|
Permission.ProjectAdmin,
|
||||||
Permission.ProjectMember,
|
Permission.ProjectMember,
|
||||||
Permission.ReadTelemetryException,
|
Permission.ReadTelemetryException,
|
||||||
],
|
],
|
||||||
update: [],
|
update: [
|
||||||
|
Permission.ProjectOwner,
|
||||||
|
Permission.ProjectAdmin,
|
||||||
|
Permission.EditTelemetryException,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
@TableColumn({
|
@TableColumn({
|
||||||
type: TableColumnType.ObjectID,
|
type: TableColumnType.ObjectID,
|
||||||
title: "Mark as Muted By User ID",
|
title: "Mark as Muted By User ID",
|
||||||
description:
|
description: "User ID who marked this exception as muted.",
|
||||||
"User ID who marked this exception as muted.",
|
|
||||||
})
|
})
|
||||||
@Column({
|
@Column({
|
||||||
type: ColumnType.ObjectID,
|
type: ColumnType.ObjectID,
|
||||||
@ -791,8 +872,4 @@ export default class TelemetryExceptionStatus extends DatabaseBaseModel {
|
|||||||
transformer: ObjectID.getDatabaseTransformer(),
|
transformer: ObjectID.getDatabaseTransformer(),
|
||||||
})
|
})
|
||||||
public markedAsMutedByUserId?: ObjectID = undefined;
|
public markedAsMutedByUserId?: ObjectID = undefined;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,38 +0,0 @@
|
|||||||
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
||||||
|
|
||||||
export class MigrationName1724607603707 implements MigrationInterface {
|
|
||||||
public name = 'MigrationName1724607603707'
|
|
||||||
|
|
||||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
||||||
await queryRunner.query(`CREATE TABLE "TelemetryExceptionStatus" ("_id" uuid NOT NULL DEFAULT uuid_generate_v4(), "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), "deletedAt" TIMESTAMP, "version" integer NOT NULL, "projectId" uuid NOT NULL, "telemetryServiceId" uuid NOT NULL, "message" character varying, "stackTrace" character varying, "exceptionType" character varying, "fingerPrint" character varying(100), "createdByUserId" uuid, "deletedByUserId" uuid, "markedAsResolvedAt" TIMESTAMP WITH TIME ZONE, "markedAsMutedAt" TIMESTAMP WITH TIME ZONE, "firstSeenAt" TIMESTAMP WITH TIME ZONE, "lastSeenAt" TIMESTAMP WITH TIME ZONE, "assignToUserId" uuid, "assignToTeamId" uuid, "markedAsResolvedByUserId" uuid, "markedAsMutedByUserId" uuid, CONSTRAINT "PK_8db287c0fc7516e22d53876137c" PRIMARY KEY ("_id"))`);
|
|
||||||
await queryRunner.query(`CREATE INDEX "IDX_7c02d07bf73bfdac7301a6c86d" ON "TelemetryExceptionStatus" ("projectId") `);
|
|
||||||
await queryRunner.query(`CREATE INDEX "IDX_0f66442452b5a89efa085ede0f" ON "TelemetryExceptionStatus" ("telemetryServiceId") `);
|
|
||||||
await queryRunner.query(`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type":"Recurring","value":{"intervalType":"Day","intervalCount":{"_type":"PositiveNumber","value":1}}}'`);
|
|
||||||
await queryRunner.query(`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type":"RestrictionTimes","value":{"restictionType":"None","dayRestrictionTimes":null,"weeklyRestrictionTimes":[]}}'`);
|
|
||||||
await queryRunner.query(`ALTER TABLE "TelemetryExceptionStatus" ADD CONSTRAINT "FK_7c02d07bf73bfdac7301a6c86d5" FOREIGN KEY ("projectId") REFERENCES "Project"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
|
||||||
await queryRunner.query(`ALTER TABLE "TelemetryExceptionStatus" ADD CONSTRAINT "FK_0f66442452b5a89efa085ede0fd" FOREIGN KEY ("telemetryServiceId") REFERENCES "TelemetryService"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
|
||||||
await queryRunner.query(`ALTER TABLE "TelemetryExceptionStatus" ADD CONSTRAINT "FK_fe9e43b2cf2278894f9fe67c92f" FOREIGN KEY ("createdByUserId") REFERENCES "User"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
|
||||||
await queryRunner.query(`ALTER TABLE "TelemetryExceptionStatus" ADD CONSTRAINT "FK_3b402ffb6fe47992c38f4cd5e7a" FOREIGN KEY ("deletedByUserId") REFERENCES "User"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
|
||||||
await queryRunner.query(`ALTER TABLE "TelemetryExceptionStatus" ADD CONSTRAINT "FK_88a1d97d74c54cd80b384f2a911" FOREIGN KEY ("assignToUserId") REFERENCES "User"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
|
||||||
await queryRunner.query(`ALTER TABLE "TelemetryExceptionStatus" ADD CONSTRAINT "FK_1c8cc9368c92f60cb093af277f8" FOREIGN KEY ("assignToTeamId") REFERENCES "Team"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
|
||||||
await queryRunner.query(`ALTER TABLE "TelemetryExceptionStatus" ADD CONSTRAINT "FK_fe156e1dce6bdae3f349d33e293" FOREIGN KEY ("markedAsResolvedByUserId") REFERENCES "User"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
|
||||||
await queryRunner.query(`ALTER TABLE "TelemetryExceptionStatus" ADD CONSTRAINT "FK_9d7647bf6d537f5afbd00ef4a8b" FOREIGN KEY ("markedAsMutedByUserId") REFERENCES "User"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
||||||
await queryRunner.query(`ALTER TABLE "TelemetryExceptionStatus" DROP CONSTRAINT "FK_9d7647bf6d537f5afbd00ef4a8b"`);
|
|
||||||
await queryRunner.query(`ALTER TABLE "TelemetryExceptionStatus" DROP CONSTRAINT "FK_fe156e1dce6bdae3f349d33e293"`);
|
|
||||||
await queryRunner.query(`ALTER TABLE "TelemetryExceptionStatus" DROP CONSTRAINT "FK_1c8cc9368c92f60cb093af277f8"`);
|
|
||||||
await queryRunner.query(`ALTER TABLE "TelemetryExceptionStatus" DROP CONSTRAINT "FK_88a1d97d74c54cd80b384f2a911"`);
|
|
||||||
await queryRunner.query(`ALTER TABLE "TelemetryExceptionStatus" DROP CONSTRAINT "FK_3b402ffb6fe47992c38f4cd5e7a"`);
|
|
||||||
await queryRunner.query(`ALTER TABLE "TelemetryExceptionStatus" DROP CONSTRAINT "FK_fe9e43b2cf2278894f9fe67c92f"`);
|
|
||||||
await queryRunner.query(`ALTER TABLE "TelemetryExceptionStatus" DROP CONSTRAINT "FK_0f66442452b5a89efa085ede0fd"`);
|
|
||||||
await queryRunner.query(`ALTER TABLE "TelemetryExceptionStatus" DROP CONSTRAINT "FK_7c02d07bf73bfdac7301a6c86d5"`);
|
|
||||||
await queryRunner.query(`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type": "RestrictionTimes", "value": {"restictionType": "None", "dayRestrictionTimes": null, "weeklyRestrictionTimes": []}}'`);
|
|
||||||
await queryRunner.query(`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type": "Recurring", "value": {"intervalType": "Day", "intervalCount": {"_type": "PositiveNumber", "value": 1}}}'`);
|
|
||||||
await queryRunner.query(`DROP INDEX "public"."IDX_0f66442452b5a89efa085ede0f"`);
|
|
||||||
await queryRunner.query(`DROP INDEX "public"."IDX_7c02d07bf73bfdac7301a6c86d"`);
|
|
||||||
await queryRunner.query(`DROP TABLE "TelemetryExceptionStatus"`);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,93 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
|
||||||
|
export class MigrationName1724610006927 implements MigrationInterface {
|
||||||
|
public name = "MigrationName1724610006927";
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TABLE "TelemetryException" ("_id" uuid NOT NULL DEFAULT uuid_generate_v4(), "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), "deletedAt" TIMESTAMP, "version" integer NOT NULL, "projectId" uuid NOT NULL, "telemetryServiceId" uuid NOT NULL, "message" character varying, "stackTrace" character varying, "exceptionType" character varying, "fingerprint" character varying(100), "createdByUserId" uuid, "deletedByUserId" uuid, "markedAsResolvedAt" TIMESTAMP WITH TIME ZONE, "markedAsMutedAt" TIMESTAMP WITH TIME ZONE, "firstSeenAt" TIMESTAMP WITH TIME ZONE, "lastSeenAt" TIMESTAMP WITH TIME ZONE, "assignToUserId" uuid, "assignToTeamId" uuid, "markedAsResolvedByUserId" uuid, "markedAsMutedByUserId" uuid, CONSTRAINT "PK_53717afe73c3e72c11713e5e25f" PRIMARY KEY ("_id"))`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE INDEX "IDX_3310c3a807a7e8bca9d1bd8e0e" ON "TelemetryException" ("projectId") `,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE INDEX "IDX_6470c69cb5f53c5899c0483df5" ON "TelemetryException" ("telemetryServiceId") `,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE INDEX "IDX_e270eb229cd583c653c2176db9" ON "TelemetryException" ("fingerprint") `,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type":"Recurring","value":{"intervalType":"Day","intervalCount":{"_type":"PositiveNumber","value":1}}}'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type":"RestrictionTimes","value":{"restictionType":"None","dayRestrictionTimes":null,"weeklyRestrictionTimes":[]}}'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "TelemetryException" ADD CONSTRAINT "FK_3310c3a807a7e8bca9d1bd8e0eb" FOREIGN KEY ("projectId") REFERENCES "Project"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "TelemetryException" ADD CONSTRAINT "FK_6470c69cb5f53c5899c0483df5f" FOREIGN KEY ("telemetryServiceId") REFERENCES "TelemetryService"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "TelemetryException" ADD CONSTRAINT "FK_d2e1b4f5dcaebbf14ed6cbd303d" FOREIGN KEY ("createdByUserId") REFERENCES "User"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "TelemetryException" ADD CONSTRAINT "FK_757f473e68b584bc42fcfbd9373" FOREIGN KEY ("deletedByUserId") REFERENCES "User"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "TelemetryException" ADD CONSTRAINT "FK_f7ec3f51dae2b4963cfb8fe5c46" FOREIGN KEY ("assignToUserId") REFERENCES "User"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "TelemetryException" ADD CONSTRAINT "FK_63221e8bd973ab71a49598d6c88" FOREIGN KEY ("assignToTeamId") REFERENCES "Team"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "TelemetryException" ADD CONSTRAINT "FK_10c7733499d5afa9b857f4a00c5" FOREIGN KEY ("markedAsResolvedByUserId") REFERENCES "User"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "TelemetryException" ADD CONSTRAINT "FK_199e3572d19b75e59f2082251f8" FOREIGN KEY ("markedAsMutedByUserId") REFERENCES "User"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "TelemetryException" DROP CONSTRAINT "FK_199e3572d19b75e59f2082251f8"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "TelemetryException" DROP CONSTRAINT "FK_10c7733499d5afa9b857f4a00c5"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "TelemetryException" DROP CONSTRAINT "FK_63221e8bd973ab71a49598d6c88"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "TelemetryException" DROP CONSTRAINT "FK_f7ec3f51dae2b4963cfb8fe5c46"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "TelemetryException" DROP CONSTRAINT "FK_757f473e68b584bc42fcfbd9373"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "TelemetryException" DROP CONSTRAINT "FK_d2e1b4f5dcaebbf14ed6cbd303d"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "TelemetryException" DROP CONSTRAINT "FK_6470c69cb5f53c5899c0483df5f"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "TelemetryException" DROP CONSTRAINT "FK_3310c3a807a7e8bca9d1bd8e0eb"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type": "RestrictionTimes", "value": {"restictionType": "None", "dayRestrictionTimes": null, "weeklyRestrictionTimes": []}}'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type": "Recurring", "value": {"intervalType": "Day", "intervalCount": {"_type": "PositiveNumber", "value": 1}}}'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP INDEX "public"."IDX_e270eb229cd583c653c2176db9"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP INDEX "public"."IDX_6470c69cb5f53c5899c0483df5"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP INDEX "public"."IDX_3310c3a807a7e8bca9d1bd8e0e"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TABLE "TelemetryException"`);
|
||||||
|
}
|
||||||
|
}
|
@ -41,6 +41,7 @@ import { MigrationName1722892318363 } from "./1722892318363-MigrationName";
|
|||||||
import { MigrationName1723825511054 } from "./1723825511054-MigrationName";
|
import { MigrationName1723825511054 } from "./1723825511054-MigrationName";
|
||||||
import { MigrationName1723828588502 } from "./1723828588502-MigrationName";
|
import { MigrationName1723828588502 } from "./1723828588502-MigrationName";
|
||||||
import { MigrationName1724078044172 } from "./1724078044172-MigrationName";
|
import { MigrationName1724078044172 } from "./1724078044172-MigrationName";
|
||||||
|
import { MigrationName1724610006927 } from "./1724610006927-MigrationName";
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
InitialMigration,
|
InitialMigration,
|
||||||
@ -86,5 +87,6 @@ export default [
|
|||||||
MigrationName1723825511054,
|
MigrationName1723825511054,
|
||||||
MigrationName1723828588502,
|
MigrationName1723828588502,
|
||||||
MigrationName1724078044172,
|
MigrationName1724078044172,
|
||||||
MigrationName1720812937067
|
MigrationName1720812937067,
|
||||||
|
MigrationName1724610006927,
|
||||||
];
|
];
|
||||||
|
@ -130,6 +130,7 @@ import AnalyticsBaseModel from "Common/Models/AnalyticsModels/AnalyticsBaseModel
|
|||||||
import CopilotPullRequestService from "./CopilotPullRequestService";
|
import CopilotPullRequestService from "./CopilotPullRequestService";
|
||||||
import ServiceCatalogDependencyService from "./ServiceCatalogDependencyService";
|
import ServiceCatalogDependencyService from "./ServiceCatalogDependencyService";
|
||||||
import TelemetryAttributeService from "./TelemetryAttributeService";
|
import TelemetryAttributeService from "./TelemetryAttributeService";
|
||||||
|
import TelemetryExceptionStatusService from "./TelemetryExceptionStatusService";
|
||||||
|
|
||||||
const services: Array<BaseService> = [
|
const services: Array<BaseService> = [
|
||||||
AcmeCertificateService,
|
AcmeCertificateService,
|
||||||
@ -271,6 +272,8 @@ const services: Array<BaseService> = [
|
|||||||
CopilotActionService,
|
CopilotActionService,
|
||||||
ServiceCopilotCodeRepositoryService,
|
ServiceCopilotCodeRepositoryService,
|
||||||
CopilotPullRequestService,
|
CopilotPullRequestService,
|
||||||
|
|
||||||
|
TelemetryExceptionStatusService,
|
||||||
];
|
];
|
||||||
|
|
||||||
export const AnalyticsServices: Array<
|
export const AnalyticsServices: Array<
|
||||||
|
10
Common/Server/Services/TelemetryExceptionStatusService.ts
Normal file
10
Common/Server/Services/TelemetryExceptionStatusService.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import DatabaseService from "./DatabaseService";
|
||||||
|
import Model from "Common/Models/DatabaseModels/TelemetryException";
|
||||||
|
|
||||||
|
export class Service extends DatabaseService<Model> {
|
||||||
|
public constructor() {
|
||||||
|
super(Model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new Service();
|
@ -13,6 +13,10 @@ export default class OneUptimeDate {
|
|||||||
return seconds * 1000 * 1000 * 1000;
|
return seconds * 1000 * 1000 * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static now(): Date {
|
||||||
|
return this.getCurrentDate();
|
||||||
|
}
|
||||||
|
|
||||||
public static getDateFromYYYYMMDD(
|
public static getDateFromYYYYMMDD(
|
||||||
year: string,
|
year: string,
|
||||||
month: string,
|
month: string,
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
import CryptoJS from "crypto-js";
|
import CryptoJS from "crypto-js";
|
||||||
|
|
||||||
export default class Crypto {
|
export default class Crypto {
|
||||||
public static getMd5Hash(text: string): string {
|
public static getMd5Hash(text: string): string {
|
||||||
return CryptoJS.MD5(text).toString();
|
return CryptoJS.MD5(text).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static getSha256Hash(text: string): string {
|
|
||||||
return CryptoJS.SHA256(text).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public static getSha256Hash(text: string): string {
|
||||||
|
return CryptoJS.SHA256(text).toString();
|
||||||
|
}
|
||||||
}
|
}
|
@ -7,7 +7,7 @@ import OTelIngestService, {
|
|||||||
TelemetryServiceDataIngested,
|
TelemetryServiceDataIngested,
|
||||||
} from "../Service/OTelIngest";
|
} from "../Service/OTelIngest";
|
||||||
import OneUptimeDate from "Common/Types/Date";
|
import OneUptimeDate from "Common/Types/Date";
|
||||||
import BadRequestException from "Common/Types/Exception/BadRequestException";
|
import BadRequestException from "Common/Types/ExceptionInstance/BadRequestException";
|
||||||
import { JSONArray, JSONObject } from "Common/Types/JSON";
|
import { JSONArray, JSONObject } from "Common/Types/JSON";
|
||||||
import JSONFunctions from "Common/Types/JSONFunctions";
|
import JSONFunctions from "Common/Types/JSONFunctions";
|
||||||
import ProductType from "Common/Types/MeteredPlan/ProductType";
|
import ProductType from "Common/Types/MeteredPlan/ProductType";
|
||||||
@ -36,7 +36,7 @@ import protobuf from "protobufjs";
|
|||||||
import Dictionary from "Common/Types/Dictionary";
|
import Dictionary from "Common/Types/Dictionary";
|
||||||
import ObjectID from "Common/Types/ObjectID";
|
import ObjectID from "Common/Types/ObjectID";
|
||||||
import LogSeverity from "Common/Types/Log/LogSeverity";
|
import LogSeverity from "Common/Types/Log/LogSeverity";
|
||||||
import Exception from "Common/Models/AnalyticsModels/Exception";
|
import ExceptionInstance from "Common/Models/AnalyticsModels/ExceptionInstance";
|
||||||
import ExceptionUtil from "../Utils/Exception";
|
import ExceptionUtil from "../Utils/Exception";
|
||||||
|
|
||||||
// Load proto file for OTel
|
// Load proto file for OTel
|
||||||
@ -127,7 +127,7 @@ router.post(
|
|||||||
const resourceSpans: JSONArray = traceData["resourceSpans"] as JSONArray;
|
const resourceSpans: JSONArray = traceData["resourceSpans"] as JSONArray;
|
||||||
|
|
||||||
const dbSpans: Array<Span> = [];
|
const dbSpans: Array<Span> = [];
|
||||||
const dbExceptions: Array<Exception> = [];
|
const dbExceptions: Array<ExceptionInstance> = [];
|
||||||
|
|
||||||
let attributes: string[] = [];
|
let attributes: string[] = [];
|
||||||
|
|
||||||
@ -301,7 +301,7 @@ router.post(
|
|||||||
|
|
||||||
if (event["name"] === SpanEventType.Exception) {
|
if (event["name"] === SpanEventType.Exception) {
|
||||||
// add exception object.
|
// add exception object.
|
||||||
const exception: Exception = new Exception();
|
const exception: ExceptionInstance = new ExceptionInstance();
|
||||||
exception.projectId = dbSpan.projectId;
|
exception.projectId = dbSpan.projectId;
|
||||||
exception.serviceId = dbSpan.serviceId;
|
exception.serviceId = dbSpan.serviceId;
|
||||||
exception.spanId = dbSpan.spanId;
|
exception.spanId = dbSpan.spanId;
|
||||||
@ -314,10 +314,15 @@ router.post(
|
|||||||
] as string;
|
] as string;
|
||||||
exception.exceptionType = eventAttributes["type"] as string;
|
exception.exceptionType = eventAttributes["type"] as string;
|
||||||
exception.escaped = eventAttributes["escaped"] as boolean;
|
exception.escaped = eventAttributes["escaped"] as boolean;
|
||||||
exception.fingerprint = ExceptionUtil.getFingerprint(exception);
|
exception.fingerprint =
|
||||||
|
ExceptionUtil.getFingerprint(exception);
|
||||||
|
|
||||||
// add exception to dbExceptions
|
// add exception to dbExceptions
|
||||||
dbExceptions.push(exception);
|
dbExceptions.push(exception);
|
||||||
|
|
||||||
|
// save exception status
|
||||||
|
// maybe this can be improved instead of doing a lot of db calls.
|
||||||
|
await ExceptionUtil.saveOrUpdateTelemetryException(exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -360,7 +365,12 @@ router.post(
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await ExceptionService;
|
await ExceptionService.createMany({
|
||||||
|
items: dbExceptions,
|
||||||
|
props: {
|
||||||
|
isRoot: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
OTelIngestService.indexAttributes({
|
OTelIngestService.indexAttributes({
|
||||||
attributes: ArrayUtil.removeDuplicates(attributes),
|
attributes: ArrayUtil.removeDuplicates(attributes),
|
||||||
|
@ -1,16 +1,112 @@
|
|||||||
import Exception from 'Common/Models/AnalyticsModels/Exception';
|
import ExceptionInstance from "Common/Models/AnalyticsModels/ExceptionInstance";
|
||||||
import Crypto from 'Common/Utils/Crypto';
|
import TelemetryException from "Common/Models/DatabaseModels/TelemetryException";
|
||||||
|
import TelemetryExceptionStatusService from "Common/Server/Services/TelemetryExceptionStatusService";
|
||||||
|
import OneUptimeDate from "Common/Types/Date";
|
||||||
|
import BadDataException from "Common/Types/Exception/BadDataException";
|
||||||
|
import Crypto from "Common/Utils/Crypto";
|
||||||
|
|
||||||
export default class ExceptionUtil {
|
export default class ExceptionUtil {
|
||||||
public static getFingerprint(exception: Exception): string {
|
public static getFingerprint(exception: ExceptionInstance): string {
|
||||||
const message: string = exception.message || "";
|
const message: string = exception.message || "";
|
||||||
const stackTrace: string = exception.stackTrace || "";
|
const stackTrace: string = exception.stackTrace || "";
|
||||||
const type: string = exception.exceptionType || "";
|
const type: string = exception.exceptionType || "";
|
||||||
const projectId: string = exception.projectId?.toString() || "";
|
const projectId: string = exception.projectId?.toString() || "";
|
||||||
const serviceId: string = exception.serviceId?.toString() || "";
|
const serviceId: string = exception.serviceId?.toString() || "";
|
||||||
|
|
||||||
const hash: string = Crypto.getSha256Hash(projectId + serviceId + message + stackTrace + type);
|
const hash: string = Crypto.getSha256Hash(
|
||||||
|
projectId + serviceId + message + stackTrace + type,
|
||||||
|
);
|
||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async saveOrUpdateTelemetryException(
|
||||||
|
exception: ExceptionInstance,
|
||||||
|
): Promise<void> {
|
||||||
|
// Exception is saved to main database as well (not just analytics db), so users can assgin it, resolve it, etc.
|
||||||
|
|
||||||
|
if (!exception.fingerprint) {
|
||||||
|
throw new BadDataException(
|
||||||
|
"Fingerprint is required to save exception status",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!exception.projectId) {
|
||||||
|
throw new BadDataException(
|
||||||
|
"Project ID is required to save exception status",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!exception.serviceId) {
|
||||||
|
throw new BadDataException(
|
||||||
|
"Service ID is required to save exception status",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const fingerprint: string = exception.fingerprint;
|
||||||
|
|
||||||
|
// check if the exception with the same fingerprint already exists in the database
|
||||||
|
|
||||||
|
const existingExceptionStatus: TelemetryException | null =
|
||||||
|
await TelemetryExceptionStatusService.findOneBy({
|
||||||
|
query: {
|
||||||
|
fingerprint: fingerprint,
|
||||||
|
projectId: exception.projectId,
|
||||||
|
telemetryServiceId: exception.serviceId,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
_id: true,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
isRoot: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (existingExceptionStatus) {
|
||||||
|
// then update last seen as and unmark as resolved/muted
|
||||||
|
await TelemetryExceptionStatusService.updateOneBy({
|
||||||
|
query: {
|
||||||
|
_id: existingExceptionStatus._id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
lastSeenAt: OneUptimeDate.now(),
|
||||||
|
markedAsResolvedByUserId: null,
|
||||||
|
markedAsResolvedAt: null, // unmark as resolved if it was marked as resolved
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
isRoot: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!existingExceptionStatus) {
|
||||||
|
// Create a new exception status if it doesn't exist
|
||||||
|
const newExceptionStatus: TelemetryException = new TelemetryException();
|
||||||
|
newExceptionStatus.fingerprint = exception.fingerprint;
|
||||||
|
newExceptionStatus.projectId = exception.projectId;
|
||||||
|
newExceptionStatus.telemetryServiceId = exception.serviceId;
|
||||||
|
newExceptionStatus.lastSeenAt = OneUptimeDate.now();
|
||||||
|
newExceptionStatus.firstSeenAt = OneUptimeDate.now();
|
||||||
|
|
||||||
|
if (exception.exceptionType) {
|
||||||
|
newExceptionStatus.exceptionType = exception.exceptionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exception.message) {
|
||||||
|
newExceptionStatus.message = exception.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exception.stackTrace) {
|
||||||
|
newExceptionStatus.stackTrace = exception.stackTrace;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the new exception status to the database
|
||||||
|
await TelemetryExceptionStatusService.create({
|
||||||
|
data: newExceptionStatus,
|
||||||
|
props: {
|
||||||
|
isRoot: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user