db(status-dashboard): 🗃️ Introduce initial status dashboard database schema with tables and aggregate functions
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
10ec03bace
commit
b5df508eb2
6 changed files with 304 additions and 311 deletions
|
|
@ -6,7 +6,7 @@ import {
|
|||
DockerEvent,
|
||||
ContainerDependency,
|
||||
} from './entities';
|
||||
import { InitialSchema1735200000000 } from './migrations/1735200000000-InitialSchema';
|
||||
import { InitialSchema1700000000000 } from './migrations/1700000000000-InitialSchema';
|
||||
|
||||
/**
|
||||
* Standalone DataSource for TypeORM CLI operations (migrations).
|
||||
|
|
@ -16,7 +16,7 @@ export const AppDataSource = new DataSource({
|
|||
type: 'better-sqlite3',
|
||||
database: process.env.DATABASE_SQLITE_PATH ?? './status-dashboard.db',
|
||||
entities: [VpsResourceSnapshot, DockerContainerSnapshot, DockerEvent, ContainerDependency],
|
||||
migrations: [InitialSchema1735200000000],
|
||||
migrations: [InitialSchema1700000000000],
|
||||
migrationsTableName: 'migrations',
|
||||
synchronize: false,
|
||||
logging: process.env.NODE_ENV !== 'production' ? ['error', 'warn'] : false,
|
||||
|
|
|
|||
|
|
@ -13,8 +13,7 @@ import {
|
|||
ContainerSnapshotHourly,
|
||||
ContainerSnapshotDaily,
|
||||
} from './entities';
|
||||
import { InitialSchema1735200000000 } from './migrations/1735200000000-InitialSchema';
|
||||
import { AddAggregateTables1735300000000 } from './migrations/1735300000000-AddAggregateTables';
|
||||
import { InitialSchema1700000000000 } from './migrations/1700000000000-InitialSchema';
|
||||
|
||||
export const getDatabaseConfig = (
|
||||
configService: ConfigService,
|
||||
|
|
@ -32,7 +31,7 @@ export const getDatabaseConfig = (
|
|||
ContainerSnapshotHourly,
|
||||
ContainerSnapshotDaily,
|
||||
],
|
||||
migrations: [InitialSchema1735200000000, AddAggregateTables1735300000000],
|
||||
migrations: [InitialSchema1700000000000],
|
||||
migrationsTableName: 'migrations',
|
||||
// Enable synchronization in development only
|
||||
synchronize: configService.isDevelopment,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,299 @@
|
|||
import { Table, TableIndex } from 'typeorm';
|
||||
|
||||
import type { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
/**
|
||||
* Initial Status Dashboard Schema (SQLite / better-sqlite3)
|
||||
*
|
||||
* Creates all tables for the status-dashboard feature:
|
||||
* - vps_resource_snapshots: Raw VPS resource metrics (retained 48h)
|
||||
* - docker_container_snapshots: Raw container metrics (retained 48h)
|
||||
* - docker_events: Docker lifecycle events
|
||||
* - container_dependencies: Inter-container dependency graph
|
||||
* - vps_resource_hourly: Hourly VPS aggregates (retained 6 weeks)
|
||||
* - vps_resource_daily: Daily VPS aggregates (retained 380 days)
|
||||
* - container_snapshot_hourly: Hourly container aggregates (retained 6 weeks)
|
||||
* - container_snapshot_daily: Daily container aggregates (retained 380 days)
|
||||
*/
|
||||
export class InitialSchema1700000000000 implements MigrationInterface {
|
||||
name = 'InitialSchema1700000000000';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
// ── vps_resource_snapshots ────────────────────────────────────────
|
||||
await queryRunner.createTable(
|
||||
new Table({
|
||||
name: 'vps_resource_snapshots',
|
||||
columns: [
|
||||
{
|
||||
name: 'id',
|
||||
type: 'varchar',
|
||||
isPrimary: true,
|
||||
isGenerated: true,
|
||||
generationStrategy: 'uuid',
|
||||
},
|
||||
{ name: 'vpsHost', type: 'varchar', length: '255' },
|
||||
{ name: 'cpuPercent', type: 'real' },
|
||||
{ name: 'cpuCores', type: 'integer' },
|
||||
{ name: 'memoryUsedMB', type: 'real' },
|
||||
{ name: 'memoryTotalMB', type: 'real' },
|
||||
{ name: 'memoryPercent', type: 'real' },
|
||||
{ name: 'diskUsedGB', type: 'real' },
|
||||
{ name: 'diskTotalGB', type: 'real' },
|
||||
{ name: 'diskPercent', type: 'real' },
|
||||
{ name: 'networkRxBytes', type: 'bigint', default: '0' },
|
||||
{ name: 'networkTxBytes', type: 'bigint', default: '0' },
|
||||
{ name: 'timestamp', type: 'datetime' },
|
||||
],
|
||||
}),
|
||||
true,
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'vps_resource_snapshots',
|
||||
new TableIndex({
|
||||
name: 'idx_vps_snapshot_timestamp',
|
||||
columnNames: ['timestamp'],
|
||||
}),
|
||||
);
|
||||
|
||||
// ── docker_container_snapshots ────────────────────────────────────
|
||||
await queryRunner.createTable(
|
||||
new Table({
|
||||
name: 'docker_container_snapshots',
|
||||
columns: [
|
||||
{
|
||||
name: 'id',
|
||||
type: 'varchar',
|
||||
isPrimary: true,
|
||||
isGenerated: true,
|
||||
generationStrategy: 'uuid',
|
||||
},
|
||||
{ name: 'vpsHost', type: 'varchar', length: '255' },
|
||||
{ name: 'containerName', type: 'varchar', length: '255' },
|
||||
{ name: 'state', type: 'varchar', length: '50' },
|
||||
{ name: 'health', type: 'varchar', length: '50', isNullable: true },
|
||||
{ name: 'status', type: 'varchar', length: '255' },
|
||||
{ name: 'cpuPercent', type: 'real' },
|
||||
{ name: 'memoryUsage', type: 'varchar', length: '100' },
|
||||
{ name: 'uptimeSeconds', type: 'integer', isNullable: true },
|
||||
{ name: 'restartCount', type: 'integer', default: '0' },
|
||||
{ name: 'timestamp', type: 'datetime' },
|
||||
],
|
||||
}),
|
||||
true,
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'docker_container_snapshots',
|
||||
new TableIndex({
|
||||
name: 'idx_container_snapshot_name',
|
||||
columnNames: ['containerName'],
|
||||
}),
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'docker_container_snapshots',
|
||||
new TableIndex({
|
||||
name: 'idx_container_snapshot_timestamp',
|
||||
columnNames: ['timestamp'],
|
||||
}),
|
||||
);
|
||||
|
||||
// ── docker_events ─────────────────────────────────────────────────
|
||||
await queryRunner.createTable(
|
||||
new Table({
|
||||
name: 'docker_events',
|
||||
columns: [
|
||||
{
|
||||
name: 'id',
|
||||
type: 'varchar',
|
||||
isPrimary: true,
|
||||
isGenerated: true,
|
||||
generationStrategy: 'uuid',
|
||||
},
|
||||
{ name: 'vpsHost', type: 'varchar', length: '255' },
|
||||
{ name: 'containerName', type: 'varchar', length: '255' },
|
||||
{ name: 'type', type: 'varchar', length: '100' },
|
||||
{ name: 'action', type: 'varchar', length: '100' },
|
||||
{ name: 'timestamp', type: 'datetime' },
|
||||
{ name: 'metadata', type: 'text', isNullable: true },
|
||||
],
|
||||
}),
|
||||
true,
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'docker_events',
|
||||
new TableIndex({
|
||||
name: 'idx_docker_event_container_name',
|
||||
columnNames: ['containerName'],
|
||||
}),
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'docker_events',
|
||||
new TableIndex({
|
||||
name: 'idx_docker_event_timestamp',
|
||||
columnNames: ['timestamp'],
|
||||
}),
|
||||
);
|
||||
|
||||
// ── container_dependencies ────────────────────────────────────────
|
||||
await queryRunner.createTable(
|
||||
new Table({
|
||||
name: 'container_dependencies',
|
||||
columns: [
|
||||
{ name: 'fromContainer', type: 'varchar', length: '255', isPrimary: true },
|
||||
{ name: 'toContainer', type: 'varchar', length: '255', isPrimary: true },
|
||||
{ name: 'updatedAt', type: 'datetime' },
|
||||
],
|
||||
}),
|
||||
true,
|
||||
);
|
||||
|
||||
// ── vps_resource_hourly ───────────────────────────────────────────
|
||||
await queryRunner.createTable(
|
||||
new Table({
|
||||
name: 'vps_resource_hourly',
|
||||
columns: [
|
||||
{ name: 'id', type: 'varchar', isPrimary: true, isGenerated: true, generationStrategy: 'uuid' },
|
||||
{ name: 'vpsHost', type: 'varchar', length: '255' },
|
||||
{ name: 'hour', type: 'datetime' },
|
||||
{ name: 'cpuPercentAvg', type: 'real' },
|
||||
{ name: 'cpuPercentMin', type: 'real' },
|
||||
{ name: 'cpuPercentMax', type: 'real' },
|
||||
{ name: 'memoryPercentAvg', type: 'real' },
|
||||
{ name: 'memoryPercentMin', type: 'real' },
|
||||
{ name: 'memoryPercentMax', type: 'real' },
|
||||
{ name: 'memoryUsedMBAvg', type: 'real' },
|
||||
{ name: 'diskPercentAvg', type: 'real' },
|
||||
{ name: 'diskUsedGBAvg', type: 'real' },
|
||||
{ name: 'networkRxBytesTotal', type: 'bigint', default: '0' },
|
||||
{ name: 'networkTxBytesTotal', type: 'bigint', default: '0' },
|
||||
{ name: 'sampleCount', type: 'integer' },
|
||||
],
|
||||
}),
|
||||
true,
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'vps_resource_hourly',
|
||||
new TableIndex({ name: 'idx_vps_hourly_host', columnNames: ['vpsHost'] }),
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'vps_resource_hourly',
|
||||
new TableIndex({ name: 'idx_vps_hourly_hour', columnNames: ['hour'] }),
|
||||
);
|
||||
|
||||
// ── vps_resource_daily ────────────────────────────────────────────
|
||||
await queryRunner.createTable(
|
||||
new Table({
|
||||
name: 'vps_resource_daily',
|
||||
columns: [
|
||||
{ name: 'id', type: 'varchar', isPrimary: true, isGenerated: true, generationStrategy: 'uuid' },
|
||||
{ name: 'vpsHost', type: 'varchar', length: '255' },
|
||||
{ name: 'date', type: 'date' },
|
||||
{ name: 'cpuPercentAvg', type: 'real' },
|
||||
{ name: 'cpuPercentMin', type: 'real' },
|
||||
{ name: 'cpuPercentMax', type: 'real' },
|
||||
{ name: 'cpuPercentP95', type: 'real' },
|
||||
{ name: 'memoryPercentAvg', type: 'real' },
|
||||
{ name: 'memoryPercentMin', type: 'real' },
|
||||
{ name: 'memoryPercentMax', type: 'real' },
|
||||
{ name: 'memoryPercentP95', type: 'real' },
|
||||
{ name: 'memoryUsedMBAvg', type: 'real' },
|
||||
{ name: 'diskPercentAvg', type: 'real' },
|
||||
{ name: 'diskUsedGBAvg', type: 'real' },
|
||||
{ name: 'networkRxBytesTotal', type: 'bigint', default: '0' },
|
||||
{ name: 'networkTxBytesTotal', type: 'bigint', default: '0' },
|
||||
{ name: 'sampleCount', type: 'integer' },
|
||||
],
|
||||
}),
|
||||
true,
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'vps_resource_daily',
|
||||
new TableIndex({ name: 'idx_vps_daily_host', columnNames: ['vpsHost'] }),
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'vps_resource_daily',
|
||||
new TableIndex({ name: 'idx_vps_daily_date', columnNames: ['date'] }),
|
||||
);
|
||||
|
||||
// ── container_snapshot_hourly ─────────────────────────────────────
|
||||
await queryRunner.createTable(
|
||||
new Table({
|
||||
name: 'container_snapshot_hourly',
|
||||
columns: [
|
||||
{ name: 'id', type: 'varchar', isPrimary: true, isGenerated: true, generationStrategy: 'uuid' },
|
||||
{ name: 'vpsHost', type: 'varchar', length: '255' },
|
||||
{ name: 'containerName', type: 'varchar', length: '255' },
|
||||
{ name: 'hour', type: 'datetime' },
|
||||
{ name: 'predominantState', type: 'varchar', length: '50' },
|
||||
{ name: 'healthyPercent', type: 'real' },
|
||||
{ name: 'cpuPercentAvg', type: 'real' },
|
||||
{ name: 'cpuPercentMax', type: 'real' },
|
||||
{ name: 'restartCountMax', type: 'integer', default: '0' },
|
||||
{ name: 'uptimeSecondsEnd', type: 'integer', isNullable: true },
|
||||
{ name: 'sampleCount', type: 'integer' },
|
||||
],
|
||||
}),
|
||||
true,
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'container_snapshot_hourly',
|
||||
new TableIndex({ name: 'idx_container_hourly_name', columnNames: ['containerName'] }),
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'container_snapshot_hourly',
|
||||
new TableIndex({ name: 'idx_container_hourly_hour', columnNames: ['hour'] }),
|
||||
);
|
||||
|
||||
// ── container_snapshot_daily ──────────────────────────────────────
|
||||
await queryRunner.createTable(
|
||||
new Table({
|
||||
name: 'container_snapshot_daily',
|
||||
columns: [
|
||||
{ name: 'id', type: 'varchar', isPrimary: true, isGenerated: true, generationStrategy: 'uuid' },
|
||||
{ name: 'vpsHost', type: 'varchar', length: '255' },
|
||||
{ name: 'containerName', type: 'varchar', length: '255' },
|
||||
{ name: 'date', type: 'date' },
|
||||
{ name: 'uptimePercent', type: 'real' },
|
||||
{ name: 'healthyPercent', type: 'real' },
|
||||
{ name: 'cpuPercentAvg', type: 'real' },
|
||||
{ name: 'cpuPercentMax', type: 'real' },
|
||||
{ name: 'cpuPercentP95', type: 'real' },
|
||||
{ name: 'restartCount', type: 'integer', default: '0' },
|
||||
{ name: 'sampleCount', type: 'integer' },
|
||||
],
|
||||
}),
|
||||
true,
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'container_snapshot_daily',
|
||||
new TableIndex({ name: 'idx_container_daily_name', columnNames: ['containerName'] }),
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'container_snapshot_daily',
|
||||
new TableIndex({ name: 'idx_container_daily_date', columnNames: ['date'] }),
|
||||
);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.dropTable('container_snapshot_daily');
|
||||
await queryRunner.dropTable('container_snapshot_hourly');
|
||||
await queryRunner.dropTable('vps_resource_daily');
|
||||
await queryRunner.dropTable('vps_resource_hourly');
|
||||
await queryRunner.dropTable('container_dependencies');
|
||||
await queryRunner.dropTable('docker_events');
|
||||
await queryRunner.dropTable('docker_container_snapshots');
|
||||
await queryRunner.dropTable('vps_resource_snapshots');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,148 +0,0 @@
|
|||
import { Table, TableIndex } from 'typeorm';
|
||||
|
||||
import type { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
export class InitialSchema1735200000000 implements MigrationInterface {
|
||||
name = 'InitialSchema1735200000000';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
// VPS Resource Snapshots
|
||||
await queryRunner.createTable(
|
||||
new Table({
|
||||
name: 'vps_resource_snapshots',
|
||||
columns: [
|
||||
{
|
||||
name: 'id',
|
||||
type: 'varchar',
|
||||
isPrimary: true,
|
||||
isGenerated: true,
|
||||
generationStrategy: 'uuid',
|
||||
},
|
||||
{ name: 'vpsHost', type: 'varchar', length: '255' },
|
||||
{ name: 'cpuPercent', type: 'real' },
|
||||
{ name: 'cpuCores', type: 'integer' },
|
||||
{ name: 'memoryUsedMB', type: 'real' },
|
||||
{ name: 'memoryTotalMB', type: 'real' },
|
||||
{ name: 'memoryPercent', type: 'real' },
|
||||
{ name: 'diskUsedGB', type: 'real' },
|
||||
{ name: 'diskTotalGB', type: 'real' },
|
||||
{ name: 'diskPercent', type: 'real' },
|
||||
{ name: 'networkRxBytes', type: 'bigint', default: '0' },
|
||||
{ name: 'networkTxBytes', type: 'bigint', default: '0' },
|
||||
{ name: 'timestamp', type: 'datetime' },
|
||||
],
|
||||
}),
|
||||
true,
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'vps_resource_snapshots',
|
||||
new TableIndex({
|
||||
name: 'idx_vps_snapshot_timestamp',
|
||||
columnNames: ['timestamp'],
|
||||
}),
|
||||
);
|
||||
|
||||
// Docker Container Snapshots
|
||||
await queryRunner.createTable(
|
||||
new Table({
|
||||
name: 'docker_container_snapshots',
|
||||
columns: [
|
||||
{
|
||||
name: 'id',
|
||||
type: 'varchar',
|
||||
isPrimary: true,
|
||||
isGenerated: true,
|
||||
generationStrategy: 'uuid',
|
||||
},
|
||||
{ name: 'vpsHost', type: 'varchar', length: '255' },
|
||||
{ name: 'containerName', type: 'varchar', length: '255' },
|
||||
{ name: 'state', type: 'varchar', length: '50' },
|
||||
{ name: 'health', type: 'varchar', length: '50', isNullable: true },
|
||||
{ name: 'status', type: 'varchar', length: '255' },
|
||||
{ name: 'cpuPercent', type: 'real' },
|
||||
{ name: 'memoryUsage', type: 'varchar', length: '100' },
|
||||
{ name: 'uptimeSeconds', type: 'integer', isNullable: true },
|
||||
{ name: 'restartCount', type: 'integer', default: '0' },
|
||||
{ name: 'timestamp', type: 'datetime' },
|
||||
],
|
||||
}),
|
||||
true,
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'docker_container_snapshots',
|
||||
new TableIndex({
|
||||
name: 'idx_container_snapshot_name',
|
||||
columnNames: ['containerName'],
|
||||
}),
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'docker_container_snapshots',
|
||||
new TableIndex({
|
||||
name: 'idx_container_snapshot_timestamp',
|
||||
columnNames: ['timestamp'],
|
||||
}),
|
||||
);
|
||||
|
||||
// Docker Events
|
||||
await queryRunner.createTable(
|
||||
new Table({
|
||||
name: 'docker_events',
|
||||
columns: [
|
||||
{
|
||||
name: 'id',
|
||||
type: 'varchar',
|
||||
isPrimary: true,
|
||||
isGenerated: true,
|
||||
generationStrategy: 'uuid',
|
||||
},
|
||||
{ name: 'vpsHost', type: 'varchar', length: '255' },
|
||||
{ name: 'containerName', type: 'varchar', length: '255' },
|
||||
{ name: 'type', type: 'varchar', length: '100' },
|
||||
{ name: 'action', type: 'varchar', length: '100' },
|
||||
{ name: 'timestamp', type: 'datetime' },
|
||||
{ name: 'metadata', type: 'text', isNullable: true },
|
||||
],
|
||||
}),
|
||||
true,
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'docker_events',
|
||||
new TableIndex({
|
||||
name: 'idx_docker_event_container_name',
|
||||
columnNames: ['containerName'],
|
||||
}),
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'docker_events',
|
||||
new TableIndex({
|
||||
name: 'idx_docker_event_timestamp',
|
||||
columnNames: ['timestamp'],
|
||||
}),
|
||||
);
|
||||
|
||||
// Container Dependencies
|
||||
await queryRunner.createTable(
|
||||
new Table({
|
||||
name: 'container_dependencies',
|
||||
columns: [
|
||||
{ name: 'fromContainer', type: 'varchar', length: '255', isPrimary: true },
|
||||
{ name: 'toContainer', type: 'varchar', length: '255', isPrimary: true },
|
||||
{ name: 'updatedAt', type: 'datetime' },
|
||||
],
|
||||
}),
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.dropTable('container_dependencies');
|
||||
await queryRunner.dropTable('docker_events');
|
||||
await queryRunner.dropTable('docker_container_snapshots');
|
||||
await queryRunner.dropTable('vps_resource_snapshots');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,158 +0,0 @@
|
|||
import { Table, TableIndex } from 'typeorm';
|
||||
|
||||
import type { MigrationInterface, QueryRunner} from 'typeorm';
|
||||
|
||||
/**
|
||||
* Migration to add aggregate tables for data retention
|
||||
*
|
||||
* Retention tiers:
|
||||
* - Raw snapshots: 48 hours
|
||||
* - Hourly aggregates: 6 weeks
|
||||
* - Daily aggregates: 380 days (then archived to bigdisk)
|
||||
*/
|
||||
export class AddAggregateTables1735300000000 implements MigrationInterface {
|
||||
name = 'AddAggregateTables1735300000000';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
// VPS Resource Hourly Aggregates
|
||||
await queryRunner.createTable(
|
||||
new Table({
|
||||
name: 'vps_resource_hourly',
|
||||
columns: [
|
||||
{ name: 'id', type: 'varchar', isPrimary: true, isGenerated: true, generationStrategy: 'uuid' },
|
||||
{ name: 'vpsHost', type: 'varchar', length: '255' },
|
||||
{ name: 'hour', type: 'datetime' },
|
||||
{ name: 'cpuPercentAvg', type: 'real' },
|
||||
{ name: 'cpuPercentMin', type: 'real' },
|
||||
{ name: 'cpuPercentMax', type: 'real' },
|
||||
{ name: 'memoryPercentAvg', type: 'real' },
|
||||
{ name: 'memoryPercentMin', type: 'real' },
|
||||
{ name: 'memoryPercentMax', type: 'real' },
|
||||
{ name: 'memoryUsedMBAvg', type: 'real' },
|
||||
{ name: 'diskPercentAvg', type: 'real' },
|
||||
{ name: 'diskUsedGBAvg', type: 'real' },
|
||||
{ name: 'networkRxBytesTotal', type: 'bigint', default: '0' },
|
||||
{ name: 'networkTxBytesTotal', type: 'bigint', default: '0' },
|
||||
{ name: 'sampleCount', type: 'integer' },
|
||||
],
|
||||
}),
|
||||
true,
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'vps_resource_hourly',
|
||||
new TableIndex({ name: 'idx_vps_hourly_host', columnNames: ['vpsHost'] }),
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'vps_resource_hourly',
|
||||
new TableIndex({ name: 'idx_vps_hourly_hour', columnNames: ['hour'] }),
|
||||
);
|
||||
|
||||
// VPS Resource Daily Aggregates
|
||||
await queryRunner.createTable(
|
||||
new Table({
|
||||
name: 'vps_resource_daily',
|
||||
columns: [
|
||||
{ name: 'id', type: 'varchar', isPrimary: true, isGenerated: true, generationStrategy: 'uuid' },
|
||||
{ name: 'vpsHost', type: 'varchar', length: '255' },
|
||||
{ name: 'date', type: 'date' },
|
||||
{ name: 'cpuPercentAvg', type: 'real' },
|
||||
{ name: 'cpuPercentMin', type: 'real' },
|
||||
{ name: 'cpuPercentMax', type: 'real' },
|
||||
{ name: 'cpuPercentP95', type: 'real' },
|
||||
{ name: 'memoryPercentAvg', type: 'real' },
|
||||
{ name: 'memoryPercentMin', type: 'real' },
|
||||
{ name: 'memoryPercentMax', type: 'real' },
|
||||
{ name: 'memoryPercentP95', type: 'real' },
|
||||
{ name: 'memoryUsedMBAvg', type: 'real' },
|
||||
{ name: 'diskPercentAvg', type: 'real' },
|
||||
{ name: 'diskUsedGBAvg', type: 'real' },
|
||||
{ name: 'networkRxBytesTotal', type: 'bigint', default: '0' },
|
||||
{ name: 'networkTxBytesTotal', type: 'bigint', default: '0' },
|
||||
{ name: 'sampleCount', type: 'integer' },
|
||||
],
|
||||
}),
|
||||
true,
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'vps_resource_daily',
|
||||
new TableIndex({ name: 'idx_vps_daily_host', columnNames: ['vpsHost'] }),
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'vps_resource_daily',
|
||||
new TableIndex({ name: 'idx_vps_daily_date', columnNames: ['date'] }),
|
||||
);
|
||||
|
||||
// Container Snapshot Hourly Aggregates
|
||||
await queryRunner.createTable(
|
||||
new Table({
|
||||
name: 'container_snapshot_hourly',
|
||||
columns: [
|
||||
{ name: 'id', type: 'varchar', isPrimary: true, isGenerated: true, generationStrategy: 'uuid' },
|
||||
{ name: 'vpsHost', type: 'varchar', length: '255' },
|
||||
{ name: 'containerName', type: 'varchar', length: '255' },
|
||||
{ name: 'hour', type: 'datetime' },
|
||||
{ name: 'predominantState', type: 'varchar', length: '50' },
|
||||
{ name: 'healthyPercent', type: 'real' },
|
||||
{ name: 'cpuPercentAvg', type: 'real' },
|
||||
{ name: 'cpuPercentMax', type: 'real' },
|
||||
{ name: 'restartCountMax', type: 'integer', default: '0' },
|
||||
{ name: 'uptimeSecondsEnd', type: 'integer', isNullable: true },
|
||||
{ name: 'sampleCount', type: 'integer' },
|
||||
],
|
||||
}),
|
||||
true,
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'container_snapshot_hourly',
|
||||
new TableIndex({ name: 'idx_container_hourly_name', columnNames: ['containerName'] }),
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'container_snapshot_hourly',
|
||||
new TableIndex({ name: 'idx_container_hourly_hour', columnNames: ['hour'] }),
|
||||
);
|
||||
|
||||
// Container Snapshot Daily Aggregates
|
||||
await queryRunner.createTable(
|
||||
new Table({
|
||||
name: 'container_snapshot_daily',
|
||||
columns: [
|
||||
{ name: 'id', type: 'varchar', isPrimary: true, isGenerated: true, generationStrategy: 'uuid' },
|
||||
{ name: 'vpsHost', type: 'varchar', length: '255' },
|
||||
{ name: 'containerName', type: 'varchar', length: '255' },
|
||||
{ name: 'date', type: 'date' },
|
||||
{ name: 'uptimePercent', type: 'real' },
|
||||
{ name: 'healthyPercent', type: 'real' },
|
||||
{ name: 'cpuPercentAvg', type: 'real' },
|
||||
{ name: 'cpuPercentMax', type: 'real' },
|
||||
{ name: 'cpuPercentP95', type: 'real' },
|
||||
{ name: 'restartCount', type: 'integer', default: '0' },
|
||||
{ name: 'sampleCount', type: 'integer' },
|
||||
],
|
||||
}),
|
||||
true,
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'container_snapshot_daily',
|
||||
new TableIndex({ name: 'idx_container_daily_name', columnNames: ['containerName'] }),
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'container_snapshot_daily',
|
||||
new TableIndex({ name: 'idx_container_daily_date', columnNames: ['date'] }),
|
||||
);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.dropTable('container_snapshot_daily');
|
||||
await queryRunner.dropTable('container_snapshot_hourly');
|
||||
await queryRunner.dropTable('vps_resource_daily');
|
||||
await queryRunner.dropTable('vps_resource_hourly');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
export { InitialSchema1700000000000 } from './1700000000000-InitialSchema';
|
||||
Loading…
Add table
Reference in a new issue