Skip to content

Commit 9829dc1

Browse files
committed
feat: enhance health monitoring configuration and metrics
- Added new environment variables for health collection interval and HTTP check enablement. - Updated health collector service to dynamically set the health collection interval based on environment variables. - Refactored health snapshot service to include additional memory metrics and conditional HTTP check logic. - Improved overall health reporting by refining the collection and snapshot processes.
1 parent 1384a67 commit 9829dc1

File tree

3 files changed

+25
-25
lines changed

3 files changed

+25
-25
lines changed

.env.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
SESAME_HEALTH_HEAP_THRESHOLD_MB=1024
22
SESAME_HEALTH_RSS_THRESHOLD_MB=3072
33
SESAME_HEALTH_NATIVE_DERIVE_MIN_GROWTH_MB=256
4+
SESAME_HEALTH_COLLECTION_INTERVAL_MS=30000
5+
SESAME_HEALTH_ENABLE_HTTP_CHECK=false

apps/api/src/core/health/health-collector.service.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ import { Interval } from '@nestjs/schedule'
33
import { HealthHistoryService } from './health-history.service'
44
import { HealthSnapshotService } from './health-snapshot.service'
55

6-
const HEALTH_COLLECTION_INTERVAL_MS = 5_000
6+
const DEFAULT_HEALTH_COLLECTION_INTERVAL_MS = 5_000
7+
const parsedHealthCollectionIntervalMs = Number.parseInt(`${process.env.SESAME_HEALTH_COLLECTION_INTERVAL_MS || ''}`, 10)
8+
const HEALTH_COLLECTION_INTERVAL_MS = Number.isFinite(parsedHealthCollectionIntervalMs) && parsedHealthCollectionIntervalMs > 0
9+
? parsedHealthCollectionIntervalMs
10+
: DEFAULT_HEALTH_COLLECTION_INTERVAL_MS
711

812
@Injectable()
913
export class HealthCollectorService implements OnModuleInit {

apps/api/src/core/health/health-snapshot.service.ts

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Injectable } from '@nestjs/common'
22
import { statfs } from 'fs/promises'
33
import { cpus, loadavg, totalmem } from 'os'
4-
import { DiskHealthIndicator, HealthCheckError, HealthCheckResult, HealthCheckService, HealthIndicatorResult, HttpHealthIndicator, MemoryHealthIndicator, MongooseHealthIndicator } from '@nestjs/terminus'
4+
import { DiskHealthIndicator, HealthCheckError, HealthCheckResult, HealthCheckService, HealthIndicatorResult, HttpHealthIndicator, MongooseHealthIndicator } from '@nestjs/terminus'
55

