Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Debug logging enhancements #68

Merged
merged 18 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion api/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,32 @@
import 'dotenv/config';
import process from 'node:process';
import { NestFactory } from '@nestjs/core';
import { LogLevel } from '@nestjs/common';
import { NestExpressApplication } from '@nestjs/platform-express';
import { AppModule } from './app/app.module.js';
import getConfig from './config/config.js';

function makeLogLevelList(): LogLevel[] {
// From: https://github.com/nestjs/nest/blob/master/packages/common/services/logger.service.ts#L9
const allLogLevels: LogLevel[] = ['verbose', 'debug', 'log', 'warn', 'error', 'fatal'];
// From: https://stackoverflow.com/a/78585135/1701505
const levels = allLogLevels.slice(
// TODO: possibly the env var shoud come via dotenv, or Config?
allLogLevels.indexOf((process.env.NESTJS_LOG_LEVEL || 'log') as LogLevel),
allLogLevels.length,
);
return levels;
}

async function bootstrap() {
const config = getConfig();

const app = await NestFactory.create<NestExpressApplication>(AppModule);
const app = await NestFactory.create<NestExpressApplication>(
AppModule,
{
logger: makeLogLevelList()
}
);

app.enableShutdownHooks();

Expand Down
1 change: 1 addition & 0 deletions api/src/ol/validators/validators.processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ export class ValidatorsProcessor extends WorkerHost {
try {
const validators = await this.validatorsService.queryValidators();
await redisClient.set(VALIDATORS_CACHE_KEY, JSON.stringify(validators));
this.logger.debug(`Wrote this to the cache: ${JSON.stringify(validators).slice(0, 200)}`)
const duration = Date.now() - start;
this.logger.log(`Validators cache updated in ${duration}ms`);
} catch (error) {
Expand Down
28 changes: 24 additions & 4 deletions api/src/ol/validators/validators.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,31 +64,45 @@ export class ValidatorsService {
if (this.cacheEnabled) {
const cachedValidators = await this.getFromCache<Validator[]>(VALIDATORS_CACHE_KEY);
if (cachedValidators) {
this.logger.debug('Returning cached validators')
this.logger.debug(`Read this data from cache: ${JSON.stringify(cachedValidators).slice(0, 200)}`)
return cachedValidators;
}
}

const validators = await this.queryValidators();
await this.setCache('validators', validators);
await this.setCache(VALIDATORS_CACHE_KEY, validators);
this.logger.debug('Stored validators in cache')
this.logger.debug(`This data written back: ${JSON.stringify(validators).slice(0, 200)}`)

return validators;
}

public async getValidatorsHandlers(): Promise<Map<string, string>> {
if (this.cacheEnabled) {
this.logger.debug('Cache is enabled')
const cacheHandlersString = await this.getFromCache<string>(VALIDATORS_HANDLERS_CACHE_KEY);
return cacheHandlersString
? new Map<string, string>(Object.entries(cacheHandlersString))
: new Map();
// NOTE: cacheHandlersString is NOT a string (it is an Object)
let result:Map<string, string> = new Map([['bad', 'data']]);
if (cacheHandlersString) {
let entries = Object.entries(cacheHandlersString);
result = new Map<string, string>(entries)
} else {
result = new Map();
}
this.logger.debug(`returning handles map with ${result.size} entries`)
return result;
}

let handlers = new Map<string, string>();
try {
handlers = await this.loadValidatorHandles();
this.logger.debug(`Loaded validator handles: ${handlers}, ${JSON.stringify(handlers)}`)
} catch (error) {
this.logger.error('Error loading validators handlers', error);
} finally {
const obj = Object.fromEntries(handlers);
this.logger.debug(`Storing validator handles: ${obj}, ${JSON.stringify(obj)}`)
await redisClient.set(VALIDATORS_HANDLERS_CACHE_KEY, JSON.stringify(obj));
this.logger.log('Validators handlers cache updated');
}
Expand Down Expand Up @@ -171,6 +185,7 @@ export class ValidatorsService {
);

let handles = await this.getValidatorsHandlers();
this.logger.debug(`handles map has ${handles.size} entries`)
let allValidators = [...currentValidators, ...eligibleValidators];
return await Promise.all(
allValidators.map(async (validator) => {
Expand All @@ -180,6 +195,9 @@ export class ValidatorsService {
const slowWallet = await this.olService.getSlowWallet(validator.address);
const unlocked = Number(slowWallet?.unlocked);
const addr = validator.address.toString('hex').toLocaleUpperCase();
if (!handles.get(addr)) {
this.logger.debug(`handles miss for address ${addr}`)
}
const handle = handles.get(addr) || null;

return new Validator({
Expand Down Expand Up @@ -319,6 +337,7 @@ export class ValidatorsService {
const eligible = await this.olService.getEligibleValidators();
const active = await this.olService.getValidatorSet();
const handles = await this.getValidatorsHandlers();
this.logger.debug(`handles map has ${handles.size} entries`)
const currentEpoch = await this.olService.aptosClient
.getLedgerInfo()
.then((info) => Number(info.epoch));
Expand Down Expand Up @@ -457,6 +476,7 @@ export class ValidatorsService {

async loadValidatorHandles(): Promise<Map<string, string>> {
if (!this.validatorHandlesUrl) {
this.logger.warn('Validator handles URL is not configured')
return new Map<string, string>();
}

Expand Down
Loading