Skip to content

Commit

Permalink
fix: 🐛 stop polling debug_metrics for recent Geth versions
Browse files Browse the repository at this point in the history
Added new check whether geth supports the debug_metrics RPC method,
since support has been dropped in newer versions (as of 1.9). This fixes
the issue where ethlogger output is spammed with error messages of the
node metrics request failing.

✅ Closes: #49
  • Loading branch information
ziegfried committed Aug 7, 2020
1 parent a8b34d7 commit 66180f7
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 8 deletions.
2 changes: 1 addition & 1 deletion src/platforms/generic.ts
Expand Up @@ -24,7 +24,7 @@ import { prefixKeys } from '../utils/obj';

const { debug, warn, error } = createModuleDebug('platforms:generic');

export async function checkRpcMethodSupport(eth: EthereumClient, req: EthRequest<[], any>): Promise<boolean> {
export async function checkRpcMethodSupport(eth: EthereumClient, req: EthRequest<any, any>): Promise<boolean> {
try {
debug('Checking if RPC method %s is supported by ethereum node', req.method);
await eth.request(req, { immediate: true });
Expand Down
40 changes: 33 additions & 7 deletions src/platforms/geth.ts
Expand Up @@ -8,7 +8,7 @@ import { createModuleDebug } from '../utils/debug';
import { durationStringToMs, parseAbbreviatedNumber } from '../utils/parse';
import { captureDefaultMetrics, GenericNodeAdapter, checkRpcMethodSupport } from './generic';

const { debug, error } = createModuleDebug('platforms:geth');
const { debug, info, error } = createModuleDebug('platforms:geth');

type MetricsObj = { [k: string]: number | string | any[] | MetricsObj };

Expand Down Expand Up @@ -67,15 +67,25 @@ export function formatGethMemStats(memStats: GethMemStats): [string, number | un
);
}

export async function captureGethMetrics(ethClient: EthereumClient, captureTime: number): Promise<NodeMetricsMessage> {
export async function captureGethMetrics(
ethClient: EthereumClient,
captureTime: number,
supports: { debugMetrics: boolean; memStats: boolean }
): Promise<NodeMetricsMessage | null> {
if (!supports.debugMetrics && !supports.memStats) {
return null;
}
const [metricsResults, memStatsResults] = await Promise.all([
ethClient.request(gethMetrics(true)),
ethClient.request(gethMemStats()),
supports.debugMetrics ? ethClient.request(gethMetrics(true)) : null,
supports.memStats ? ethClient.request(gethMemStats()) : null,
]);
return {
type: 'nodeMetrics',
time: captureTime,
metrics: Object.fromEntries([...formatGethMetrics(metricsResults), ...formatGethMemStats(memStatsResults)]),
metrics: Object.fromEntries([
...(metricsResults != null ? formatGethMetrics(metricsResults) : []),
...(memStatsResults != null ? formatGethMemStats(memStatsResults) : []),
]),
};
}

Expand Down Expand Up @@ -133,6 +143,22 @@ export interface GethNodeInfo extends NodeInfo {
export class GethAdapter extends GenericNodeAdapter {
protected gethNodeInfo?: GethNodeInfoResponse;

protected gethSupports?: { debugMetrics: boolean; memStats: boolean };

public async initialize(ethClient: EthereumClient) {
await super.initialize(ethClient);
debug('Determining support for geth-specific RPC methods');
const [supportsDebugMetrics, supportsMemStats] = await Promise.all([
checkRpcMethodSupport(ethClient, gethMetrics(true)),
checkRpcMethodSupport(ethClient, gethMemStats()),
]);
this.gethSupports = {
debugMetrics: supportsDebugMetrics,
memStats: supportsMemStats,
};
info('Determined support for geth-specific RPC methods: %o', this.gethSupports);
}

public async captureNodeInfo(ethClient: EthereumClient): Promise<NodeInfo> {
debug('Retrieving nodeInfo from geth node');
const [baseNodeInfo, gethNodeInfoRes, clientVersionRes] = await Promise.all([
Expand Down Expand Up @@ -161,9 +187,9 @@ export class GethAdapter extends GenericNodeAdapter {
public async captureNodeMetrics(ethClient: EthereumClient, captureTime: number): Promise<NodeMetricsMessage[]> {
const [defaultMetrics, gethMetrics] = await Promise.all([
captureDefaultMetrics(ethClient, captureTime),
captureGethMetrics(ethClient, captureTime),
captureGethMetrics(ethClient, captureTime, this.gethSupports!),
]);
return [defaultMetrics, gethMetrics];
return [defaultMetrics, gethMetrics].filter(m => m != null) as NodeMetricsMessage[];
}

public async supportsPendingTransactions(ethClient: EthereumClient): Promise<boolean> {
Expand Down

0 comments on commit 66180f7

Please sign in to comment.