Skip to content

Commit

Permalink
Merge pull request #1746 from OneUptime/take-screenshot-on-incident-c…
Browse files Browse the repository at this point in the history
…reate

Take screenshot on incident create
  • Loading branch information
simlarsen authored Nov 13, 2024
2 parents aa95f89 + 4c6c138 commit 03e063c
Show file tree
Hide file tree
Showing 26 changed files with 574 additions and 275 deletions.
1 change: 0 additions & 1 deletion Common/Models/DatabaseModels/Alert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -801,7 +801,6 @@ export default class Alert extends BaseModel {
],
update: [],
})
@Index()
@TableColumn({
type: TableColumnType.Markdown,
required: false,
Expand Down
1 change: 0 additions & 1 deletion Common/Models/DatabaseModels/Incident.ts
Original file line number Diff line number Diff line change
Expand Up @@ -855,7 +855,6 @@ export default class Incident extends BaseModel {
],
update: [],
})
@Index()
@TableColumn({
type: TableColumnType.Markdown,
required: false,
Expand Down
1 change: 0 additions & 1 deletion Common/Models/DatabaseModels/IncidentStateTimeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,6 @@ export default class IncidentStateTimeline extends BaseModel {
],
update: [],
})
@Index()
@TableColumn({
type: TableColumnType.Markdown,
required: false,
Expand Down
1 change: 0 additions & 1 deletion Common/Models/DatabaseModels/MonitorStatusTimeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,6 @@ export default class MonitorStatusTimeline extends BaseModel {
],
update: [],
})
@Index()
@TableColumn({
type: TableColumnType.Markdown,
required: false,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { MigrationInterface, QueryRunner } from "typeorm";

export class MigrationName1731433043136 implements MigrationInterface {
public name = "MigrationName1731433043136";

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`DROP INDEX "public"."IDX_5218e92f700d91afe6a8db79cb"`,
);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE INDEX "IDX_5218e92f700d91afe6a8db79cb" ON "Incident" ("rootCause") `,
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { MigrationInterface, QueryRunner } from "typeorm";

export class MigrationName1731433309124 implements MigrationInterface {
public name = "MigrationName1731433309124";

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`DROP INDEX "public"."IDX_fc40ea6a9ad55f29bca4f4a15d"`,
);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE INDEX "IDX_fc40ea6a9ad55f29bca4f4a15d" ON "Alert" ("rootCause") `,
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { MigrationInterface, QueryRunner } from "typeorm";

export class MigrationName1731435267537 implements MigrationInterface {
public name = "MigrationName1731435267537";

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`DROP INDEX "public"."IDX_01ac1d1ef9e72aeb6dac6575dd"`,
);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE INDEX "IDX_01ac1d1ef9e72aeb6dac6575dd" ON "MonitorStatusTimeline" ("rootCause") `,
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { MigrationInterface, QueryRunner } from "typeorm";

export class MigrationName1731435514287 implements MigrationInterface {
public name = "MigrationName1731435514287";

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`DROP INDEX "public"."IDX_7db6b1a8fbbc9eb44c2e7f5047"`,
);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE INDEX "IDX_7db6b1a8fbbc9eb44c2e7f5047" ON "IncidentStateTimeline" ("rootCause") `,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ import { MigrationName1729682875503 } from "./1729682875503-MigrationName";
import { MigrationName1730117995642 } from "./1730117995642-MigrationName";
import { MigrationName1730209089495 } from "./1730209089495-MigrationName";
import { MigrationName1730223198692 } from "./1730223198692-MigrationName";
import { MigrationName1731433043136 } from "./1731433043136-MigrationName";
import { MigrationName1731433309124 } from "./1731433309124-MigrationName";
import { MigrationName1731435267537 } from "./1731435267537-MigrationName";
import { MigrationName1731435514287 } from "./1731435514287-MigrationName";

export default [
InitialMigration,
Expand Down Expand Up @@ -160,4 +164,8 @@ export default [
MigrationName1730117995642,
MigrationName1730209089495,
MigrationName1730223198692,
MigrationName1731433043136,
MigrationName1731433309124,
MigrationName1731435267537,
MigrationName1731435514287,
];
192 changes: 192 additions & 0 deletions Common/Server/Utils/Browser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
import {
Page as PlaywrightPage,
Browser as PlaywrightBrowser,
chromium,
firefox,
} from "playwright";
import LocalFile from "./LocalFile";
import BadDataException from "../../Types/Exception/BadDataException";
import ScreenSizeType from "../../Types/ScreenSizeType";
import BrowserType from "../../Types/BrowserType";
import logger from "./Logger";

export type Page = PlaywrightPage;
export type Browser = PlaywrightBrowser;

export default class BrowserUtil {
public static async convertHtmlToBase64Screenshot(data: {
html: string;
}): Promise<string | null> {
try {
const html: string = data.html;

const pageAndBrowser: {
page: Page;
browser: Browser;
} = await BrowserUtil.getPageByBrowserType({
browserType: BrowserType.Chromium,
screenSizeType: ScreenSizeType.Desktop,
});

const page: Page = pageAndBrowser.page;
const browser: Browser = pageAndBrowser.browser;
await page.setContent(html);
const screenshot: Buffer = await page.screenshot({ type: "png" });

await browser.close();

return screenshot.toString("base64");
} catch (e) {
logger.debug(e);
return null;
}
}

public static async getPageByBrowserType(data: {
browserType: BrowserType;
screenSizeType: ScreenSizeType;
}): Promise<{
page: Page;
browser: Browser;
}> {
const viewport: {
height: number;
width: number;
} = BrowserUtil.getViewportHeightAndWidth({
screenSizeType: data.screenSizeType,
});

let page: Page | null = null;
let browser: Browser | null = null;

if (data.browserType === BrowserType.Chromium) {
browser = await chromium.launch({
executablePath: await BrowserUtil.getChromeExecutablePath(),
});
page = await browser.newPage();
}

if (data.browserType === BrowserType.Firefox) {
browser = await firefox.launch({
executablePath: await BrowserUtil.getFirefoxExecutablePath(),
});
page = await browser.newPage();
}

// if (data.browserType === BrowserType.Webkit) {
// browser = await webkit.launch();
// page = await browser.newPage();
// }

await page?.setViewportSize({
width: viewport.width,
height: viewport.height,
});

if (!browser) {
throw new BadDataException("Invalid Browser Type.");
}

if (!page) {
// close the browser if page is not created
await browser.close();
throw new BadDataException("Invalid Browser Type.");
}

return {
page: page,
browser: browser,
};
}

public static getViewportHeightAndWidth(options: {
screenSizeType: ScreenSizeType;
}): {
height: number;
width: number;
} {
let viewPortHeight: number = 0;
let viewPortWidth: number = 0;

switch (options.screenSizeType) {
case ScreenSizeType.Desktop:
viewPortHeight = 1080;
viewPortWidth = 1920;
break;
case ScreenSizeType.Mobile:
viewPortHeight = 640;
viewPortWidth = 360;
break;
case ScreenSizeType.Tablet:
viewPortHeight = 768;
viewPortWidth = 1024;
break;
default:
viewPortHeight = 1080;
viewPortWidth = 1920;
break;
}

return { height: viewPortHeight, width: viewPortWidth };
}

public static async getChromeExecutablePath(): Promise<string> {
const doesDirectoryExist: boolean = await LocalFile.doesDirectoryExist(
"/root/.cache/ms-playwright",
);
if (!doesDirectoryExist) {
throw new BadDataException("Chrome executable path not found.");
}

// get list of files in the directory
const directories: string[] = await LocalFile.getListOfDirectories(
"/root/.cache/ms-playwright",
);

if (directories.length === 0) {
throw new BadDataException("Chrome executable path not found.");
}

const chromeInstallationName: string | undefined = directories.find(
(directory: string) => {
return directory.includes("chromium");
},
);

if (!chromeInstallationName) {
throw new BadDataException("Chrome executable path not found.");
}

return `/root/.cache/ms-playwright/${chromeInstallationName}/chrome-linux/chrome`;
}

public static async getFirefoxExecutablePath(): Promise<string> {
const doesDirectoryExist: boolean = await LocalFile.doesDirectoryExist(
"/root/.cache/ms-playwright",
);
if (!doesDirectoryExist) {
throw new BadDataException("Firefox executable path not found.");
}

// get list of files in the directory
const directories: string[] = await LocalFile.getListOfDirectories(
"/root/.cache/ms-playwright",
);

if (directories.length === 0) {
throw new BadDataException("Firefox executable path not found.");
}

const firefoxInstallationName: string | undefined = directories.find(
(directory: string) => {
return directory.includes("firefox");
},
);

if (!firefoxInstallationName) {
throw new BadDataException("Firefox executable path not found.");
}

return `/root/.cache/ms-playwright/${firefoxInstallationName}/firefox/firefox`;
}
}
3 changes: 3 additions & 0 deletions Common/Server/Utils/Monitor/Criteria/CompareCriteria.ts
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,9 @@ export default class CompareCriteria {
case FilterType.NotEqualTo:
message += ` not equal to ${data.threshold}. `;
break;
case FilterType.EqualTo:
message += ` equal to ${data.threshold}. `;
break;
case FilterType.Contains:
message += ` contains ${data.threshold}. `;
break;
Expand Down
2 changes: 0 additions & 2 deletions Common/Server/Utils/Monitor/MonitorIncident.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,6 @@ export default class MonitorIncident {
continue;
}

// create incident here.

logger.debug(`${input.monitor.id?.toString()} - Create incident.`);

const incident: Incident = new Incident();
Expand Down
11 changes: 11 additions & 0 deletions Common/Types/Html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,15 @@ export default class HTML {
public toString(): string {
return this.html;
}

public static isHtml(text: string): boolean {
// Check if the text is HTML

// Example usage const htmlString = '<div>Hello, World!</div>'; const notHtmlString = 'Just a regular string'
// console.log(HTML.isHtml(htmlString)); // true
// console.log(HTML.isHtml(notHtmlString)); // false

const htmlPattern: RegExp = /<\/?[a-z][\s\S]*>/i;
return htmlPattern.test(text);
}
}
1 change: 1 addition & 0 deletions Common/UI/Components/ModelTable/TableView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ const TableViewElement: <T extends DatabaseBaseModel | AnalyticsBaseModel>(

elements.push(
<MoreMenuItem
key={"save-new-view"}
text="Save as New View"
className="bg-gray-50 hover:bg-gray-100 text-gray-700 hover:text-gray-900 font-medium -mt-2"
icon={IconProp.Add}
Expand Down
2 changes: 2 additions & 0 deletions Common/UI/Components/MoreMenu/MoreMenuItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ export interface ComponentProps {
rightElement?: Array<ReactElement> | ReactElement | undefined;
className?: string | undefined;
iconClassName?: string | undefined;
key: string | number;
}

const MoreMenuItem: FunctionComponent<ComponentProps> = (
props: ComponentProps,
): ReactElement => {
return (
<a
key={props.key}
className={`cursor-pointer group flex items-center px-4 py-2 text-sm text-gray-600 hover:text-gray-700 hover:bg-gray-50 ${props.className}`}
role="menuitem"
onClick={() => {
Expand Down
Loading

0 comments on commit 03e063c

Please sign in to comment.