66
const MEMORY_MULTIPLIER = 1024 * 1024
77
const GIGABYTE_MULTIPLIER = 1024 * 1024 * 1024
@@ -36,6 +36,7 @@ const HEAP_MEMORY_THRESHOLD_MB = resolveThresholdMb('SESAME_HEALTH_HEAP_THRESHOL
3636
const RSS_MEMORY_THRESHOLD_MB = resolveThresholdMb('SESAME_HEALTH_RSS_THRESHOLD_MB', { dev: 3072, prod: 1024 })
3737
const NATIVE_MEMORY_DERIVE_MIN_SAMPLES = 6
3838
const NATIVE_MEMORY_DERIVE_MIN_GROWTH_MB = resolveThresholdMb('SESAME_HEALTH_NATIVE_DERIVE_MIN_GROWTH_MB', { dev: 256, prod: 128 })
39+
const ENABLE_HTTP_GITHUB_CHECK = !/^(false|0|off|no)$/i.test(`${process.env.SESAME_HEALTH_ENABLE_HTTP_CHECK || 'true'}`)
3940

4041
export type HealthSnapshotPayload = HealthCheckResult & {
4142
system: {
@@ -79,7 +80,6 @@ export class HealthSnapshotService {
7980
private readonly mongoose: MongooseHealthIndicator,
8081
private readonly http: HttpHealthIndicator,
8182
private readonly disk: DiskHealthIndicator,
82-
private readonly memory: MemoryHealthIndicator,
8383
) { }
8484

8585
public async collectSnapshot(): Promise<HealthSnapshotPayload> {
@@ -88,13 +88,19 @@ export class HealthSnapshotService {
8888
const memoryUsage = process.memoryUsage()
8989
const cpuCount = Math.max(cpus().length, 1)
9090
const [load1m, load5m, load15m] = loadavg()
91+
const cpuIndicator = this.checkCpu().cpu
92+
const heapIndicator = this.checkMemoryHeap().memory_heap
93+
const rssIndicator = this.checkMemoryRss().memory_rss
9194
const externalMb = Number((memoryUsage.external / MEMORY_MULTIPLIER).toFixed(2))
9295
const arrayBuffersMb = Number((memoryUsage.arrayBuffers / MEMORY_MULTIPLIER).toFixed(2))
9396
const nativeMb = Number((externalMb + arrayBuffersMb).toFixed(2))
9497
const memoryNativeIndicator = this.buildMemoryNativeIndicator(nativeMb, externalMb, arrayBuffersMb)
9598

9699
const details = {
97100
...((healthResult.details || {}) as HealthIndicatorResult),
101+
cpu: cpuIndicator,
102+
memory_heap: heapIndicator,
103+
memory_rss: rssIndicator,
98104
memory_native: memoryNativeIndicator,
99105
}
100106
const hasAnyDown = Object.values(details).some((indicator) => indicator?.status === 'down')
@@ -138,14 +144,16 @@ export class HealthSnapshotService {
138144

139145
private async collectHealthResult(): Promise<HealthCheckResult> {
140146
try {
141-
return await this.health.check([
147+
const checks: Array<() => Promise<HealthIndicatorResult>> = [
142148
() => this.checkMongoose(),
143-
() => this.http.pingCheck('http-github', 'https://github.com'),
144149
() => this.checkStorage(),
145-
() => this.checkMemoryHeap(),
146-
() => this.checkMemoryRss(),
147-
() => this.checkCpu(),
148-
])
150+
]
151+
152+
if (ENABLE_HTTP_GITHUB_CHECK) {
153+
checks.splice(1, 0, () => this.http.pingCheck('http-github', 'https://github.com'))
154+
}
155+
156+
return await this.health.check(checks)
149157
} catch (error) {
150158
if (error instanceof HealthCheckError) {
151159
const details = this.extractHealthErrorDetails(error)
@@ -219,10 +227,6 @@ export class HealthSnapshotService {
219227
cores: cpuCount,
220228
} as const
221229

222-
if (indicator.status === 'down') {
223-
throw new HealthCheckError('cpu_check_failed', { cpu: indicator })
224-
}
225-
226230
return { cpu: indicator }
227231
}
228232

@@ -275,8 +279,7 @@ export class HealthSnapshotService {
275279
return { storage: indicator }
276280
}
277281

278-
private async checkMemoryHeap(): Promise<Record<string, { status: 'up' | 'down'; usedMb: number; thresholdMb: number; usedPercent: number }>> {
279-
await this.memory.checkHeap('memory_heap', HEAP_MEMORY_THRESHOLD_MB * MEMORY_MULTIPLIER)
282+
private checkMemoryHeap(): Record<string, { status: 'up' | 'down'; usedMb: number; thresholdMb: number; usedPercent: number }> {
280283
const heapUsedMb = process.memoryUsage().heapUsed / MEMORY_MULTIPLIER
281284
const usedPercent = heapUsedMb / HEAP_MEMORY_THRESHOLD_MB
282285

@@ -287,15 +290,10 @@ export class HealthSnapshotService {
287290
usedPercent: Number((usedPercent * 100).toFixed(2)),
288291
} as const
289292

290-
if (indicator.status === 'down') {
291-
throw new HealthCheckError('memory_heap_check_failed', { memory_heap: indicator })
292-
}
293-
294293
return { memory_heap: indicator }
295294
}
296295

297-
private async checkMemoryRss(): Promise<Record<string, { status: 'up' | 'down'; usedMb: number; thresholdMb: number; usedPercent: number }>> {
298-
await this.memory.checkRSS('memory_rss', RSS_MEMORY_THRESHOLD_MB * MEMORY_MULTIPLIER)
296+
private checkMemoryRss(): Record<string, { status: 'up' | 'down'; usedMb: number; thresholdMb: number; usedPercent: number }> {
299297
const rssMb = process.memoryUsage().rss / MEMORY_MULTIPLIER
300298
const usedPercent = rssMb / RSS_MEMORY_THRESHOLD_MB
301299

@@ -306,10 +304,6 @@ export class HealthSnapshotService {
306304
usedPercent: Number((usedPercent * 100).toFixed(2)),
307305
} as const
308306

309-
if (indicator.status === 'down') {
310-
throw new HealthCheckError('memory_rss_check_failed', { memory_rss: indicator })
311-
}
312-
313307
return { memory_rss: indicator }
314308
}
315309
}

0 commit comments

Comments
 (0)