Skip to content

Commit

Permalink
Add audit alerts
Browse files Browse the repository at this point in the history
  • Loading branch information
hardillb committed Oct 18, 2023
1 parent 62be25e commit 6429709
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 1 deletion.
39 changes: 38 additions & 1 deletion lib/launcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ const HEALTH_POLL_MAX_STARTUP_ERROR_COUNT = 10
const HEALTH_POLL_MAX_ERROR_COUNT = 3

/** The number of seconds between resource polling */
const RESOURCE_POLL_INTERVAL = 5
const RESOURCE_POLL_INTERVAL = 10
const RESOURCE_ALERT_SAMPLES = 30
const CPU_LIMIT = process.env['FORGE_CPU_LIMIT']

Check failure on line 42 in lib/launcher.js

View workflow job for this annotation

GitHub Actions / build / build (16.x)

["FORGE_CPU_LIMIT"] is better written in dot notation
const MEMORY_LIMIT = process.env['FORGE_MEMORY_LIMIT']

Check failure on line 43 in lib/launcher.js

View workflow job for this annotation

GitHub Actions / build / build (16.x)

["FORGE_MEMORY_LIMIT"] is better written in dot notation

const States = {
STOPPED: 'stopped',
Expand Down Expand Up @@ -84,6 +87,8 @@ class Launcher {

// defaults to the last 3.5 hours of samples at 5 second intervals
this.sampleBuffer = new SampleBuffer(this.options.sampleBufferMax || 2520)
this.cpuAuditLogged = 0
this.memoryAuditLogged = 0
}

async loadSettings () {
Expand Down Expand Up @@ -516,6 +521,38 @@ class Launcher {

const sample = await resourceSample(pollUrl, RESOURCE_POLL_INTERVAL)
this.sampleBuffer.add(sample)

//avg over the last minute for alerts

Check failure on line 525 in lib/launcher.js

View workflow job for this annotation

GitHub Actions / build / build (16.x)

Expected space or tab after '//' in comment
if ( CPU_LIMIT || MEMORY_LIMIT) {

Check failure on line 526 in lib/launcher.js

View workflow job for this annotation

GitHub Actions / build / build (16.x)

There should be no space after this paren
const avg = this.sampleBuffer.avgLastX(RESOURCE_ALERT_SAMPLES)
if (avg.count == RESOURCE_ALERT_SAMPLES) {

Check failure on line 528 in lib/launcher.js

View workflow job for this annotation

GitHub Actions / build / build (16.x)

Expected '===' and instead saw '=='
console.log(`${JSON.stringify(avg,null,2)} ${avg.count}`)

Check failure on line 529 in lib/launcher.js

View workflow job for this annotation

GitHub Actions / build / build (16.x)

A space is required after ','

Check failure on line 529 in lib/launcher.js

View workflow job for this annotation

GitHub Actions / build / build (16.x)

A space is required after ','
if (CPU_LIMIT) {
if (avg.cpu > (CPU_LIMIT * 0.75)) {
if (this.cpuAuditLogged === 0) {
await this.logAuditEvent('resources.cpu',{})

Check failure on line 533 in lib/launcher.js

View workflow job for this annotation

GitHub Actions / build / build (16.x)

A space is required after ','
this.cpuAuditLogged = RESOURCE_ALERT_SAMPLES
}
} else {
if (this.cpuAuditLogged > 0) {
this.cpuAuditLogged -= 1
}
}
}
if (MEMORY_LIMIT) {
if (avg.ps > (MEMORY_LIMIT * 0.75)) {

Check failure on line 543 in lib/launcher.js

View workflow job for this annotation

GitHub Actions / build / build (16.x)

Multiple spaces found before '{'
if (this.memoryAuditLogged === 0) {
await this.logAuditEvent('resources.memory',{})

Check failure on line 545 in lib/launcher.js

View workflow job for this annotation

GitHub Actions / build / build (16.x)

A space is required after ','
this.memoryAuditLogged = RESOURCE_ALERT_SAMPLES
}
} else {
if (this.memoryAuditLogged > 0) {
this.memoryAuditLogged -= 1
}
}
}
}
}
}, RESOURCE_POLL_INTERVAL * 1000)

this.proc.on('close', (code, signal) => {
Expand Down
36 changes: 36 additions & 0 deletions lib/resources/sampleBuffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,42 @@ class SampleBuffer {
return result
}
}

lastX (x) {
if (this.head > x) {
return this.buffer.slice(this.head - x, this.head)
} else {
if (this.wrapped) {
const d = x - this.head
const result = this.buffer.slice(this.size - d, this.size)
result.push(...this.buffer.slice(0, this.head))
return result
} else {
return this.buffer.slice(0, this.head)
}
}
}

avgLastX (x) {
const samples = this.lastX(x)
const result = {}
samples.forEach(sample => {
for (const [key, value] of Object.entries(sample)) {
if (key !== 'ts' && key !== 'err') {
if (result[key]) {
result[key] += value
} else {
result[key] = value
}
}
}
})
for (const [key, value] of Object.entries(result)) {
result[key] = value/samples.length
}
result.count = samples.length
return result
}
}

module.exports = SampleBuffer

0 comments on commit 6429709

Please sign in to comment.