Skip to content
Open
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
24 changes: 11 additions & 13 deletions packages/relay/src/lib/clients/cache/localLRUCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,10 @@
const cache = this.getCacheInstance(key);
const value = cache.get(prefixedKey);
if (value !== undefined) {
const censoredKey = key.replace(Utils.IP_ADDRESS_REGEX, '<REDACTED>');
const censoredValue = JSON.stringify(value).replace(/"ipAddress":"[^"]+"/, '"ipAddress":"<REDACTED>"');
if (this.logger.isLevelEnabled('trace')) {
this.logger.trace(`Returning cached value ${censoredKey}:${censoredValue} on ${callingMethod} call`);
const censoredKey = key.replace(Utils.IP_ADDRESS_REGEX, '<REDACTED>');
const censoredValue = JSON.stringify(value).replace(/"ipAddress":"[^"]+"/, '"ipAddress":"<REDACTED>"');
this.logger.trace('Returning cached value %s:%s on %s call', censoredKey, censoredValue, callingMethod);

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This logs sensitive data returned by
process environment
as clear text.
}
return value;
}
Expand All @@ -144,9 +144,8 @@
const prefixedKey = this.prefixKey(key);
const cache = this.getCacheInstance(key);
const remainingTtl = cache.getRemainingTTL(prefixedKey); // in milliseconds
if (this.logger.isLevelEnabled('trace')) {
this.logger.trace(`returning remaining TTL ${key}:${remainingTtl} on ${callingMethod} call`);
}
this.logger.trace(`returning remaining TTL %s:%s on %s call`, key, remainingTtl, callingMethod);

return remainingTtl;
}

Expand All @@ -173,7 +172,7 @@
const message = `Caching ${censoredKey}:${censoredValue} on ${callingMethod} for ${
resolvedTtl > 0 ? `${resolvedTtl} ms` : 'indefinite time'
}`;
this.logger.trace(`${message} (cache size: ${this.cache.size}, max: ${this.options.max})`);
this.logger.trace(`%s (cache size: %s, max: %s)`, message, this.cache.size, this.options.max);

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This logs sensitive data returned by
process environment
as clear text.
}
}

Expand Down Expand Up @@ -214,9 +213,9 @@
*/
public async delete(key: string, callingMethod: string): Promise<void> {
const prefixedKey = this.prefixKey(key);
if (this.logger.isLevelEnabled('trace')) {
this.logger.trace(`delete cache for ${key} on ${callingMethod} call`);
}

this.logger.trace(`delete cache for %s on %s call`, key, callingMethod);

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This logs sensitive data returned by
process environment
as clear text.

const cache = this.getCacheInstance(key);
cache.delete(prefixedKey);
}
Expand Down Expand Up @@ -275,9 +274,8 @@

const matchingKeys = keys.filter((key) => regex.test(key));

if (this.logger.isLevelEnabled('trace')) {
this.logger.trace(`retrieving keys matching ${pattern} on ${callingMethod} call`);
}
this.logger.trace(`retrieving keys matching %s on %s call`, pattern, callingMethod);

// Remove the prefix from the returned keys
return matchingKeys.map((key) => key.substring(LocalLRUCache.CACHE_KEY_PREFIX.length));
}
Expand Down
50 changes: 24 additions & 26 deletions packages/relay/src/lib/clients/cache/redisCache/redisCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export class RedisCache implements ICacheClient {
if (this.logger.isLevelEnabled('trace')) {
const censoredKey = key.replace(Utils.IP_ADDRESS_REGEX, '<REDACTED>');
const censoredValue = result.replace(/"ipAddress":"[^"]+"/, '"ipAddress":"<REDACTED>"');
this.logger.trace(`Returning cached value ${censoredKey}:${censoredValue} on ${callingMethod} call`);
this.logger.trace(`Returning cached value %s:%s on %s call`, censoredKey, censoredValue, callingMethod);
}
// TODO: add metrics
return JSON.parse(result);
Expand All @@ -106,13 +106,13 @@ export class RedisCache implements ICacheClient {
await this.client.set(prefixedKey, serializedValue);
}

const censoredKey = key.replace(Utils.IP_ADDRESS_REGEX, '<REDACTED>');
const censoredValue = serializedValue.replace(/"ipAddress":"[^"]+"/, '"ipAddress":"<REDACTED>"');
const message = `Caching ${censoredKey}:${censoredValue} on ${callingMethod} for ${
resolvedTtl > 0 ? `${resolvedTtl} ms` : 'indefinite time'
}`;
if (this.logger.isLevelEnabled('trace')) {
this.logger.trace(`${message}`);
const censoredKey = key.replace(Utils.IP_ADDRESS_REGEX, '<REDACTED>');
const censoredValue = serializedValue.replace(/"ipAddress":"[^"]+"/, '"ipAddress":"<REDACTED>"');
const message = `Caching ${censoredKey}:${censoredValue} on ${callingMethod} for ${
resolvedTtl > 0 ? `${resolvedTtl} ms` : 'indefinite time'
}`;
this.logger.trace(`%s`, message);
}
// TODO: add metrics
}
Expand All @@ -138,9 +138,12 @@ export class RedisCache implements ICacheClient {
await this.client.mSet(serializedKeyValuePairs);

// Log the operation
const entriesLength = Object.keys(keyValuePairs).length;
if (this.logger.isLevelEnabled('trace')) {
this.logger.trace(`caching multiple keys via ${callingMethod}, total keys: ${entriesLength}`);
this.logger.trace(
`caching multiple keys via %s, total keys: %s`,
callingMethod,
Object.keys(keyValuePairs).length,
);
}
}

