mirror of
https://github.com/mempool/mempool.git
synced 2026-08-13 12:33:11 +02:00
Merge pull request #6185 from mempool/mononaut/ssr-monitoring
This commit is contained in:
commit
389b91eeec
5 changed files with 71 additions and 6 deletions
|
|
@ -3,9 +3,12 @@ import path from 'path';
|
|||
import os from 'os';
|
||||
import { IBackendInfo } from '../mempool.interfaces';
|
||||
import config from '../config';
|
||||
import bitcoinClient from './bitcoin/bitcoin-client';
|
||||
import logger from '../logger';
|
||||
|
||||
class BackendInfo {
|
||||
private backendInfo: IBackendInfo;
|
||||
private timer;
|
||||
|
||||
constructor() {
|
||||
// This file is created by ./fetch-version.ts during building
|
||||
|
|
@ -26,7 +29,22 @@ class BackendInfo {
|
|||
gitCommit: versionInfo.gitCommit,
|
||||
lightning: config.LIGHTNING.ENABLED,
|
||||
backend: config.MEMPOOL.BACKEND,
|
||||
coreVersion: '?',
|
||||
};
|
||||
|
||||
this.timer = setInterval(async () => {
|
||||
await this.$updateCoreVersion();
|
||||
}, 10 * 60 * 1000); // every 10 minutes
|
||||
this.$updateCoreVersion(); // starting immediately
|
||||
}
|
||||
|
||||
private async $updateCoreVersion(): Promise<void> {
|
||||
try {
|
||||
const networkInfo = await bitcoinClient.getNetworkInfo();
|
||||
this.backendInfo.coreVersion = networkInfo.subversion;
|
||||
} catch (e) {
|
||||
logger.err(`Exception in $updateCoreVersion. Reason: ${(e instanceof Error ? e.message : e)}`);
|
||||
}
|
||||
}
|
||||
|
||||
public getBackendInfo(): IBackendInfo {
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ interface FailoverHost {
|
|||
hybrid?: string,
|
||||
backend?: string,
|
||||
electrs?: string,
|
||||
ssr?: string,
|
||||
core?: string,
|
||||
lastUpdated: number,
|
||||
}
|
||||
}
|
||||
|
|
@ -35,7 +37,7 @@ interface FailoverHost {
|
|||
class FailoverRouter {
|
||||
activeHost: FailoverHost;
|
||||
fallbackHost: FailoverHost;
|
||||
maxSlippage: number = config.ESPLORA.MAX_BEHIND_TIP ?? 2;
|
||||
maxSlippage: number = config.ESPLORA.MAX_BEHIND_TIP ?? (Common.isLiquid() ? 8 : 2);
|
||||
maxHeight: number = 0;
|
||||
hosts: FailoverHost[];
|
||||
multihost: boolean;
|
||||
|
|
@ -145,7 +147,8 @@ class FailoverRouter {
|
|||
if (Date.now() - host.hashes.lastUpdated > this.gitHashInterval) {
|
||||
await Promise.all([
|
||||
this.$updateFrontendGitHash(host),
|
||||
this.$updateBackendGitHash(host),
|
||||
this.$updateBackendVersions(host),
|
||||
this.$updateSSRGitHash(host),
|
||||
config.MEMPOOL.OFFICIAL ? this.$updateHybridGitHash(host) : Promise.resolve(),
|
||||
]);
|
||||
host.hashes.lastUpdated = Date.now();
|
||||
|
|
@ -301,18 +304,33 @@ class FailoverRouter {
|
|||
}
|
||||
}
|
||||
|
||||
private async $updateBackendGitHash(host: FailoverHost): Promise<void> {
|
||||
private async $updateBackendVersions(host: FailoverHost): Promise<void> {
|
||||
try {
|
||||
const url = `${host.publicDomain}/api/v1/backend-info`;
|
||||
const response = await this.pollConnection.get<any>(url, { timeout: config.ESPLORA.FALLBACK_TIMEOUT });
|
||||
if (response.data?.gitCommit) {
|
||||
host.hashes.backend = response.data.gitCommit;
|
||||
}
|
||||
if (response.data?.coreVersion) {
|
||||
host.hashes.core = response.data.coreVersion;
|
||||
}
|
||||
} catch (e) {
|
||||
// failed to get backend build hash - do nothing
|
||||
}
|
||||
}
|
||||
|
||||
private async $updateSSRGitHash(host: FailoverHost): Promise<void> {
|
||||
try {
|
||||
const url = `${host.publicDomain}/ssr/api/status`;
|
||||
const response = await this.pollConnection.get<any>(url, { timeout: config.ESPLORA.FALLBACK_TIMEOUT });
|
||||
if (response.data?.gitHash) {
|
||||
host.hashes.ssr = response.data.gitHash;
|
||||
}
|
||||
} catch (e) {
|
||||
// failed to get ssr build hash - do nothing
|
||||
}
|
||||
}
|
||||
|
||||
// returns the public mempool domain corresponding to an esplora server url
|
||||
// (a bit of a hack to avoid manually specifying frontend & backend URLs for each esplora server)
|
||||
private extractPublicDomain(url: string): string {
|
||||
|
|
|
|||
|
|
@ -504,9 +504,35 @@ export interface IBackendInfo {
|
|||
gitCommit: string;
|
||||
version: string;
|
||||
lightning: boolean;
|
||||
coreVersion: string;
|
||||
backend: 'esplora' | 'electrum' | 'none';
|
||||
}
|
||||
|
||||
export interface INetworkInfo {
|
||||
version: number;
|
||||
subversion: string;
|
||||
protocolversion: number;
|
||||
localservices: string;
|
||||
localrelay: boolean;
|
||||
timeoffset: number;
|
||||
networkactive: boolean;
|
||||
networks: {
|
||||
name: string;
|
||||
limited: boolean;
|
||||
reachable: boolean;
|
||||
proxy: string;
|
||||
proxy_randomize_credentials: boolean;
|
||||
}[];
|
||||
relayfee: number;
|
||||
incrementalfee: number;
|
||||
localaddresses: {
|
||||
address: string;
|
||||
port: number;
|
||||
score: number;
|
||||
}[];
|
||||
warnings: string;
|
||||
}
|
||||
|
||||
export interface IDifficultyAdjustment {
|
||||
progressPercent: number;
|
||||
difficultyChange: number;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
<th class="frontend only-large">Front</th>
|
||||
<th class="backend only-large">Back</th>
|
||||
<th class="electrs only-large">Electrs</th>
|
||||
<th class="ssr only-large">SSR</th>
|
||||
<th class="core only-large">Core</th>
|
||||
</tr>
|
||||
<tr *ngFor="let host of hosts; let i = index; trackBy: trackByFn">
|
||||
<td class="rank">{{ i + 1 }}</td>
|
||||
|
|
@ -32,9 +34,9 @@
|
|||
<td class="rtt only-small">{{ (host.rtt / 1000) | number : '1.1-1' }} {{ host.rtt == null ? '' : 's'}} {{ !host.checked ? '⏳' : (host.unreachable ? '🔥' : '✅') }}</td>
|
||||
<td class="rtt only-large">{{ host.rtt | number : '1.0-0' }} {{ host.rtt == null ? '' : 'ms'}} {{ !host.checked ? '⏳' : (host.unreachable ? '🔥' : '✅') }}</td>
|
||||
<td class="height">{{ host.latestHeight }} {{ !host.checked ? '⏳' : (host.outOfSync ? '🚫' : (host.latestHeight && host.latestHeight < maxHeight ? '🟧' : '✅')) }}</td>
|
||||
<ng-container *ngFor="let type of ['hybrid', 'frontend', 'backend', 'electrs']">
|
||||
<td class="{{type}} only-large" [style.background-color]="host.hashes?.[type] ? '#' + host.hashes[type].slice(0, 6) : ''">
|
||||
@if (host.hashes?.[type]) {
|
||||
<ng-container *ngFor="let type of ['hybrid', 'frontend', 'backend', 'electrs', 'ssr', 'core']">
|
||||
<td class="{{type}} only-large" [style.background-color]="type !== 'core' && host.hashes?.[type] ? '#' + host.hashes[type].slice(0, 6) : ''">
|
||||
@if (type !== 'core' && host.hashes?.[type]) {
|
||||
<a [style.color]="'white'" href="https://github.com/mempool/{{repoMap[type]}}/commit/{{ host.hashes[type] }}" target="_blank">{{ host.hashes[type].slice(0, 8) || '?' }}</a>
|
||||
} @else {
|
||||
<span>?</span>
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ export class ServerHealthComponent implements OnInit {
|
|||
hybrid: 'mempool.space',
|
||||
backend: 'mempool',
|
||||
electrs: 'electrs',
|
||||
ssr: 'mempool.space',
|
||||
};
|
||||
|
||||
constructor(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue