-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
51704b6
commit 2c02679
Showing
7 changed files
with
14,126 additions
and
11,193 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
vivy-modules/vivy-system/src/modules/health/health.controller.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { Controller, Get, ServiceUnavailableException } from '@nestjs/common' | ||
import { ApiTags } from '@nestjs/swagger' | ||
import { HealthCheckService, HealthCheck, HealthCheckResult } from '@nestjs/terminus' | ||
import { Public } from '@vivy-common/security' | ||
import { HealthService } from './health.service' | ||
|
||
/** | ||
* 健康检查 | ||
* @author vivy | ||
*/ | ||
@ApiTags('健康检查') | ||
@Controller('health') | ||
export class HealthController { | ||
constructor( | ||
private health: HealthCheckService, | ||
private healthService: HealthService | ||
) {} | ||
|
||
/** | ||
* 健康检查 | ||
*/ | ||
@Get() | ||
@Public() | ||
@HealthCheck() | ||
async check(): Promise<HealthCheckResult> { | ||
try { | ||
return await this.health.check([ | ||
() => this.healthService.checkNetwork(), | ||
() => this.healthService.checkMysql(), | ||
() => this.healthService.checkRedis(), | ||
() => this.healthService.checkDisk(), | ||
() => this.healthService.checkMemoryHeap(), | ||
() => this.healthService.checkMemoryRSS(), | ||
]) | ||
} catch (error) { | ||
// TODO: send email to the admin | ||
return (error as ServiceUnavailableException).getResponse() as HealthCheckResult | ||
} | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
vivy-modules/vivy-system/src/modules/health/health.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { HttpModule } from '@nestjs/axios' | ||
import { Module } from '@nestjs/common' | ||
import { TerminusModule } from '@nestjs/terminus' | ||
import { HealthController } from './health.controller' | ||
import { HealthService } from './health.service' | ||
import { RedisHealthIndicator } from './indicators/redis.health' | ||
|
||
@Module({ | ||
imports: [TerminusModule, HttpModule], | ||
controllers: [HealthController], | ||
providers: [HealthService, RedisHealthIndicator], | ||
}) | ||
export class HealthModule {} |
64 changes: 64 additions & 0 deletions
64
vivy-modules/vivy-system/src/modules/health/health.service.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import { Injectable } from '@nestjs/common' | ||
import { | ||
DiskHealthIndicator, | ||
HttpHealthIndicator, | ||
MemoryHealthIndicator, | ||
TypeOrmHealthIndicator, | ||
} from '@nestjs/terminus' | ||
import { RedisHealthIndicator } from './indicators/redis.health' | ||
|
||
@Injectable() | ||
export class HealthService { | ||
constructor( | ||
private http: HttpHealthIndicator, | ||
private db: TypeOrmHealthIndicator, | ||
private memory: MemoryHealthIndicator, | ||
private disk: DiskHealthIndicator, | ||
private redis: RedisHealthIndicator | ||
) {} | ||
|
||
/** | ||
* 检查网络连接 | ||
*/ | ||
async checkNetwork() { | ||
return this.http.pingCheck('vivy', 'http://43.140.221.180:8000/') | ||
} | ||
|
||
/** | ||
* 检查 MySQL 连接 | ||
*/ | ||
async checkMysql() { | ||
return this.db.pingCheck('mysql') | ||
} | ||
|
||
/** | ||
* 检查 Redis 连接 | ||
*/ | ||
async checkRedis() { | ||
return this.redis.pingCheck('redis') | ||
} | ||
|
||
/** | ||
* 检查磁盘使用情况 | ||
*/ | ||
async checkDisk() { | ||
return this.disk.checkStorage('disk', { | ||
path: '/', | ||
thresholdPercent: 0.8, | ||
}) | ||
} | ||
|
||
/** | ||
* 检查进程的内存堆使用情况 | ||
*/ | ||
async checkMemoryHeap() { | ||
return this.memory.checkHeap('memory-heap', 200 * 1024 * 1024) | ||
} | ||
|
||
/** | ||
* 检查进程的内存使用情况 (RSS) | ||
*/ | ||
async checkMemoryRSS() { | ||
return this.memory.checkRSS('memory-rss', 200 * 1024 * 1024) | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
vivy-modules/vivy-system/src/modules/health/indicators/redis.health.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { Injectable } from '@nestjs/common' | ||
import { HealthIndicator, HealthIndicatorResult, HealthCheckError } from '@nestjs/terminus' | ||
import { InjectRedis } from '@nestjs-modules/ioredis' | ||
import Redis from 'ioredis' | ||
|
||
@Injectable() | ||
export class RedisHealthIndicator extends HealthIndicator { | ||
constructor( | ||
@InjectRedis() | ||
private redis: Redis | ||
) { | ||
super() | ||
} | ||
|
||
async pingCheck(key: string): Promise<HealthIndicatorResult> { | ||
try { | ||
const result = await this.redis.ping() | ||
if (result !== 'PONG') { | ||
throw new Error('Invalid PING response') | ||
} | ||
return this.getStatus(key, true) | ||
} catch (error) { | ||
throw new HealthCheckError('Redis check failed', this.getStatus(key, false, { error: error.message })) | ||
} | ||
} | ||
} |