Expand All @@ -166,10 +169,13 @@ export class RedisCache implements ICacheClient {
// Execute pipeline operation
await pipeline.execAsPipeline();

// Log the operation
if (this.logger.isLevelEnabled('trace')) {
// Log the operation
const entriesLength = Object.keys(keyValuePairs).length;
this.logger.trace(`caching multiple keys via ${callingMethod}, total keys: ${entriesLength}`);
this.logger.trace(
`caching multiple keys via %s, total keys: %s`,
callingMethod,
Object.keys(keyValuePairs).length,
);
}
}

Expand All @@ -183,9 +189,7 @@ export class RedisCache implements ICacheClient {
async delete(key: string, callingMethod: string): Promise<void> {
const prefixedKey = this.prefixKey(key);
await this.client.del(prefixedKey);
if (this.logger.isLevelEnabled('trace')) {
this.logger.trace(`delete cache for ${key} on ${callingMethod} call`);
}
this.logger.trace(`delete cache for %s on %s call`, key, callingMethod);
// TODO: add metrics
}

Expand All @@ -200,9 +204,7 @@ export class RedisCache implements ICacheClient {
async incrBy(key: string, amount: number, callingMethod: string): Promise<number> {
const prefixedKey = this.prefixKey(key);
const result = await this.client.incrBy(prefixedKey, amount);
if (this.logger.isLevelEnabled('trace')) {
this.logger.trace(`incrementing ${key} by ${amount} on ${callingMethod} call`);
}
this.logger.trace(`incrementing %s by %s on %s call`, key, amount, callingMethod);
return result;
}

Expand All @@ -218,9 +220,7 @@ export class RedisCache implements ICacheClient {
async lRange(key: string, start: number, end: number, callingMethod: string): Promise<any[]> {
const prefixedKey = this.prefixKey(key);
const result = await this.client.lRange(prefixedKey, start, end);
if (this.logger.isLevelEnabled('trace')) {
this.logger.trace(`retrieving range [${start}:${end}] from ${key} on ${callingMethod} call`);
}
this.logger.trace(`retrieving range [%s:%s] from %s on %s call`, start, end, key, callingMethod);
return result.map((item) => JSON.parse(item));
}

Expand All @@ -237,7 +237,7 @@ export class RedisCache implements ICacheClient {
const serializedValue = JSON.stringify(value);
const result = await this.client.rPush(prefixedKey, serializedValue);
if (this.logger.isLevelEnabled('trace')) {
this.logger.trace(`pushing ${serializedValue} to ${key} on ${callingMethod} call`);
this.logger.trace(`pushing %s to %s on %s call`, serializedValue, key, callingMethod);
}
return result;
}
Expand All @@ -251,9 +251,7 @@ export class RedisCache implements ICacheClient {
async keys(pattern: string, callingMethod: string): Promise<string[]> {
const prefixedPattern = this.prefixKey(pattern);
const result = await this.client.keys(prefixedPattern);
if (this.logger.isLevelEnabled('trace')) {
this.logger.trace(`retrieving keys matching ${pattern} on ${callingMethod} call`);
}
this.logger.trace(`retrieving keys matching %s on %s call`, pattern, callingMethod);
// Remove the prefix from the returned keys
return result.map((key) => key.substring(RedisCache.CACHE_KEY_PREFIX.length));
}
Expand All @@ -278,7 +276,7 @@ export class RedisCache implements ICacheClient {
await pipeline.exec();

if (this.logger.isLevelEnabled('trace')) {
this.logger.trace(`Cleared ${keysToDelete.length} cache keys`);
this.logger.trace(`Cleared %s cache keys`, keysToDelete.length);
}
}
}
Expand Down
85 changes: 51 additions & 34 deletions packages/relay/src/lib/clients/mirrorNodeClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@
retryDelay: (retryCount, error) => {
const delay = mirrorNodeRetryDelay * retryCount;
if (this.logger.isLevelEnabled('trace')) {
this.logger.trace(`Retry delay ${delay} ms on '${error?.request?.path}'`);
this.logger.trace(`Retry delay %s ms on '%s'`, delay, error?.request?.path);
}
return delay;
},
Expand Down Expand Up @@ -290,7 +290,9 @@
});

this.logger.info(
`Mirror Node client successfully configured to REST url: ${this.restUrl} and Web3 url: ${this.web3Url} `,
`Mirror Node client successfully configured to REST url: %s and Web3 url: %s `,
this.restUrl,

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This logs sensitive data returned by
process environment
as clear text.
this.web3Url,

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This logs sensitive data returned by
process environment
as clear text.
);
this.cacheService = cacheService;

Expand Down Expand Up @@ -377,7 +379,7 @@
try {
return JSONBigInt.parse(data);
} catch (error) {
this.logger.warn(`Failed to parse response data from Mirror Node: ${error}`);
this.logger.warn(`Failed to parse response data from Mirror Node: %s`, error);
}
}

