src/alert/alert.service.ts
Properties |
|
Methods |
|
constructor(prismaService: PrismaService)
|
||||||
|
Defined in src/alert/alert.service.ts:26
|
||||||
|
Parameters :
|
| checkValue | ||||||
checkValue(value, thresholds)
|
||||||
|
Defined in src/alert/alert.service.ts:306
|
||||||
|
Parameters :
Returns :
{ valid: boolean; minBreach: boolean; maxBreach: boolean; }
|
| Async create | ||||||||||||
create(createAlertInput: CreateAlertDto, userId: string)
|
||||||||||||
|
Defined in src/alert/alert.service.ts:75
|
||||||||||||
|
Creates a new alert
Parameters :
Returns :
Promise<Alert>
A Promise that resolves to the created alert object. |
| Async findAllByUserId | |||||||||||||||
findAllByUserId(userId: string, queryOptions: literal type)
|
|||||||||||||||
|
Defined in src/alert/alert.service.ts:358
|
|||||||||||||||
|
Retrieves alerts for a specific user with pagination.
Parameters :
Returns :
Promise<Alert[]>
A Promise that resolves to an array of alerts for the specified user. |
| Async findMany | ||||||||
findMany(query: Prisma.AlertWhereInput)
|
||||||||
|
Defined in src/alert/alert.service.ts:221
|
||||||||
|
Finds and returns alerts based on query.
Parameters :
Returns :
unknown
A Promise that resolves to an array of alerts associated with the project. |
| Async getAlert | ||||||||
getAlert(alertId: number)
|
||||||||
|
Defined in src/alert/alert.service.ts:192
|
||||||||
|
Finds and returns the alert with the specified ID.
Parameters :
Returns :
Promise<Alert>
A Promise that resolves to the found alert object. |
| Async getAlertsByProjectID | ||||||||
getAlertsByProjectID(projectId: number)
|
||||||||
|
Defined in src/alert/alert.service.ts:205
|
||||||||
|
Finds and returns alerts associated with the specified project ID.
Parameters :
Returns :
Promise<Alert[]>
A Promise that resolves to an array of alerts associated with the project. |
| Async getAlertTargets | ||||||||
getAlertTargets(alert: Alert)
|
||||||||
|
Defined in src/alert/alert.service.ts:280
|
||||||||
|
Finds and returns alert targets.
Parameters :
Returns :
Promise<literal type>
A Promise that resolves to an object. |
| Async getAlertTriggers | ||||||||
getAlertTriggers(query: literal type)
|
||||||||
|
Defined in src/alert/alert.service.ts:250
|
||||||||
|
Finds and returns alert trigger events.
Parameters :
Returns :
Promise<AlertTrigger[]>
A Promise that resolves to an array of alerts. |
| getDiff | ||||||||||||||||
getDiff(alertParams: AlertParams, alertTrigger: AlertTrigger, pcc: boolean)
|
||||||||||||||||
|
Defined in src/alert/alert.service.ts:57
|
||||||||||||||||
|
Parameters :
Returns :
number
|
| Async getDueAlerts |
getDueAlerts()
|
|
Defined in src/alert/alert.service.ts:232
|
|
Finds and returns alerts which are due to be checked. Returns alerts that have nextCheckAt less than current time.
Returns :
Promise<Alert[]>
A Promise that resolves to an array of alerts. |
| getThresholds | ||||||||||||
getThresholds(alertParams: AlertParams, alertType: AlertType)
|
||||||||||||
|
Defined in src/alert/alert.service.ts:36
|
||||||||||||
|
Returns thresholds for the given AlertParams
Parameters :
Returns :
any
A Promise that resolves to thresholds |
| Async update | ||||||||||||
update(id: number, updateAlertInput: UpdateAlertDto)
|
||||||||||||
|
Defined in src/alert/alert.service.ts:115
|
||||||||||||
|
Updates the alert with the specified changes.
Parameters :
Returns :
Promise<Alert>
A Promise that resolves to the updated alert object. |
| Async updateAlertCheckTimes | ||||||||||||
updateAlertCheckTimes(alert: Alert, checkTime: Date)
|
||||||||||||
|
Defined in src/alert/alert.service.ts:171
|
||||||||||||
|
Updates the alert check times.
Parameters :
Returns :
Promise<Alert>
A Promise that resolves to the updated alert object. |
| Async updateAlertStatus | ||||||||||||
updateAlertStatus(alertId: number, status: AlertStatus)
|
||||||||||||
|
Defined in src/alert/alert.service.ts:149
|
||||||||||||
|
Updates the status of an alert with the specified ID.
Parameters :
Returns :
Promise<Alert>
A Promise that resolves to the updated alert object. |
| validateAlertThresholds | ||||||||||||
validateAlertThresholds(alert: Alert, targets: any[])
|
||||||||||||
|
Defined in src/alert/alert.service.ts:335
|
||||||||||||
|
Validates alert thresholds.
Parameters :
Returns :
literal type[]
A Promise that resolves to an array. |
| Public alertCategoryToFieldMap |
Type : object
|
Default value : {
[AlertCategory.METRIC]: "value",
DEFAULT: "value",
}
|
|
Defined in src/alert/alert.service.ts:19
|
| Public alertCategoryToTableMap |
Type : object
|
Default value : {
[AlertCategory.METRIC]: "metricsData",
}
|
|
Defined in src/alert/alert.service.ts:24
|
import { Injectable } from "@nestjs/common";
import { PrismaService } from "../common/prisma/prisma.service";
import { CreateAlertDto } from "./dto/create-alert.dto";
import {
Alert,
AlertCategory,
AlertCheckType,
AlertStatus,
AlertType,
} from "./entities/alert.entity";
import { UpdateAlertDto } from "./dto/update-alert.dto";
import { AlertParams } from "./types/alert-params.type";
import { Thresholds } from "./types/thresholds.type";
import { AlertTrigger } from "./entities/alert-trigger.entity";
import { Prisma } from "@prisma/client";
@Injectable()
export class AlertService {
public alertCategoryToFieldMap = {
[AlertCategory.METRIC]: "value",
DEFAULT: "value",
};
public alertCategoryToTableMap = {
[AlertCategory.METRIC]: "metricsData",
};
constructor(private readonly prismaService: PrismaService) {}
/**
* Returns thresholds for the given AlertParams
* @param {AlertParams} alertParams The given AlertParams
* @returns {Thresholds} A Promise that resolves to thresholds
* @throws {Error} If there are issues during the threshold calculation
*/
getThresholds(alertParams: AlertParams, alertType: AlertType) {
let min = null;
let max = null;
if ([AlertType.MIN, AlertType.MIN_MAX].includes(alertType)) {
min = alertParams.min;
}
if ([AlertType.MAX, AlertType.MIN_MAX].includes(alertType)) {
max = alertParams.max;
}
if ([AlertType.PCC_MIN, AlertType.PCC].includes(alertType)) {
min = (1 - alertParams.pcc / 100) * alertParams.initValue;
}
if ([AlertType.PCC_MAX, AlertType.PCC].includes(alertType)) {
max = (1 + alertParams.pcc / 100) * alertParams.initValue;
}
return new Thresholds({ min: min, max: max });
}
getDiff(
alertParams: AlertParams,
alertTrigger: AlertTrigger,
pcc: boolean = false,
) {
let diffVal = alertTrigger.targetValue - alertParams.initValue;
if (pcc) {
diffVal = (diffVal / alertParams.initValue) * 100;
}
return diffVal;
}
/**
* Creates a new alert
* @param {CreateAlertDto} createAlertInput - The data object containing information to create the alert.
* @returns {Promise<Alert>} A Promise that resolves to the created alert object.
* @throws {Error} If there are issues during the alert creation process.
*/
async create(
createAlertInput: CreateAlertDto,
userId: string,
): Promise<Alert> {
const alertData = {
name: createAlertInput.name,
projectId: createAlertInput.projectId,
userId: userId,
category: createAlertInput.category,
status: AlertStatus.ACTIVE,
type: createAlertInput.type,
checkType: AlertCheckType.VALUE,
interval: createAlertInput.interval,
targetTable: this.alertCategoryToTableMap[createAlertInput.category],
targetField: this.alertCategoryToFieldMap.DEFAULT,
targetFilter: JSON.stringify(createAlertInput.targetFilter),
thresholds: JSON.stringify(
this.getThresholds(createAlertInput.alertParams, createAlertInput.type),
),
alertParams: JSON.stringify(createAlertInput.alertParams),
};
if (alertData.category == AlertCategory.METRIC) {
alertData.checkType = AlertCheckType.WINDOW;
alertData.targetField = this.alertCategoryToFieldMap[alertData.category];
}
const alert = await this.prismaService.alert.create({
data: alertData,
});
return new Alert(alert);
}
/**
* Updates the alert with the specified changes.
* @param {number} id - The ID of the alert to update.
* @param {UpdateAlertDto} updateAlertInput - The data to be updated.
* @returns {Promise<Alert>} A Promise that resolves to the updated alert object.
* @throws {Error} If there are issues updating the alert status.
*/
async update(id: number, updateAlertInput: UpdateAlertDto): Promise<Alert> {
const alert = await this.getAlert(id);
const alertData = {
name: updateAlertInput.name,
interval: updateAlertInput.interval,
status: updateAlertInput.status,
type: updateAlertInput.type,
};
if (updateAlertInput.alertParams) {
alertData["alertParams"] = JSON.stringify(updateAlertInput.alertParams);
alertData["thresholds"] = JSON.stringify(
this.getThresholds(updateAlertInput.alertParams, AlertType[alert.type]),
);
}
const updatedAlert: Alert = new Alert(
await this.prismaService.alert.update({
where: {
id: id,
},
data: alertData,
}),
);
return updatedAlert;
}
/**
* Updates the status of an alert with the specified ID.
* @param {number} alertId - The ID of the alert to update.
* @param {AlertStatus} status - The new status to assign to the alert.
* @returns {Promise<Alert>} A Promise that resolves to the updated alert object.
* @throws {Error} If there are issues updating the alert status.
*/
async updateAlertStatus(
alertId: number,
status: AlertStatus,
): Promise<Alert> {
const alert = await this.prismaService.alert.update({
where: {
id: alertId,
},
data: {
status: status,
},
});
return new Alert(alert);
}
/**
* Updates the alert check times.
* @param {Alert} alert - alert
* @param {Date} checkTime - The time when the check was performed.
* @returns {Promise<Alert>} A Promise that resolves to the updated alert object.
* @throws {Error} If there are issues updating the alert status.
*/
async updateAlertCheckTimes(alert: Alert, checkTime: Date): Promise<Alert> {
const lastCheckAt = new Date(checkTime.getTime());
const nextCheckAt = new Date(checkTime.getTime() + alert.interval * 1000);
const updatedAlert = await this.prismaService.alert.update({
where: {
id: alert.id,
},
data: {
lastCheckAt: lastCheckAt,
nextCheckAt: nextCheckAt,
},
});
return new Alert(updatedAlert);
}
/**
* Finds and returns the alert with the specified ID.
* @param {number} alertId - The ID of the alert to find.
* @returns {Promise<Alert>} A Promise that resolves to the found alert object.
* @throws {Error} If there are issues finding the alert.
*/
async getAlert(alertId: number): Promise<Alert> {
const alert = await this.prismaService.alert.findFirst({
where: { id: alertId },
});
return new Alert(alert);
}
/**
* Finds and returns alerts associated with the specified project ID.
* @param {number} projectId - The ID of the project for which to find alerts.
* @returns {Promise<Alert[]>} A Promise that resolves to an array of alerts associated with the project.
* @throws {Error} If there are issues finding alerts for the project.
*/
async getAlertsByProjectID(projectId: number): Promise<Alert[]> {
const alerts = await this.prismaService.alert.findMany({
where: {
projectId: projectId,
NOT: { status: { equals: AlertStatus.DELETED } },
},
});
return alerts.map((alert) => new Alert(alert));
}
/**
* Finds and returns alerts based on query.
* @param {Prisma.AlertWhereInput} query - query
* @returns {Promise<Alert[]>} A Promise that resolves to an array of alerts associated with the project.
* @throws {Error} If there are issues finding alerts.
*/
async findMany(query: Prisma.AlertWhereInput) {
const alerts = await this.prismaService.alert.findMany({ where: query });
return alerts.map((alert) => new Alert(alert));
}
/**
* Finds and returns alerts which are due to be checked.
* Returns alerts that have nextCheckAt less than current time.
* @returns {Promise<Alert[]>} A Promise that resolves to an array of alerts.
* @throws {Error} If there are issues finding alerts.
*/
async getDueAlerts(): Promise<Alert[]> {
const alerts = await this.prismaService.alert.findMany({
where: {
nextCheckAt: { lte: new Date() },
NOT: {
OR: [{ status: { equals: AlertStatus.INPROGRESS } }],
},
},
});
return alerts.map((alert) => new Alert(alert));
}
/**
* Finds and returns alert trigger events.
* @param {} query - ALertTriggers query
* @returns {Promise<AlertTrigger[]>} A Promise that resolves to an array of alerts.
* @throws {Error} If there are issues finding alerts.
*/
async getAlertTriggers(query: {
alertId?: number[];
targetTable?: string[];
targetField?: string[];
targetId?: number[];
startTime?: Date;
endTime?: Date;
}): Promise<AlertTrigger[]> {
const queryOptions = {
alertId: { in: query.alertId },
targetTable: { in: query.targetTable },
targetField: { in: query.targetField },
targetId: { in: query.targetId },
};
const events = await this.prismaService.alertTrigger.findMany({
where: {
timestamp: { gte: query.startTime, lte: query.endTime },
...queryOptions,
},
});
return events.map((event) => new AlertTrigger(event));
}
/**
* Finds and returns alert targets.
* @param {Alert} alert - alert
* @returns {Promise<{targets: any[], targetTime: string, targetFilter: any}>} A Promise that resolves to an object.
* @throws {Error} If there are issues finding target.
*/
async getAlertTargets(
alert: Alert,
): Promise<{ targets: any[]; targetTime: string; targetFilter: any }> {
const checkTime = new Date();
const targetFilter = JSON.parse(alert.targetFilter);
const targetTable = alert.targetTable;
if (alert.checkType == AlertCheckType.WINDOW) {
targetFilter["createdAt"] = {
gt: alert.lastCheckAt,
lte: checkTime,
};
}
const targets = await this.prismaService[targetTable].findMany({
where: { ...targetFilter },
});
return {
targets: targets,
targetTime: checkTime.toString(),
targetFilter: targetFilter,
};
}
checkValue(value, thresholds) {
let valid = true;
let minBreach = false;
let maxBreach = false;
if (thresholds["min"]) {
if (thresholds["min"] > value) {
valid = false;
minBreach = true;
}
}
if (thresholds["max"]) {
if (value > thresholds["max"]) {
valid = false;
maxBreach = true;
}
}
return { valid, minBreach, maxBreach };
}
/**
* Validates alert thresholds.
* @param {Alert} alert - alert
* @param {any[]} targets - target array
* @returns {Promise<{valid: boolean, target: any}[]>} A Promise that resolves to an array.
* @throws {Error} If there are issues finding target.
*/
validateAlertThresholds(
alert: Alert,
targets: any[],
): { valid: boolean; target: any }[] {
const thresholds = JSON.parse(alert.thresholds);
return targets.map((target) => {
const result = this.checkValue(target[alert.targetField], thresholds);
return {
...result,
target: target,
};
});
}
/**
* Retrieves alerts for a specific user with pagination.
*
* @param {string} userId - The ID of the user to retrieve alerts for.
* @param {number} page - The page number for pagination (default is 1).
* @param {number} limit - The number of alerts per page (default is 10).
* @returns {Promise<Alert[]>} A Promise that resolves to an array of alerts for the specified user.
* @throws {Error} If there are issues during the alert search process.
*/
async findAllByUserId(
userId: string,
queryOptions: {
pageSize?: number;
pageOffset?: number;
startId?: number;
} = {},
): Promise<Alert[]> {
const pageSize = +queryOptions.pageSize || 30;
const pageOffset = +queryOptions.pageOffset || 0;
const findArgs = {
where: {
userId: userId,
NOT: {
OR: [{ status: { equals: AlertStatus.DELETED } }],
},
},
take: Math.min(100, pageSize), // Limit the number of messages returned
skip: pageOffset * pageSize, // Offset based on the page number and page size
};
const alerts = await this.prismaService.alert.findMany(findArgs);
return alerts.map((alert) => new Alert(alert));
}
}