health check

This commit is contained in:
hannathkadher
2025-04-23 17:31:16 +04:00
parent cb2056d1b3
commit 0749fab633
3 changed files with 77 additions and 64 deletions

View File

@ -43,73 +43,84 @@ import { SubspaceProductAllocationEntity } from '../modules/space/entities/subsp
import { SubspaceEntity } from '../modules/space/entities/subspace/subspace.entity'; import { SubspaceEntity } from '../modules/space/entities/subspace/subspace.entity';
import { TagEntity } from '../modules/space/entities/tag.entity'; import { TagEntity } from '../modules/space/entities/tag.entity';
import { ClientEntity } from '../modules/client/entities'; import { ClientEntity } from '../modules/client/entities';
import { createLogger } from 'winston';
import { winstonLoggerOptions } from 'src/common/filters/http-exception/logger/winston.logger';
@Module({ @Module({
imports: [ imports: [
TypeOrmModule.forRootAsync({ TypeOrmModule.forRootAsync({
imports: [ConfigModule], imports: [ConfigModule],
inject: [ConfigService], inject: [ConfigService],
useFactory: (configService: ConfigService) => ({ useFactory: (configService: ConfigService) => {
name: 'default', const sslEnabled = JSON.parse(configService.get<string>('DB_SSL'));
type: 'postgres', const winstonLogger = createLogger(winstonLoggerOptions);
host: configService.get('DB_HOST'), const typeOrmLogger = new TypeOrmWinstonLogger(winstonLogger);
port: configService.get('DB_PORT'),
username: configService.get('DB_USER'), return {
password: configService.get('DB_PASSWORD'), name: 'default',
database: configService.get('DB_NAME'), type: 'postgres',
entities: [ host: configService.get('DB_HOST'),
NewTagEntity, port: configService.get('DB_PORT'),
ProjectEntity, username: configService.get('DB_USER'),
UserEntity, password: configService.get('DB_PASSWORD'),
UserSessionEntity, database: configService.get('DB_NAME'),
UserOtpEntity, synchronize: Boolean(JSON.parse(configService.get('DB_SYNC'))),
ProductEntity, logging: ['query', 'error', 'warn', 'schema', 'migration'],
DeviceUserPermissionEntity, namingStrategy: new SnakeNamingStrategy(),
DeviceEntity, ssl: sslEnabled ? { rejectUnauthorized: false } : false,
PermissionTypeEntity, extra: {
CommunityEntity, charset: 'utf8mb4',
SpaceEntity, max: 20,
SpaceLinkEntity, idleTimeoutMillis: 5000,
SubspaceEntity, connectionTimeoutMillis: 11000,
TagEntity, maxUses: 7500,
UserSpaceEntity, ...(sslEnabled && {
DeviceUserPermissionEntity, ssl: { rejectUnauthorized: false }, // Required for Azure PostgreSQL
RoleTypeEntity, }),
UserNotificationEntity, },
DeviceNotificationEntity, entities: [
RegionEntity, NewTagEntity,
TimeZoneEntity, ProjectEntity,
VisitorPasswordEntity, UserEntity,
DeviceStatusLogEntity, UserSessionEntity,
SceneEntity, UserOtpEntity,
SceneIconEntity, ProductEntity,
SceneDeviceEntity, DeviceUserPermissionEntity,
SpaceModelEntity, DeviceEntity,
SubspaceModelEntity, PermissionTypeEntity,
TagModel, CommunityEntity,
InviteUserEntity, SpaceEntity,
InviteUserSpaceEntity, SpaceLinkEntity,
InviteSpaceEntity, SubspaceEntity,
AutomationEntity, TagEntity,
SpaceModelProductAllocationEntity, UserSpaceEntity,
SubspaceModelProductAllocationEntity, RoleTypeEntity,
SpaceProductAllocationEntity, UserNotificationEntity,
SubspaceProductAllocationEntity, DeviceNotificationEntity,
ClientEntity, RegionEntity,
], TimeZoneEntity,
namingStrategy: new SnakeNamingStrategy(), VisitorPasswordEntity,
synchronize: Boolean(JSON.parse(configService.get('DB_SYNC'))), DeviceStatusLogEntity,
logging: false, SceneEntity,
extra: { SceneIconEntity,
charset: 'utf8mb4', SceneDeviceEntity,
max: 20, // set pool max size SpaceModelEntity,
idleTimeoutMillis: 5000, // close idle clients after 5 second SubspaceModelEntity,
connectionTimeoutMillis: 11_000, // return an error after 11 second if connection could not be established TagModel,
maxUses: 7500, // close (and replace) a connection after it has been used 7500 times (see below for discussion) InviteUserEntity,
}, InviteUserSpaceEntity,
continuationLocalStorage: true, InviteSpaceEntity,
ssl: Boolean(JSON.parse(configService.get('DB_SSL'))), AutomationEntity,
}), SpaceModelProductAllocationEntity,
SubspaceModelProductAllocationEntity,
SpaceProductAllocationEntity,
SubspaceProductAllocationEntity,
ClientEntity,
],
};
},
}), }),
], ],
providers: [TypeOrmWinstonLogger],
}) })
export class DatabaseModule {} export class DatabaseModule {}

View File

@ -1,4 +1,5 @@
import { Controller, Get } from '@nestjs/common'; import { Controller, Get } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { import {
HealthCheck, HealthCheck,
HealthCheckService, HealthCheckService,
@ -8,6 +9,7 @@ import {
HttpHealthIndicator, HttpHealthIndicator,
} from '@nestjs/terminus'; } from '@nestjs/terminus';
@ApiTags('Health Module')
@Controller('health') @Controller('health')
export class HealthController { export class HealthController {
constructor( constructor(
@ -29,7 +31,7 @@ export class HealthController {
path: '/', path: '/',
}), }),
() => this.memory.checkHeap('memory_heap', 300 * 1024 * 1024), () => this.memory.checkHeap('memory_heap', 300 * 1024 * 1024),
() => this.http.pingCheck('tuya', 'https://openapi.tuya.com'), () => this.http.pingCheck('tuya', process.env.TUYA_EU_URL),
]); ]);
} }
} }

View File

@ -3,9 +3,9 @@ import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus'; import { TerminusModule } from '@nestjs/terminus';
import { TypeOrmModule } from '@nestjs/typeorm'; import { TypeOrmModule } from '@nestjs/typeorm';
import { HealthController } from './controllers'; import { HealthController } from './controllers';
import { HttpModule } from '@nestjs/axios';
@Module({ @Module({
imports: [TerminusModule, TypeOrmModule], imports: [TerminusModule, HttpModule, TypeOrmModule],
controllers: [HealthController], controllers: [HealthController],
}) })
export class HealthModule {} export class HealthModule {}