-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Sentinel Aliase Naming configuration * remove consolelogs * add RPC_STUCK_THRESHOLD and small refactor * update notification jobs to send health reasons * add instance name to report * add RPC_STUCK_THRESHOLD as config obj * add RPC_STUCK_THRESHOLD to test * add default value * fix test * dumb change
- Loading branch information
Showing
7 changed files
with
107 additions
and
68 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
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 |
---|---|---|
@@ -1,71 +1,103 @@ | ||
class Report { | ||
constructor (app) { | ||
this.app = app; | ||
this._isSyncingMethodExist = true; //default we will try to call web3.eth.isSyncing. | ||
} | ||
|
||
async checkDatabase () { | ||
try { | ||
return (await this.app.db.sysQueries.healthCheck()) !== undefined; | ||
} catch (err) { | ||
this.app.logger.error(`Report.checkDatabase(): ${err}`); | ||
return false; | ||
constructor(app) { | ||
this.app = app; | ||
this._isSyncingMethodExist = true; //default we will try to call web3.eth.isSyncing. | ||
} | ||
} | ||
|
||
async fullReport () { | ||
let rpcIsSyncing = false; | ||
// not available on all networks | ||
if(this._isSyncingMethodExist) { | ||
try { | ||
rpcIsSyncing = await this.app.client.RPCClient.web3.eth.isSyncing(); | ||
} catch(err) { | ||
this._isSyncingMethodExist = false; | ||
this.app.logger.error(`report.fullReport() - web3.eth.isSyncing failed: ${err}`); | ||
} | ||
|
||
async checkDatabase() { | ||
try { | ||
const isHealthy = (await this.app.db.sysQueries.healthCheck()) !== undefined; | ||
return {isHealthy, reason: ''}; | ||
} catch (err) { | ||
this.app.logger.error(`Report.checkDatabase(): ${err}`); | ||
return {isHealthy: false, reason: `Database check failed: ${err.message}`}; | ||
} | ||
} | ||
const rpcProvider = (new URL(this.app.config.HTTP_RPC_NODE)).hostname; | ||
const databaseOk = await this.checkDatabase(); | ||
const estimationQueueSize = this.app.queues.getEstimationQueueLength(); | ||
const agreementQueueSize = this.app.queues.getAgreementQueueLength(); | ||
const lastTimeNewBlocks = this.app.eventTracker.lastTimeNewBlocks; | ||
const waitingForNewBlocksSince = Math.floor(Math.abs(new Date() - lastTimeNewBlocks) / 1000); | ||
const RPCStuck = waitingForNewBlocksSince * 1000 > this.app.config.POLLING_INTERVAL * 2; | ||
const overallHealthy = rpcIsSyncing === false && databaseOk && !RPCStuck; | ||
return { | ||
timestamp: Date.now(), | ||
healthy: overallHealthy, | ||
process: { | ||
uptime: Math.floor(process.uptime()), | ||
pid: process.pid | ||
}, | ||
network: { | ||
chainId: await this.app.client.getChainId(), | ||
rpc: { | ||
rpcProvider: rpcProvider, | ||
totalRequests: this.app.client.getTotalRequests(), | ||
isSyncing: rpcIsSyncing, | ||
lastTimeNewBlocks: lastTimeNewBlocks, | ||
waitingForNewBlocksSince: waitingForNewBlocksSince, | ||
msg: this._isSyncingMethodExist ? "" : "RPC doesn't implement web3.eth.isSyncing", | ||
|
||
async checkRPCSyncing() { | ||
if (!this._isSyncingMethodExist) { | ||
return {isHealthy: true, reason: 'RPC does not implement web3.eth.isSyncing'}; | ||
} | ||
}, | ||
account: { | ||
address: this.app.client.getAccountAddress(), | ||
balance: await this.app.client.getAccountBalance() | ||
}, | ||
queues: { | ||
agreementQueue: agreementQueueSize, | ||
estimationQueue: estimationQueueSize | ||
}, | ||
protocol: { | ||
cfa: this.app.client.contracts.getCFAv1Address(), | ||
ida: this.app.client.contracts.getIDAv1Address(), | ||
gda: this.app.client.contracts.getGDAv1Address(), | ||
supertokens: Object.values(this.app.client.superToken.superTokenNames) | ||
} | ||
}; | ||
} | ||
|
||
try { | ||
const isSyncing = await this.app.client.RPCClient.web3.eth.isSyncing(); | ||
return {isHealthy: !isSyncing, reason: isSyncing ? 'RPC is syncing' : ''}; | ||
} catch (err) { | ||
this._isSyncingMethodExist = false; | ||
this.app.logger.error('Report.checkRPCSyncing()', err); | ||
return {isHealthy: false, reason: `RPC syncing check failed: ${err.message}`}; | ||
} | ||
} | ||
|
||
async checkRPCStuck() { | ||
|
||
const waitingForNewBlocksSince = this.awaitingForNewBlocksSince(); | ||
const rpcStuckThreshold = this.app.config.RPC_STUCK_THRESHOLD; | ||
const isStuck = waitingForNewBlocksSince > rpcStuckThreshold; | ||
const reason = isStuck ? `RPC is stuck. No new blocks for ${waitingForNewBlocksSince} s` : ''; | ||
return {isHealthy: !isStuck, reason}; | ||
} | ||
|
||
awaitingForNewBlocksSince() { | ||
const currentTime = Date.now(); | ||
const lastTimeNewBlocks = this.app.eventTracker.lastTimeNewBlocks.getTime(); | ||
return Math.floor(Math.abs(currentTime - lastTimeNewBlocks) / 1000); | ||
} | ||
|
||
|
||
async fullReport() { | ||
|
||
const healthDiagnostics = { | ||
database: await this.checkDatabase(), | ||
rpcSyncing: await this.checkRPCSyncing(), | ||
rpcStuck: await this.checkRPCStuck() | ||
}; | ||
|
||
const overallHealthy = Object.values(healthDiagnostics).every(check => check.isHealthy); | ||
const reasons = Object.entries(healthDiagnostics) | ||
.filter(([_, check]) => !check.isHealthy) | ||
.map(([key, check]) => `${key}: ${check.reason}`); | ||
|
||
return { | ||
timestamp: Date.now(), | ||
healthy: overallHealthy, | ||
reasons: reasons, | ||
|
||
process: { | ||
uptime: Math.floor(process.uptime()), | ||
pid: process.pid | ||
}, | ||
|
||
network: { | ||
chainId: await this.app.client.getChainId(), | ||
rpc: { | ||
rpcProvider: (new URL(this.app.config.HTTP_RPC_NODE)).hostname, | ||
totalRequests: this.app.client.getTotalRequests(), | ||
isSyncing: healthDiagnostics.rpcSyncing.isHealthy, | ||
lastTimeNewBlocks: this.app.eventTracker.lastTimeNewBlocks, | ||
waitingForNewBlocksSince: this.awaitingForNewBlocksSince(), | ||
msg: this._isSyncingMethodExist ? "" : "RPC doesn't implement web3.eth.isSyncing", | ||
} | ||
}, | ||
|
||
account: { | ||
address: this.app.client.getAccountAddress(), | ||
balance: (await this.app.client.getAccountBalance()).toString(), | ||
}, | ||
|
||
queues: { | ||
agreementQueue: this.app.queues.getAgreementQueueLength(), | ||
estimationQueue: this.app.queues.getEstimationQueueLength() | ||
}, | ||
|
||
protocol: { | ||
cfa: this.app.client.contracts.getCFAv1Address(), | ||
ida: this.app.client.contracts.getIDAv1Address(), | ||
gda: this.app.client.contracts.getGDAv1Address(), | ||
supertokens: Object.values(this.app.client.superToken.superTokenNames) | ||
} | ||
}; | ||
} | ||
} | ||
|
||
module.exports = Report; |
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
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
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
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
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