feat(core): Workflow Execution Statistics (#4200)
Add recording and reporting of workflow execution statistics
This commit is contained in:
@@ -13,6 +13,7 @@ import {
|
||||
Column,
|
||||
Entity,
|
||||
Index,
|
||||
JoinColumn,
|
||||
JoinTable,
|
||||
ManyToMany,
|
||||
OneToMany,
|
||||
@@ -24,6 +25,7 @@ import { TagEntity } from './TagEntity';
|
||||
import { SharedWorkflow } from './SharedWorkflow';
|
||||
import { objectRetriever, sqlite } from '../utils/transformers';
|
||||
import { AbstractEntity, jsonColumnType } from './AbstractEntity';
|
||||
import { WorkflowStatistics } from './WorkflowStatistics';
|
||||
import type { IWorkflowDb } from '@/Interfaces';
|
||||
|
||||
@Entity()
|
||||
@@ -78,6 +80,16 @@ export class WorkflowEntity extends AbstractEntity implements IWorkflowDb {
|
||||
@OneToMany(() => SharedWorkflow, (sharedWorkflow) => sharedWorkflow.workflow)
|
||||
shared: SharedWorkflow[];
|
||||
|
||||
@OneToMany(
|
||||
() => WorkflowStatistics,
|
||||
(workflowStatistics: WorkflowStatistics) => workflowStatistics.workflow,
|
||||
)
|
||||
@JoinColumn({ referencedColumnName: 'workflow' })
|
||||
statistics: WorkflowStatistics[];
|
||||
|
||||
@Column({ default: false })
|
||||
dataLoaded: boolean;
|
||||
|
||||
@Column({
|
||||
type: config.getEnv('database.type') === 'sqlite' ? 'text' : 'json',
|
||||
nullable: true,
|
||||
|
||||
32
packages/cli/src/databases/entities/WorkflowStatistics.ts
Normal file
32
packages/cli/src/databases/entities/WorkflowStatistics.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { Column, Entity, RelationId, ManyToOne, PrimaryColumn } from 'typeorm';
|
||||
import { datetimeColumnType } from './AbstractEntity';
|
||||
import { WorkflowEntity } from './WorkflowEntity';
|
||||
|
||||
export enum StatisticsNames {
|
||||
productionSuccess = 'production_success',
|
||||
productionError = 'production_error',
|
||||
manualSuccess = 'manual_success',
|
||||
manualError = 'manual_error',
|
||||
}
|
||||
|
||||
@Entity()
|
||||
export class WorkflowStatistics {
|
||||
@Column()
|
||||
count: number;
|
||||
|
||||
@Column(datetimeColumnType)
|
||||
latestEvent: Date;
|
||||
|
||||
@PrimaryColumn({ length: 128 })
|
||||
name: StatisticsNames;
|
||||
|
||||
@ManyToOne(() => WorkflowEntity, (workflow) => workflow.shared, {
|
||||
primary: true,
|
||||
onDelete: 'CASCADE',
|
||||
})
|
||||
workflow: WorkflowEntity;
|
||||
|
||||
@RelationId((workflowStatistics: WorkflowStatistics) => workflowStatistics.workflow)
|
||||
@PrimaryColumn()
|
||||
workflowId: number;
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import { SharedWorkflow } from './SharedWorkflow';
|
||||
import { SharedCredentials } from './SharedCredentials';
|
||||
import { InstalledPackages } from './InstalledPackages';
|
||||
import { InstalledNodes } from './InstalledNodes';
|
||||
import { WorkflowStatistics } from './WorkflowStatistics';
|
||||
|
||||
export const entities = {
|
||||
CredentialsEntity,
|
||||
@@ -25,4 +26,5 @@ export const entities = {
|
||||
SharedCredentials,
|
||||
InstalledPackages,
|
||||
InstalledNodes,
|
||||
WorkflowStatistics,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
import { logMigrationEnd, logMigrationStart } from '../../utils/migrationHelpers';
|
||||
import config from '@/config';
|
||||
|
||||
export class WorkflowStatistics1664196174002 implements MigrationInterface {
|
||||
name = 'WorkflowStatistics1664196174002';
|
||||
|
||||
async up(queryRunner: QueryRunner): Promise<void> {
|
||||
logMigrationStart(this.name);
|
||||
|
||||
const tablePrefix = config.getEnv('database.tablePrefix');
|
||||
|
||||
await queryRunner.query(
|
||||
`CREATE TABLE ${tablePrefix}workflow_statistics (
|
||||
count INTEGER DEFAULT 0,
|
||||
latestEvent DATETIME,
|
||||
name VARCHAR(128) NOT NULL,
|
||||
workflowId INTEGER,
|
||||
PRIMARY KEY(workflowId, name),
|
||||
FOREIGN KEY(workflowId) REFERENCES ${tablePrefix}workflow_entity(id) ON DELETE CASCADE
|
||||
)`,
|
||||
);
|
||||
|
||||
// Add dataLoaded column to workflow table
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE ${tablePrefix}workflow_entity ADD COLUMN dataLoaded BOOLEAN DEFAULT false`,
|
||||
);
|
||||
|
||||
logMigrationEnd(this.name);
|
||||
}
|
||||
|
||||
async down(queryRunner: QueryRunner): Promise<void> {
|
||||
const tablePrefix = config.getEnv('database.tablePrefix');
|
||||
|
||||
await queryRunner.query(`DROP TABLE "${tablePrefix}workflow_statistics"`);
|
||||
await queryRunner.query(`ALTER TABLE ${tablePrefix}workflow_entity DROP COLUMN dataLoaded`);
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import { IntroducePinData1654090101303 } from './1654090101303-IntroducePinData'
|
||||
import { AddNodeIds1658932910559 } from './1658932910559-AddNodeIds';
|
||||
import { AddJsonKeyPinData1659895550980 } from './1659895550980-AddJsonKeyPinData';
|
||||
import { CreateCredentialsUserRole1660062385367 } from './1660062385367-CreateCredentialsUserRole';
|
||||
import { WorkflowStatistics1664196174002 } from './1664196174002-WorkflowStatistics';
|
||||
import { CreateWorkflowsEditorRole1663755770894 } from './1663755770894-CreateWorkflowsEditorRole';
|
||||
import { CreateCredentialUsageTable1665484192213 } from './1665484192213-CreateCredentialUsageTable';
|
||||
import { RemoveCredentialUsageTable1665754637026 } from './1665754637026-RemoveCredentialUsageTable';
|
||||
@@ -52,4 +53,5 @@ export const mysqlMigrations = [
|
||||
CreateCredentialUsageTable1665484192213,
|
||||
RemoveCredentialUsageTable1665754637026,
|
||||
AddWorkflowVersionIdColumn1669739707125,
|
||||
WorkflowStatistics1664196174002,
|
||||
];
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
import { getTablePrefix, logMigrationEnd, logMigrationStart } from '../../utils/migrationHelpers';
|
||||
import config from '@/config';
|
||||
|
||||
export class WorkflowStatistics1664196174001 implements MigrationInterface {
|
||||
name = 'WorkflowStatistics1664196174001';
|
||||
|
||||
async up(queryRunner: QueryRunner): Promise<void> {
|
||||
logMigrationStart(this.name);
|
||||
const tablePrefix = getTablePrefix();
|
||||
|
||||
// Create statistics table
|
||||
await queryRunner.query(
|
||||
`CREATE TABLE ${tablePrefix}workflow_statistics (
|
||||
"count" INTEGER DEFAULT 0,
|
||||
"latestEvent" TIMESTAMP,
|
||||
"name" VARCHAR(128) NOT NULL,
|
||||
"workflowId" INTEGER,
|
||||
PRIMARY KEY("workflowId", "name"),
|
||||
FOREIGN KEY("workflowId") REFERENCES ${tablePrefix}workflow_entity("id") ON DELETE CASCADE
|
||||
)`,
|
||||
);
|
||||
|
||||
// Add dataLoaded column to workflow table
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE ${tablePrefix}workflow_entity ADD COLUMN "dataLoaded" BOOLEAN DEFAULT false;`,
|
||||
);
|
||||
|
||||
logMigrationEnd(this.name);
|
||||
}
|
||||
|
||||
async down(queryRunner: QueryRunner): Promise<void> {
|
||||
let tablePrefix = config.getEnv('database.tablePrefix');
|
||||
const schema = config.getEnv('database.postgresdb.schema');
|
||||
if (schema) {
|
||||
tablePrefix = schema + '.' + tablePrefix;
|
||||
}
|
||||
|
||||
await queryRunner.query(`DROP TABLE ${tablePrefix}workflow_statistics`);
|
||||
await queryRunner.query(`ALTER TABLE ${tablePrefix}workflow_entity DROP COLUMN dataLoaded`);
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import { IntroducePinData1654090467022 } from './1654090467022-IntroducePinData'
|
||||
import { AddNodeIds1658932090381 } from './1658932090381-AddNodeIds';
|
||||
import { AddJsonKeyPinData1659902242948 } from './1659902242948-AddJsonKeyPinData';
|
||||
import { CreateCredentialsUserRole1660062385367 } from './1660062385367-CreateCredentialsUserRole';
|
||||
import { WorkflowStatistics1664196174001 } from './1664196174001-WorkflowStatistics';
|
||||
import { CreateWorkflowsEditorRole1663755770893 } from './1663755770893-CreateWorkflowsEditorRole';
|
||||
import { CreateCredentialUsageTable1665484192212 } from './1665484192212-CreateCredentialUsageTable';
|
||||
import { RemoveCredentialUsageTable1665754637025 } from './1665754637025-RemoveCredentialUsageTable';
|
||||
@@ -48,4 +49,5 @@ export const postgresMigrations = [
|
||||
CreateCredentialUsageTable1665484192212,
|
||||
RemoveCredentialUsageTable1665754637025,
|
||||
AddWorkflowVersionIdColumn1669739707126,
|
||||
WorkflowStatistics1664196174001,
|
||||
];
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
import { logMigrationEnd, logMigrationStart } from '../../utils/migrationHelpers';
|
||||
import config from '@/config';
|
||||
|
||||
export class WorkflowStatistics1664196174000 implements MigrationInterface {
|
||||
name = 'WorkflowStatistics1664196174000';
|
||||
|
||||
async up(queryRunner: QueryRunner): Promise<void> {
|
||||
logMigrationStart(this.name);
|
||||
|
||||
const tablePrefix = config.getEnv('database.tablePrefix');
|
||||
|
||||
await queryRunner.query(
|
||||
`CREATE TABLE \`${tablePrefix}workflow_statistics\` (
|
||||
"count" INTEGER DEFAULT 0,
|
||||
"latestEvent" DATETIME,
|
||||
"name" VARCHAR(128) NOT NULL,
|
||||
"workflowId" INTEGER,
|
||||
PRIMARY KEY("workflowId", "name"),
|
||||
FOREIGN KEY("workflowId") REFERENCES \`${tablePrefix}workflow_entity\`("id") ON DELETE CASCADE
|
||||
)`,
|
||||
);
|
||||
|
||||
// Add dataLoaded column to workflow table
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE \`${tablePrefix}workflow_entity\` ADD COLUMN "dataLoaded" BOOLEAN DEFAULT false`,
|
||||
);
|
||||
|
||||
logMigrationEnd(this.name);
|
||||
}
|
||||
|
||||
async down(queryRunner: QueryRunner): Promise<void> {
|
||||
const tablePrefix = config.getEnv('database.tablePrefix');
|
||||
|
||||
await queryRunner.query(`DROP TABLE "${tablePrefix}workflow_statistics"`);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE \`${tablePrefix}workflow_entity\` DROP COLUMN "dataLoaded"`,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import { IntroducePinData1654089251344 } from './1654089251344-IntroducePinData'
|
||||
import { AddNodeIds1658930531669 } from './1658930531669-AddNodeIds';
|
||||
import { AddJsonKeyPinData1659888469333 } from './1659888469333-AddJsonKeyPinData';
|
||||
import { CreateCredentialsUserRole1660062385367 } from './1660062385367-CreateCredentialsUserRole';
|
||||
import { WorkflowStatistics1664196174000 } from './1664196174000-WorkflowStatistics';
|
||||
import { CreateWorkflowsEditorRole1663755770892 } from './1663755770892-CreateWorkflowsUserRole';
|
||||
import { CreateCredentialUsageTable1665484192211 } from './1665484192211-CreateCredentialUsageTable';
|
||||
import { RemoveCredentialUsageTable1665754637024 } from './1665754637024-RemoveCredentialUsageTable';
|
||||
@@ -46,6 +47,7 @@ const sqliteMigrations = [
|
||||
CreateCredentialUsageTable1665484192211,
|
||||
RemoveCredentialUsageTable1665754637024,
|
||||
AddWorkflowVersionIdColumn1669739707124,
|
||||
WorkflowStatistics1664196174000,
|
||||
];
|
||||
|
||||
export { sqliteMigrations };
|
||||
|
||||
Reference in New Issue
Block a user