Expand All @@ -394,9 +396,12 @@
const ms = Date.now() - start;
if (this.logger.isLevelEnabled('debug')) {
this.logger.debug(
`Successfully received response from mirror node server: method=${method}, path=${path}, status=${
response.status
}, duration:${ms}ms, data:${JSON.stringify(response.data)}`,
`Successfully received response from mirror node server: method=%s, path=%s, status=%s, duration:%sms, data:%s`,
method,
path,

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This logs sensitive data returned by
process environment
as clear text.
response.status,
ms,
JSON.stringify(response.data),
);
}
this.mirrorResponseHistogram.labels(pathLabel, response.status?.toString()).observe(ms);
Expand Down Expand Up @@ -451,27 +456,35 @@
const acceptedErrorResponses = MirrorNodeClient.acceptedErrorStatusesResponsePerRequestPathMap.get(pathLabel);

if (error.response && acceptedErrorResponses?.includes(effectiveStatusCode)) {
if (this.logger.isLevelEnabled('debug')) {
this.logger.debug(
`An accepted error occurred while communicating with the mirror node server: method=${method}, path=${path}, status=${effectiveStatusCode}`,
);
}
this.logger.debug(
`An accepted error occurred while communicating with the mirror node server: method=%s, path=%s, status=%s}`,
method,
path,

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This logs sensitive data returned by
process environment
as clear text.
effectiveStatusCode,
);
return null;
}

// Contract Call returns 400 for a CONTRACT_REVERT but is a valid response, expected and should not be logged as error:
if (pathLabel === MirrorNodeClient.CONTRACT_CALL_ENDPOINT && effectiveStatusCode === 400) {
if (this.logger.isLevelEnabled('debug')) {
this.logger.debug(
`[${method}] ${path} Contract Revert: ( StatusCode: '${effectiveStatusCode}', StatusText: '${
error.response.statusText
}', Detail: '${JSON.stringify(error.response.detail)}',Data: '${JSON.stringify(error.response.data)}')`,
`[%s] %s Contract Revert: ( StatusCode: '%s', StatusText: '%s', Detail: '%s',Data: '%s')`,
method,
path,

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This logs sensitive data returned by
process environment
as clear text.
effectiveStatusCode,
error.response.statusText,
JSON.stringify(error.response.detail),
JSON.stringify(error.response.data),
);
}
} else {
this.logger.error(
new Error(error.message),
`Error encountered while communicating with the mirror node server: method=${method}, path=${path}, status=${effectiveStatusCode}`,
`Error encountered while communicating with the mirror node server: method=%s, path=%s, status=%s`,
method,
path,

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This logs sensitive data returned by
process environment
as clear text.
effectiveStatusCode,
);
}

