Skip to content

Commit

Permalink
Introduced logger to have better control of logging
Browse files Browse the repository at this point in the history
  • Loading branch information
thehenrytsai committed Oct 4, 2024
1 parent 7cabd6c commit 959e342
Show file tree
Hide file tree
Showing 6 changed files with 178 additions and 15 deletions.
4 changes: 2 additions & 2 deletions packages/agent/src/connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
} from './oidc.js';
import { pollWithTtl } from './utils.js';

import { Convert } from '@web5/common';
import { Convert, logger } from '@web5/common';
import { CryptoUtils } from '@web5/crypto';
import { DidJwk } from '@web5/dids';
import { DwnInterfaceName, DwnMethodName } from '@tbd54566975/dwn-sdk-js';
Expand Down Expand Up @@ -94,7 +94,7 @@ async function initClient({

// a deeplink to a web5 compatible wallet. if the wallet scans this link it should receive
// a route to its web5 connect provider flow and the params of where to fetch the auth request.
console.log('Wallet URI:', walletUri);
logger.log(`Wallet URI: ${walletUri}`);
const generatedWalletUri = new URL(walletUri);
generatedWalletUri.searchParams.set('request_uri', parData.request_uri);
generatedWalletUri.searchParams.set(
Expand Down
24 changes: 12 additions & 12 deletions packages/agent/src/oidc.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Convert, RequireOnly } from '@web5/common';
import { Convert, logger, RequireOnly } from '@web5/common';
import {
Ed25519,
EdDsaAlgorithm,
Expand Down Expand Up @@ -631,7 +631,7 @@ async function createPermissionGrants(
const permissionsApi = new AgentPermissionsApi({ agent });

// TODO: cleanup all grants if one fails by deleting them from the DWN: https://github.com/TBD54566975/web5-js/issues/849
console.log(`Creating permission grants for ${scopes.length} scopes given...`);
logger.log(`Creating permission grants for ${scopes.length} scopes given...`);
const permissionGrants = await Promise.all(
scopes.map((scope) => {
// check if the scope is a records permission scope, or a protocol configure scope, if so it should use a delegated permission.
Expand All @@ -647,7 +647,7 @@ async function createPermissionGrants(
})
);

console.log(`Sending ${permissionGrants.length} permission grants to remote DWN...`);
logger.log(`Sending ${permissionGrants.length} permission grants to remote DWN...`);
const messagePromises = permissionGrants.map(async (grant) => {
// Quirk: we have to pull out encodedData out of the message the schema validator doesn't want it there
const { encodedData, ...rawMessage } = grant.message;
Expand All @@ -663,8 +663,8 @@ async function createPermissionGrants(

// check if the message was sent successfully, if the remote returns 409 the message may have come through already via sync
if (reply.status.code !== 202 && reply.status.code !== 409) {
console.log('Error sending RecordsWrite:', reply.status.detail);
console.log('RecordsWrite message:', rawMessage);
logger.error(`Error sending RecordsWrite: ${reply.status.detail}`);
logger.error(`RecordsWrite message: ${rawMessage}`);

Check warning on line 667 in packages/agent/src/oidc.ts

View check run for this annotation

Codecov / codecov/patch

packages/agent/src/oidc.ts#L666-L667

Added lines #L666 - L667 were not covered by tests
throw new Error(
`Could not send the message. Error details: ${reply.status.detail}`
);
Expand All @@ -677,7 +677,7 @@ async function createPermissionGrants(
const messages = await Promise.all(messagePromises);
return messages;
} catch (error) {
console.error('Error during batch-send of permission grants:', error instanceof Error ? error.message : error);
logger.error(`Error during batch-send of permission grants: ${error}`);
throw error;
}

Check warning on line 682 in packages/agent/src/oidc.ts

View check run for this annotation

Codecov / codecov/patch

packages/agent/src/oidc.ts#L680-L682

Added lines #L680 - L682 were not covered by tests
}
Expand All @@ -704,7 +704,7 @@ async function prepareProtocol(
`Could not fetch protocol: ${queryMessage.reply.status.detail}`
);
} else if (queryMessage.reply.entries === undefined || queryMessage.reply.entries.length === 0) {
console.log('Protocol does not exist, creating:', protocolDefinition.protocol);
logger.log(`Protocol does not exist, creating: ${protocolDefinition.protocol}`);

// send the protocol definition to the remote DWN first, if it passes we can process it locally
const { reply: sendReply, message: configureMessage } = await agent.sendDwnRequest({
Expand All @@ -728,7 +728,7 @@ async function prepareProtocol(
});

} else {
console.log('Protocol already exists:', protocolDefinition.protocol);
logger.log(`Protocol already exists: ${protocolDefinition.protocol}`);

// the protocol already exists, let's make sure it exists on the remote DWN as the requesting app will need it
const configureMessage = queryMessage.reply.entries![0];
Expand Down Expand Up @@ -789,7 +789,7 @@ async function submitAuthResponse(

const delegateGrants = (await Promise.all(delegateGrantPromises)).flat();

console.log('Generating auth response object...');
logger.log('Generating auth response object...');
const responseObject = await Oidc.createResponseObject({
//* the IDP's did that was selected to be connected
iss : selectedDid,
Expand All @@ -804,7 +804,7 @@ async function submitAuthResponse(
});

// Sign the Response Object using the ephemeral DID's signing key.
console.log('Signing auth response object...');
logger.log('Signing auth response object...');
const responseObjectJwt = await Oidc.signJwt({
did : delegateBearerDid,
data : responseObject,
Expand All @@ -816,7 +816,7 @@ async function submitAuthResponse(
clientDid?.didDocument!
);

console.log('Encrypting auth response object...');
logger.log('Encrypting auth response object...');
const encryptedResponse = Oidc.encryptAuthResponse({
jwt : responseObjectJwt!,
encryptionKey : sharedKey,
Expand All @@ -829,7 +829,7 @@ async function submitAuthResponse(
state : authRequest.state,
}).toString();

console.log(`Sending auth response object to Web5 Connect server: ${authRequest.redirect_uri}`);
logger.log(`Sending auth response object to Web5 Connect server: ${authRequest.redirect_uri}`);
await fetch(authRequest.redirect_uri, {
body : formEncodedRequest,
method : 'POST',
Expand Down
3 changes: 2 additions & 1 deletion packages/common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"@isaacs/ttlcache": "1.4.1",
"level": "8.0.1",
"multiformats": "13.1.0",
"pino": "9.4.0",
"readable-stream": "4.5.2"
},
"devDependencies": {
Expand Down Expand Up @@ -99,4 +100,4 @@
"rimraf": "5.0.7",
"typescript": "5.5.3"
}
}
}
1 change: 1 addition & 0 deletions packages/common/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export type * from './types.js';

export * from './cache.js';
export * from './convert.js';
export * from './logger.js';
export * from './multicodec.js';
export * from './object.js';
export * from './stores.js';
Expand Down
73 changes: 73 additions & 0 deletions packages/common/src/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { pino, LoggerOptions } from 'pino';

export enum Web5LogLevel {
Debug = 'debug',
Silent = 'silent',
}

/**
* Web5 logger interface.
*/
export interface Web5LoggerInterface {

/**
* Sets the log verbose level.
*/
setLogLevel(logLevel: Web5LogLevel): void;

/**
* Same as `info()`.
* Logs an informational message.
*/
log (message: string): void;

/**
* Logs an informational message.
*/
info(message: string): void;

/**
* Logs an error message.
*/
error(message: string): void;
}

/**
* A Web5 logger implementation.
*/
class Web5Logger implements Web5LoggerInterface {
private pinoLogger;

public constructor() {
const loggerOptions: LoggerOptions = {
level: 'silent', // Default to 'silent' log level
};

this.pinoLogger = pino(loggerOptions);
}

setLogLevel(logLevel: Web5LogLevel): void {
this.pinoLogger.level = logLevel;
}

public log(message: string): void {
this.info(message);
}

public info(message: string): void {
this.pinoLogger.info(message);
}

public error(message: string): void {
this.pinoLogger.error(message);
}
}

// Export a singleton logger instance
export const logger = new Web5Logger();

// Attach logger to the global window object in browser environment for easy access to the logger instance.
// e.g. can call `web5logger.setLogLevel('debug');` directly in browser console.
if (typeof window !== 'undefined') {
(window as any).web5logger = logger; // Makes `web5Logger` accessible globally in browser
}

Check warning on line 73 in packages/common/src/logger.ts

View check run for this annotation

Codecov / codecov/patch

packages/common/src/logger.ts#L2-L73

Added lines #L2 - L73 were not covered by tests
Loading

0 comments on commit 959e342

Please sign in to comment.