From df0fc6514b7cf9a0147b365b568d94d292548de8 Mon Sep 17 00:00:00 2001 From: Saurabhkmr98 Date: Thu, 12 Dec 2024 20:45:57 +0530 Subject: [PATCH] resolve pr reviews and add client logger with readme update --- packages/logger/README.md | 12 +++- packages/logger/index.d.ts | 19 ++++++ packages/logger/package.json | 12 +++- packages/logger/src/client-logger.ts | 86 ++++++++++++++-------------- packages/logger/src/index.ts | 5 +- packages/logger/src/logger.ts | 20 ++----- packages/logger/src/server-logger.ts | 23 ++++---- packages/logger/tsconfig.json | 6 +- 8 files changed, 111 insertions(+), 72 deletions(-) create mode 100644 packages/logger/index.d.ts diff --git a/packages/logger/README.md b/packages/logger/README.md index e2b9c1a1c4a..1cc88c3df77 100644 --- a/packages/logger/README.md +++ b/packages/logger/README.md @@ -28,7 +28,17 @@ import PlaneLogger from "@plane/logger"; Use this for general application logs. ```typescript -const logger: Logger = PlaneLogger.getLogger("info", "log-file-prefix") +const loggerOptions: ILoggerOptions = { logLevel:"info", logFilePrefix: "log-file-prefix" } + +import ClientLogger from "@plane/logger/client" +const logger = ClientLogger.getLogger(loggerOptions); +logger.log("test logs on web") + + +import ServerLogger from "@plane/logger/server" +const logger = ServerLogger.getLogger(loggerOptions); +logger.log("test logs on server") + logger.info("This is an info log"); logger.warn("This is a warning"); logger.error("This is an error"); diff --git a/packages/logger/index.d.ts b/packages/logger/index.d.ts new file mode 100644 index 00000000000..869af35186e --- /dev/null +++ b/packages/logger/index.d.ts @@ -0,0 +1,19 @@ +export interface ILoggerOptions { + logLevel?: string, + logFilePrefix?: string +} +export interface ILogger { + private instance?: any; + private logger?: WinstonLogger; // The Winston logger instance + logLevel?: string; // The current logging level + logFilePrefix?: string; + // Method to get the logger instance + getLogger(loggerOptions: ILoggerOptions): WinstonLogger; +} + +export interface IClientLogMethods { + error: (message: string, ...metadata: any[]) => void; + warn: (message: string, ...metadata: any[]) => void; + info: (message: string, ...metadata: any[]) => void; + debug: (message: string, ...metadata: any[]) => void; +} \ No newline at end of file diff --git a/packages/logger/package.json b/packages/logger/package.json index 163abb8705f..44a789234e3 100644 --- a/packages/logger/package.json +++ b/packages/logger/package.json @@ -3,13 +3,23 @@ "version": "1.0.0", "description": "Logger shared across multiple apps internally", "private": true, - "main": "./dist/index.js", + "main": "./dist/server-logger.js", + "browser": "./dist/client-logger.js", "type":"module", "module": "./dist/index.mjs", "types": "./dist/index.d.ts", "files": [ "dist/**" ], + "exports": { + ".": { + "require": "./dist/server-logger.js", + "import": "./dist/index.js", + "browser": "./dist/client-logger.js" + }, + "./client": "./dist/client-logger.js", + "./server": "./dist/server-logger.js" + }, "scripts": { "build": "tsup ./src/index.ts --format esm,cjs --dts --external react --minify", "lint": "eslint src --ext .ts,.tsx", diff --git a/packages/logger/src/client-logger.ts b/packages/logger/src/client-logger.ts index b117a8f28ed..f06a894be4d 100644 --- a/packages/logger/src/client-logger.ts +++ b/packages/logger/src/client-logger.ts @@ -1,53 +1,55 @@ -import { createLogger, format, transports, Logger as WinstonLogger } from "winston"; - +import { IClientLogMethods, ILoggerOptions } from "index"; export default class ClientLogger { - private static instance: ClientLogger; - private logger: WinstonLogger; private logLevel: string; - - private constructor(logLevel: string = "info") { - - this.logLevel = logLevel; - - this.logger = createLogger({ - level: this.logLevel, - format: format.combine( - format.colorize(), - format.timestamp({ - format: "DD/MMM/YYYY HH:mm:ss", - }), - format.printf(({ timestamp, level, message, ...metadata }) => { - const msg = `[${timestamp}] "${level}" ${message}`; - const metaString = Object.keys(metadata).length ? ` ${JSON.stringify(metadata)}` : ""; - return msg + metaString; - }) - ), - transports: [ - new transports.Console({ handleExceptions: true }) - ], - }); - - this.logger.transports.forEach((transport) => { - transport.on("error", (err) => { - // Handle the error, log it, or notify as necessary - console.error(`Logging transport error: Console`, err); - }); - }); - + private logLevels: string[]; + logMethods: IClientLogMethods; + static instance: any; + + constructor(loggerOptions: ILoggerOptions = { logLevel: "info", logFilePrefix: "log" }) { + this.logLevel = loggerOptions.logLevel || 'info'; + this.logMethods = { + error: this.logWithLevel.bind(this, "error"), + warn: this.logWithLevel.bind(this, "warn"), + info: this.logWithLevel.bind(this, "info"), + debug: this.logWithLevel.bind(this, "debug"), + }; + this.logLevels = ["error", "warn", "info", "debug"]; } - private static getInstance(logLevel?: string) { + static getInstance(loggerOptions?: ILoggerOptions) { if (!ClientLogger.instance) { - ClientLogger.instance = new ClientLogger(logLevel); - } + ClientLogger.instance = new ClientLogger(loggerOptions); + } return ClientLogger.instance; } - public static getLogger(logLevel?: string) { - const instance = ClientLogger.getInstance(logLevel); - return instance.logger + public static getLogger(loggerOptions?: ILoggerOptions): IClientLogMethods { + const instance = this.getInstance(loggerOptions); + return instance.logMethods; } -} - + logWithLevel(level: string, message: string, ...metadata: any[]) { + if (this.logLevels.indexOf(level) <= this.logLevels.indexOf(this.logLevel)) { + const timestamp = new Date().toISOString(); + const formattedMessage = `[${timestamp}] "${level.toUpperCase()}" ${message}`; + const metaString = metadata.length ? ` ${JSON.stringify(metadata)}` : ""; + + // Override to console.log equivalent + switch (level) { + case "error": + console.error(formattedMessage + metaString); + break; + case "warn": + console.warn(formattedMessage + metaString); + break; + case "info": + console.info(formattedMessage + metaString); + break; + case "debug": + console.log(formattedMessage + metaString); + break; + } + } + } +} \ No newline at end of file diff --git a/packages/logger/src/index.ts b/packages/logger/src/index.ts index 630bc8c85d4..358965ab36e 100644 --- a/packages/logger/src/index.ts +++ b/packages/logger/src/index.ts @@ -1,2 +1,5 @@ // src/index.ts -export { default } from './server-logger'; +// export { default as Logger} from './server-logger' +// export { default as ClientLogger } from './client-logger' + +export {default} from './logger'; diff --git a/packages/logger/src/logger.ts b/packages/logger/src/logger.ts index e9e320aa2a9..ca288738266 100644 --- a/packages/logger/src/logger.ts +++ b/packages/logger/src/logger.ts @@ -1,24 +1,16 @@ -import { Logger as WinstonLogger } from 'winston'; - -export interface ILogger { - logger: WinstonLogger; // The Winston logger instance - logLevel?: string; // The current logging level - logFilePrefix?: string; - - // Method to get the logger instance - getLogger(logLevel?: string, logFilePrefix?: string): WinstonLogger; -} - +import { ILogger } from 'index'; let Logger: ILogger; if (typeof window !== "undefined") { // Client-side logic - console.log("inside client logger import") - Logger = require('./client-logger').default; + console.log("inside client logger import"); + const { default: ClientLogger } = require('./client-logger'); + Logger = ClientLogger; } else { // Server-side logic - Logger = require('./server-logger').default; + const { default: ServerLogger } = require('./server-logger'); + Logger = ServerLogger; } export default Logger; diff --git a/packages/logger/src/server-logger.ts b/packages/logger/src/server-logger.ts index ea1ab81e159..c0581cfa06b 100644 --- a/packages/logger/src/server-logger.ts +++ b/packages/logger/src/server-logger.ts @@ -1,8 +1,9 @@ -import { createLogger, format, transports, Logger as WinstonLogger } from "winston"; +import { createLogger, format, LoggerOptions, transports, Logger as WinstonLogger } from "winston"; import winstonRotate from "winston-daily-rotate-file"; import { fileURLToPath } from 'url'; import { dirname } from 'path'; import fs from 'fs'; +import { ILoggerOptions } from "index"; // Get current directory const __filename = fileURLToPath(import.meta.url); @@ -18,14 +19,14 @@ if (!fs.existsSync(logDirectory)) { export default class Logger { - private static instance: Logger; + static instance?: Logger; private logger: WinstonLogger; - private logLevel: string; - private logFilePrefix: string; + private logLevel?: string; + private logFilePrefix?: string; - private constructor(logLevel: string = "info", logFilePrefix: string = "plane-log") { - this.logLevel = logLevel; - this.logFilePrefix = logFilePrefix; + private constructor(loggerOptions: ILoggerOptions = { logLevel: "info", logFilePrefix: "plane-log" }) { + this.logLevel = loggerOptions.logLevel; + this.logFilePrefix = loggerOptions.logFilePrefix; this.logger = createLogger({ level: this.logLevel, @@ -71,15 +72,15 @@ export default class Logger { } } - private static getInstance(logLevel?: string, logFilePrefix?: string) { + private static getInstance(loggerOptions?: ILoggerOptions) { if (!Logger.instance) { - Logger.instance = new Logger(logLevel, logFilePrefix); + Logger.instance = new Logger(loggerOptions); } return Logger.instance; } - public static getLogger(logLevel?: string, logFilePrefix?: string) { - const instance = Logger.getInstance(logLevel, logFilePrefix); + public static getLogger(loggerOptions?: ILoggerOptions) { + const instance = Logger.getInstance(loggerOptions); return instance.logger } diff --git a/packages/logger/tsconfig.json b/packages/logger/tsconfig.json index 3b1aa757d30..2ba1c9799b1 100644 --- a/packages/logger/tsconfig.json +++ b/packages/logger/tsconfig.json @@ -1,8 +1,10 @@ { "extends": "@plane/typescript-config/base.json", "compilerOptions": { - "module": "ESNext", - "moduleResolution": "bundler", + "module": "ESNext", + "target": "ESNext", + "moduleResolution": "node", + "esModuleInterop": true, "outDir": "./dist", "rootDir": "./src", "baseUrl": ".",