Expand All @@ -497,7 +510,7 @@
if (page === pageMax) {
// max page reached
if (this.logger.isLevelEnabled('trace')) {
this.logger.trace(`Max page reached ${pageMax} with ${results.length} results`);
this.logger.trace(`Max page reached %s with %s results`, pageMax, results.length);
}
throw predefined.PAGINATION_MAX(pageMax);
}
Expand Down Expand Up @@ -575,15 +588,15 @@
const match = url.match(regex);
const accountId = match ? match[1] : null;
if (!accountId) {
this.logger.error(`Unable to extract evm address from url ${url}`);
this.logger.error(`Unable to extract evm address from url %s`, url);
}
return String(accountId);
} else {
// account id
const match = url.match(MirrorNodeClient.EVM_ADDRESS_REGEX);
const accountId = match ? match[1] : null;
if (!accountId) {
this.logger.error(`Unable to extract account ID from url ${url}`);
this.logger.error(`Unable to extract account ID from url %s`, url);
}
return String(accountId);
}
Expand Down Expand Up @@ -802,9 +815,9 @@
// Found immature record, log the info, set flag and exit record traversal
if (this.logger.isLevelEnabled('debug')) {
this.logger.debug(
`Contract result contains nullable transaction_index or block_number, or block_hash is an empty hex (0x): contract_result=${JSON.stringify(
contractObject,
)}. ${!isLastAttempt ? `Retrying after a delay of ${mirrorNodeRetryDelay} ms.` : ``}`,
`Contract result contains nullable transaction_index or block_number, or block_hash is an empty hex (0x): contract_result=%s. %s}`,
JSON.stringify(contractObject),
!isLastAttempt ? `Retrying after a delay of ${mirrorNodeRetryDelay} ms.` : ``,

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This logs sensitive data returned by
process environment
as clear text.
);
}

Expand Down Expand Up @@ -991,9 +1004,9 @@
// Found immature record, log the info, set flag and exit record traversal
if (this.logger.isLevelEnabled('debug')) {
this.logger.debug(
`Contract result log contains nullable transaction_index, block_number, index, or block_hash is an empty hex (0x): log=${JSON.stringify(
log,
)}. ${!isLastAttempt ? `Retrying after a delay of ${mirrorNodeRetryDelay} ms.` : ``}`,
`Contract result log contains nullable transaction_index, block_number, index, or block_hash is an empty hex (0x): log=%s. %s`,
JSON.stringify(log),
!isLastAttempt ? `Retrying after a delay of ${mirrorNodeRetryDelay} ms.` : ``,

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This logs sensitive data returned by
process environment
as clear text.
);
}

Expand Down Expand Up @@ -1484,7 +1497,9 @@
} else {
this.logger.warn(
e,
`Error raised during polling mirror node for updated records: method=${methodName}, args=${args}`,
`Error raised during polling mirror node for updated records: method=%s, args=%s`,
methodName,
args,

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This logs sensitive data returned by
process environment
as clear text.
);
}
}
Expand All @@ -1495,9 +1510,12 @@

if (this.logger.isLevelEnabled('debug')) {
this.logger.debug(
`Repeating request ${methodName} with args ${JSON.stringify(
args,
)} retry count ${i} of ${repeatCount}. Waiting ${this.MIRROR_NODE_RETRY_DELAY} ms before repeating request`,
`Repeating request %s with args %s retry count %s of %s. Waiting %s ms before repeating request`,
methodName,
JSON.stringify(args),

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This logs sensitive data returned by
process environment
as clear text.
i,
repeatCount,

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This logs sensitive data returned by
process environment
as clear text.
this.MIRROR_NODE_RETRY_DELAY,

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This logs sensitive data returned by
process environment
as clear text.
);
}

Expand All @@ -1523,12 +1541,11 @@
operatorAccountId: string,
requestDetails: RequestDetails,
): Promise<ITransactionRecordMetric> {
if (this.logger.isLevelEnabled('debug')) {
this.logger.debug(
`Get transaction record via mirror node: transactionId=${transactionId}, txConstructorName=${txConstructorName}`,
);
}

this.logger.debug(
`Get transaction record via mirror node: transactionId=%s, txConstructorName=%s`,
transactionId,
txConstructorName,
);
// Create a modified copy of requestDetails
const modifiedRequestDetails = new RequestDetails({
requestId: requestDetails.requestId,
Expand Down
Loading
Loading