Skip to content

Commit

Permalink
feat: Make users capable of integrating modern logging library (#1215)
Browse files Browse the repository at this point in the history
  • Loading branch information
denbite committed Dec 6, 2023
1 parent 858b8ee commit ecf29e2
Show file tree
Hide file tree
Showing 21 changed files with 321 additions and 60 deletions.
9 changes: 9 additions & 0 deletions .changeset/nervous-bugs-doubt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"near-api-js": minor
"@near-js/accounts": patch
"@near-js/providers": patch
"@near-js/utils": patch
"@near-js/wallet-account": patch
---

Internal logging library with capabilities for integration with modern logging libraries like Pino, Winston, etc
2 changes: 2 additions & 0 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ const {
format,
logWarning,
rpc_errors,
Logger
} = utils;
const {
formatNearAmount,
Expand Down Expand Up @@ -316,5 +317,6 @@ import {
parseNearAmount,
parseResultError,
parseRpcError,
Logger
} from '@near-js/utils';
```
10 changes: 4 additions & 6 deletions packages/accounts/src/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import {
import {
baseDecode,
baseEncode,
logWarning,
Logger,
parseResultError,
DEFAULT_FUNCTION_CALL_GAS,
printTxOutcomeLogs,
Expand Down Expand Up @@ -223,12 +223,12 @@ export class Account {
return await this.connection.provider.sendTransaction(signedTx);
} catch (error) {
if (error.type === 'InvalidNonce') {
logWarning(`Retrying transaction ${receiverId}:${baseEncode(txHash)} with new nonce.`);
Logger.warn(`Retrying transaction ${receiverId}:${baseEncode(txHash)} with new nonce.`);
delete this.accessKeyByPublicKeyCache[publicKey.toString()];
return null;
}
if (error.type === 'Expired') {
logWarning(`Retrying transaction ${receiverId}:${baseEncode(txHash)} due to expired block hash`);
Logger.warn(`Retrying transaction ${receiverId}:${baseEncode(txHash)} due to expired block hash`);
return null;
}

Expand Down Expand Up @@ -360,9 +360,7 @@ export class Account {
* @param beneficiaryId The NEAR account that will receive the remaining Ⓝ balance from the account being deleted
*/
async deleteAccount(beneficiaryId: string) {
if (!(typeof process === 'object' && process.env['NEAR_NO_LOGS'])) {
console.log('Deleting an account does not automatically transfer NFTs and FTs to the beneficiary address. Ensure to transfer assets before deleting.');
}
Logger.log('Deleting an account does not automatically transfer NFTs and FTs to the beneficiary address. Ensure to transfer assets before deleting.');
return this.signAndSendTransaction({
receiverId: this.accountId,
actions: [deleteAccount(beneficiaryId)]
Expand Down
7 changes: 4 additions & 3 deletions packages/accounts/src/account_2fa.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { PublicKey } from '@near-js/crypto';
import { FinalExecutionOutcome, TypedError, FunctionCallPermissionView } from '@near-js/types';
import { fetchJson } from '@near-js/providers';
import { actionCreators } from '@near-js/transactions';
import { Logger } from '@near-js/utils'
import BN from 'bn.js';

import { SignAndSendTransactionOptions } from './account';
Expand Down Expand Up @@ -84,7 +85,7 @@ export class Account2FA extends AccountMultisig {
deployContract(contractBytes),
];
const newFunctionCallActionBatch = actions.concat(functionCall('new', newArgs, MULTISIG_GAS, MULTISIG_DEPOSIT));
console.log('deploying multisig contract for', accountId);
Logger.log('deploying multisig contract for', accountId);

const { stateStatus: multisigStateStatus } = await this.checkMultisigCodeAndStateStatus(contractBytes);
switch (multisigStateStatus) {
Expand Down Expand Up @@ -185,7 +186,7 @@ export class Account2FA extends AccountMultisig {
...(await this.get2faDisableKeyConversionActions()),
deployContract(contractBytes),
];
console.log('disabling 2fa for', this.accountId);
Logger.log('disabling 2fa for', this.accountId);
return await this.signAndSendTransaction({
receiverId: this.accountId,
actions
Expand Down Expand Up @@ -217,7 +218,7 @@ export class Account2FA extends AccountMultisig {
// TODO: Parse error from result for real (like in normal account.signAndSendTransaction)
return result;
} catch (e) {
console.warn('Error validating security code:', e);
Logger.warn('Error validating security code:', e);
if (e.toString().includes('invalid 2fa code provided') || e.toString().includes('2fa code not valid')) {
return await this.promptAndVerify();
}
Expand Down
3 changes: 2 additions & 1 deletion packages/accounts/src/account_multisig.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Action, actionCreators } from '@near-js/transactions';
import { FinalExecutionOutcome } from '@near-js/types';
import { Logger } from '@near-js/utils';

import { Account, SignAndSendTransactionOptions } from './account';
import { Connection } from './connection';
Expand Down Expand Up @@ -156,7 +157,7 @@ export class AccountMultisig extends Account {
actions: [functionCall('delete_request', { request_id: requestIdToDelete }, MULTISIG_GAS, MULTISIG_DEPOSIT)]
});
} catch (e) {
console.warn('Attempt to delete an earlier request before 15 minutes failed. Will try again.');
Logger.warn('Attempt to delete an earlier request before 15 minutes failed. Will try again.');
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions packages/accounts/src/contract.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getTransactionLastResult } from '@near-js/utils';
import { getTransactionLastResult, Logger } from '@near-js/utils';
import { ArgumentTypeError, PositionalArgsError } from '@near-js/types';
import { LocalViewExecution } from './local-view-execution';
import Ajv from 'ajv';
Expand Down Expand Up @@ -194,8 +194,8 @@ export class Contract {
...options,
});
} catch (error) {
console.warn(`Local view execution failed with: "${error.message}"`);
console.warn(`Fallback to normal RPC call`);
Logger.warn(`Local view execution failed with: "${error.message}"`);
Logger.warn(`Fallback to normal RPC call`);
}
}

Expand Down
41 changes: 23 additions & 18 deletions packages/accounts/test/account.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { getTransactionLastResult } = require('@near-js/utils');
const { getTransactionLastResult, Logger } = require('@near-js/utils');
const { actionCreators } = require('@near-js/transactions');
const { TypedError } = require('@near-js/types');
const BN = require('bn.js');
Expand Down Expand Up @@ -90,19 +90,23 @@ test('findAccessKey returns the same access key when fetched simultaneously', as
});

describe('errors', () => {
let oldLog;
let logs;

beforeEach(async () => {
oldLog = console.log;
logs = [];
console.log = function () {
logs.push(Array.from(arguments).join(' '));
beforeAll(async () => {
const custom = {
log: (...args) => {
logs.push(args.join(' '));
},
warn: () => {},
error: () => {},
};

Logger.overrideLogger(custom);
});

afterEach(async () => {
console.log = oldLog;
beforeEach(async () => {
logs = [];

});

test('create existing account', async() => {
Expand All @@ -112,7 +116,6 @@ describe('errors', () => {
});

describe('with deploy contract', () => {
let oldLog;
let logs;
let contractId = testUtils.generateUniqueString('test_contract');
let contract;
Expand All @@ -125,18 +128,20 @@ describe('with deploy contract', () => {
viewMethods: ['hello', 'getValue', 'returnHiWithLogs'],
changeMethods: ['setValue', 'generateLogs', 'triggerAssert', 'testSetRemove', 'crossContract']
});
});

beforeEach(async () => {
oldLog = console.log;
logs = [];
console.log = function () {
logs.push(Array.from(arguments).join(' '));
const custom = {
log: (...args) => {
logs.push(args.join(' '));
},
warn: () => {},
error: () => {},
};

Logger.overrideLogger(custom);
});

afterEach(async () => {
console.log = oldLog;
beforeEach(async () => {
logs = [];
});

test('cross-contact assertion and panic', async () => {
Expand Down
24 changes: 19 additions & 5 deletions packages/near-api-js/src/connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,21 @@
* })
* }
* ```
* @example disable library logs
* ```js
* async function initNear() {
* const near = await connect({
* networkId: 'testnet',
* nodeUrl: 'https://rpc.testnet.near.org',
* logger: false
* })
* }
* @module connect
*/
import { readKeyFile } from './key_stores/unencrypted_file_system_keystore';
import { InMemoryKeyStore, MergeKeyStore } from './key_stores';
import { Near, NearConfig } from './near';
import { logWarning } from './utils';
import { Logger } from '@near-js/utils';

export interface ConnectConfig extends NearConfig {
/**
Expand All @@ -38,6 +47,13 @@ export interface ConnectConfig extends NearConfig {
* Initialize connection to Near network.
*/
export async function connect(config: ConnectConfig): Promise<Near> {
if (config.logger === false) {
// disables logging
Logger.overrideLogger(undefined);
} else if (config.logger !== undefined && config.logger !== null) {
Logger.overrideLogger(config.logger);
}

// Try to find extra key in `KeyPath` if provided.
if (config.keyPath && (config.keyStore || config.deps?.keyStore)) {
try {
Expand All @@ -54,12 +70,10 @@ export async function connect(config: ConnectConfig): Promise<Near> {
keyPathStore,
config.keyStore || config.deps?.keyStore
], { writeKeyStoreIndex: 1 });
if (!(typeof process === 'object' && process.env['NEAR_NO_LOGS'])) {
console.log(`Loaded master account ${accountKeyFile[0]} key from ${config.keyPath} with public key = ${keyPair.getPublicKey()}`);
}
Logger.log(`Loaded master account ${accountKeyFile[0]} key from ${config.keyPath} with public key = ${keyPair.getPublicKey()}`);
}
} catch (error) {
logWarning(`Failed to load master account key from ${config.keyPath}: ${error}`);
Logger.warn(`Failed to load master account key from ${config.keyPath}: ${error}`);
}
}
return new Near(config);
Expand Down
2 changes: 2 additions & 0 deletions packages/near-api-js/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import * as rpc_errors from './rpc_errors';

import { PublicKey, KeyPair, KeyPairEd25519 } from './key_pair';
import { logWarning } from './errors';
import { Logger } from './logger';

export {
key_pair,
Expand All @@ -20,4 +21,5 @@ export {
KeyPairEd25519,
rpc_errors,
logWarning,
Logger
};
1 change: 1 addition & 0 deletions packages/near-api-js/src/utils/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Logger } from '@near-js/utils';
9 changes: 4 additions & 5 deletions packages/providers/src/fetch_json.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { TypedError } from '@near-js/types';
import { Logger } from '@near-js/utils';
import createError from 'http-errors';

import { exponentialBackoff } from './exponential-backoff';
Expand All @@ -16,8 +17,6 @@ export interface ConnectionInfo {
headers?: { [key: string]: string | number };
}

const logWarning = (...args) => !(typeof process === 'object' && process.env['NEAR_NO_LOGS']) && console.warn(...args);

export async function fetchJson(connectionInfoOrUrl: string | ConnectionInfo, json?: string): Promise<any> {
let connectionInfo: ConnectionInfo = { url: null };
if (typeof (connectionInfoOrUrl) === 'string') {
Expand All @@ -36,18 +35,18 @@ export async function fetchJson(connectionInfoOrUrl: string | ConnectionInfo, js
});
if (!response.ok) {
if (response.status === 503) {
logWarning(`Retrying HTTP request for ${connectionInfo.url} as it's not available now`);
Logger.warn(`Retrying HTTP request for ${connectionInfo.url} as it's not available now`);
return null;
} else if (response.status === 408) {
logWarning(`Retrying HTTP request for ${connectionInfo.url} as the previous connection was unused for some time`);
Logger.warn(`Retrying HTTP request for ${connectionInfo.url} as the previous connection was unused for some time`);
return null;
}
throw createError(response.status, await response.text());
}
return response;
} catch (error) {
if (error.toString().includes('FetchError') || error.toString().includes('Failed to fetch')) {
logWarning(`Retrying HTTP request for ${connectionInfo.url} because of error: ${error}`);
Logger.warn(`Retrying HTTP request for ${connectionInfo.url} because of error: ${error}`);
return null;
}
throw error;
Expand Down
5 changes: 2 additions & 3 deletions packages/providers/src/json-rpc-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import {
baseEncode,
getErrorTypeFromErrorMessage,
Logger,
parseRpcError,
} from '@near-js/utils';
import {
Expand Down Expand Up @@ -372,9 +373,7 @@ export class JsonRpcProvider extends Provider {
return response;
} catch (error) {
if (error.type === 'TimeoutError') {
if (!(typeof process === 'object' && process.env['NEAR_NO_LOGS'])) {
console.warn(`Retrying request to ${method} as it has timed out`, params);
}
Logger.warn(`Retrying request to ${method} as it has timed out`, params);
return null;
}

Expand Down
8 changes: 5 additions & 3 deletions packages/utils/src/errors/errors.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Logger } from '../logger';

/** @deprecated */
export function logWarning(...args: any[]): void {
if (!(typeof process === 'object' && process.env['NEAR_NO_LOGS'])){
console.warn(...args);
}
const [message, ...optinalParams] = args;
Logger.warn(message, ...optinalParams);
}
1 change: 1 addition & 0 deletions packages/utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export * from './format';
export * from './logging';
export * from './provider';
export * from './validators';
export * from './logger';
Loading

0 comments on commit ecf29e2

Please sign in to comment.