diff --git a/apps/teams-test-app/src/components/LoggerAPIs.tsx b/apps/teams-test-app/src/components/LoggerAPIs.tsx new file mode 100644 index 0000000000..7bfad27250 --- /dev/null +++ b/apps/teams-test-app/src/components/LoggerAPIs.tsx @@ -0,0 +1,33 @@ +import { logger } from '@microsoft/teams-js'; +import React, { ReactElement } from 'react'; + +import { ApiWithoutInput } from './utils'; +import { ModuleWrapper } from './utils/ModuleWrapper'; + +const TurnOnConsoleLog = (): React.ReactElement => + ApiWithoutInput({ + name: 'turnOnConsoleLog', + title: 'Turn On Console Log', + onClick: async () => { + logger.turnOnConsoleLog(); + return 'true'; + }, + }); + +const TurnOffConsoleLog = (): React.ReactElement => + ApiWithoutInput({ + name: 'turnOffConsoleLog', + title: 'Turn Off Console Log', + onClick: async () => { + logger.turnOffConsoleLog(); + return 'true'; + }, + }); +const LoggerAPIs = (): ReactElement => ( + + + + +); + +export default LoggerAPIs; diff --git a/apps/teams-test-app/src/pages/TestApp.tsx b/apps/teams-test-app/src/pages/TestApp.tsx index b7f4355b73..37b41979a4 100644 --- a/apps/teams-test-app/src/pages/TestApp.tsx +++ b/apps/teams-test-app/src/pages/TestApp.tsx @@ -22,6 +22,7 @@ import GeoLocationAPIs from '../components/GeoLocationAPIs'; import HostEntityTabAPIs from '../components/HostEntityTabAPIs'; import Links from '../components/Links'; import LocationAPIs from '../components/LocationAPIs'; +import LoggerAPIs from '../components/LoggerAPIs'; import LogAPIs from '../components/LogsAPIs'; import MailAPIs from '../components/MailAPIs'; import MarketplaceAPIs from '../components/MarketplaceAPIs'; @@ -126,6 +127,7 @@ export const TestApp: React.FC = () => { + diff --git a/change/@microsoft-teams-js-65d123d3-bbbc-4e7e-abc8-7396d65b2950.json b/change/@microsoft-teams-js-65d123d3-bbbc-4e7e-abc8-7396d65b2950.json new file mode 100644 index 0000000000..2b7e799e25 --- /dev/null +++ b/change/@microsoft-teams-js-65d123d3-bbbc-4e7e-abc8-7396d65b2950.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "Added a capability for better logging discoverability", + "packageName": "@microsoft/teams-js", + "email": "kangxuanye@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/teams-js/src/internal/globalVars.ts b/packages/teams-js/src/internal/globalVars.ts index da630650e6..034418822a 100644 --- a/packages/teams-js/src/internal/globalVars.ts +++ b/packages/teams-js/src/internal/globalVars.ts @@ -9,4 +9,5 @@ export class GlobalVars { public static hostClientType: string | undefined = undefined; public static clientSupportedSDKVersion: string; public static printCapabilityEnabled = false; + public static turnOnConsoleLog = false; } diff --git a/packages/teams-js/src/internal/telemetry.ts b/packages/teams-js/src/internal/telemetry.ts index 604fbc3ee5..1251d3e1a5 100644 --- a/packages/teams-js/src/internal/telemetry.ts +++ b/packages/teams-js/src/internal/telemetry.ts @@ -1,5 +1,6 @@ import { debug as registerLogger, Debugger } from 'debug'; +import { GlobalVars } from './globalVars'; import { UUID } from './uuidObject'; // Each teamsjs instance gets a unique identifier that will be prepended to every log statement @@ -12,7 +13,72 @@ registerLogger.formatArgs = function (args) { originalFormatArgsFunction.call(this, args); }; -const topLevelLogger = registerLogger('teamsJs'); +/** + * This function creates a customized debugger, or debugger wrapper, which wraps the debugger from `debug` npm library. + * The customized debugger inherits `extend` function, which is the most important one for debugging, and provides the + * capability to set all of attributes as `internalDebugger` does for itself. The wrapper also provides an anonymous function + * as `internalDebugger` does but this function will output verbose logs to console directly under certain circumstance. + * In the other scenarios, the debugger wrapper will behave as `internalDebugger`. + * @param namespace namespace of debugger + * @returns a debugger wrapper containning debugger created from `debug` npm library + */ +// eslint-disable-next-line @typescript-eslint/no-unused-vars +const createDebuggerFunction = (namespace: string): Debugger => { + const internalDebugger: Debugger = registerLogger(namespace); + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const func = function (formatter: any, ...args: any[]): void { + if (GlobalVars.turnOnConsoleLog && localStorage.getItem('debug') != 'teamsJs.*') { + console.timeLog( + `%c${internalDebugger.namespace}%c: ${formatter}`, + `color: ${internalDebugger.color};`, + '', + [...args], + internalDebugger.color, + ); + } else { + internalDebugger(formatter, args); + } + } as Debugger; + + Object.assign(func, { + get color() { + return internalDebugger.color; + }, + set color(value: string) { + internalDebugger.color = value; + }, + get diff() { + return internalDebugger.diff; + }, + set diff(value: number) { + internalDebugger.diff = value; + }, + get enabled(): boolean { + return internalDebugger.enabled; + }, + set enabled(enabled: boolean) { + internalDebugger.enabled = enabled; + }, + get namespace(): string { + return internalDebugger.namespace; + }, + set namespace(namespace: string) { + internalDebugger.namespace = namespace; + }, + extend(namespace: string, delimiter?: string): Debugger { + return createDebuggerFunction(internalDebugger.extend(namespace, delimiter).namespace); + }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + log(...args: any[]) { + internalDebugger.log(args); + }, + }); + + return func; +}; + +const topLevelLogger: Debugger = createDebuggerFunction('teamsJs'); /** * @internal diff --git a/packages/teams-js/src/public/index.ts b/packages/teams-js/src/public/index.ts index b8ee1fcb30..7faa7d8a71 100644 --- a/packages/teams-js/src/public/index.ts +++ b/packages/teams-js/src/public/index.ts @@ -120,3 +120,4 @@ export { settings } from './settings'; export { tasks } from './tasks'; export { liveShare, LiveShareHost } from './liveShareHost'; export { marketplace } from './marketplace'; +export { logger } from './logger'; diff --git a/packages/teams-js/src/public/logger.ts b/packages/teams-js/src/public/logger.ts new file mode 100644 index 0000000000..e4b86361d4 --- /dev/null +++ b/packages/teams-js/src/public/logger.ts @@ -0,0 +1,17 @@ +import { GlobalVars } from '../internal/globalVars'; + +export namespace logger { + /** + * Turn on client logging to display all of debug logs on browser console + */ + export function turnOnConsoleLog(): void { + GlobalVars.turnOnConsoleLog = true; + } + + /** + * Turn off client logging so that all of debug logs will not be displayed on browser console + */ + export function turnOffConsoleLog(): void { + GlobalVars.turnOnConsoleLog = false; + } +}