diff --git a/.changeset/smart-worms-remember.md b/.changeset/smart-worms-remember.md new file mode 100644 index 0000000000..185bbf0bcd --- /dev/null +++ b/.changeset/smart-worms-remember.md @@ -0,0 +1,5 @@ +--- +"@vue-storefront/logger": minor +--- + +use appropriate verbosity levels in the browser environment diff --git a/packages/logger/__tests__/unit/consolaStructuredLogger.spec.ts b/packages/logger/__tests__/unit/consolaStructuredLogger.spec.ts index 328ceaadd5..38fab6ab54 100644 --- a/packages/logger/__tests__/unit/consolaStructuredLogger.spec.ts +++ b/packages/logger/__tests__/unit/consolaStructuredLogger.spec.ts @@ -39,4 +39,40 @@ describe("createConsolaStructuredLogger", () => { const debugSpy = jest.spyOn(logger, "debug").mockImplementation(() => {}); expect(debugSpy).not.toHaveBeenCalled(); }); + + it("calls console.warn once when logger.warning is invoked", () => { + const logger = createConsolaStructuredLogger(mockStructuredLog); + const warnSpy = jest.spyOn(console, "warn").mockImplementation(() => {}); + + logger.warning(logData, metadata); + + expect(warnSpy).toHaveBeenCalledTimes(1); + + warnSpy.mockRestore(); + }); + + it("calls console.error once for each error-level logging method", () => { + const logger = createConsolaStructuredLogger(mockStructuredLog); + const errorSpy = jest.spyOn(console, "error").mockImplementation(() => {}); + + logger.error(logData, metadata); + logger.critical(logData, metadata); + logger.alert(logData, metadata); + logger.emergency(logData, metadata); + + expect(errorSpy).toHaveBeenCalledTimes(4); + + errorSpy.mockRestore(); + }); + + it("calls console.info once when info-level is invoked", () => { + const logger = createConsolaStructuredLogger(mockStructuredLog); + const infoSpy = jest.spyOn(console, "info").mockImplementation(() => {}); + + logger.info(logData, metadata); + + expect(infoSpy).toHaveBeenCalledTimes(1); + + infoSpy.mockRestore(); + }); }); diff --git a/packages/logger/__tests__/unit/reporter/consola/jsonReporter.spec.ts b/packages/logger/__tests__/unit/reporter/consola/jsonReporter.spec.ts new file mode 100644 index 0000000000..1b205e16e5 --- /dev/null +++ b/packages/logger/__tests__/unit/reporter/consola/jsonReporter.spec.ts @@ -0,0 +1,96 @@ +import { jsonReporter } from "../../../../src/reporters/consola/jsonReporter"; + +describe("jsonReporter", () => { + let consoleSpy: jest.SpyInstance; + let warnSpy: jest.SpyInstance; + + beforeEach(() => { + consoleSpy = jest.spyOn(console, "log").mockImplementation(() => {}); + warnSpy = jest.spyOn(console, "warn").mockImplementation(() => {}); + }); + + afterEach(() => { + consoleSpy.mockRestore(); + }); + + it("should log structuredLog directly in development environment", () => { + process.env.NODE_ENV = "development"; + const logObject: any = { + type: "log", + args: [{ structuredLog: { message: "test message" } }], + }; + + jsonReporter(logObject); + + expect(consoleSpy).toHaveBeenCalledWith({ message: "test message" }); + }); + + it("should log structuredLog directly in browser environment", () => { + delete process.env.NODE_ENV; + (global as any).window = {}; + + const logObject: any = { + type: "log", + args: [{ structuredLog: { message: "test message" } }], + }; + + jsonReporter(logObject); + + expect(consoleSpy).toHaveBeenCalledWith({ message: "test message" }); + + delete (global as any).window; + }); + + it("should log structuredLog as JSON in production environment", () => { + process.env.NODE_ENV = "production"; + const logObject: any = { + type: "log", + args: [{ structuredLog: { message: "test message" } }], + }; + + jsonReporter(logObject); + + expect(consoleSpy).toHaveBeenCalledWith( + JSON.stringify({ message: "test message" }) + ); + }); + + it("should use default log type if log type is not defined", () => { + const logObject: any = { + type: undefined, + args: [{ structuredLog: { message: "test message" } }], + }; + + jsonReporter(logObject); + + expect(consoleSpy).toHaveBeenCalledWith( + JSON.stringify({ message: "test message" }) + ); + }); + + it("should use default log type if console does not support the log type", () => { + const logObject: any = { + type: "unsupportedType", + args: [{ structuredLog: { message: "test message" } }], + }; + + jsonReporter(logObject); + + expect(consoleSpy).toHaveBeenCalledWith( + JSON.stringify({ message: "test message" }) + ); + }); + + it("should use warn log type if log type is warn", () => { + const logObject: any = { + type: "warn", + args: [{ structuredLog: { message: "test message" } }], + }; + + jsonReporter(logObject); + + expect(warnSpy).toHaveBeenCalledWith( + JSON.stringify({ message: "test message" }) + ); + }); +}); diff --git a/packages/logger/src/ConsolaStructuredLogger.ts b/packages/logger/src/ConsolaStructuredLogger.ts index 3af5ef2625..5baa6d7785 100644 --- a/packages/logger/src/ConsolaStructuredLogger.ts +++ b/packages/logger/src/ConsolaStructuredLogger.ts @@ -9,6 +9,7 @@ import type { } from "./interfaces/LoggerInterface"; import type { LoggerOptions } from "./interfaces/LoggerOptions"; import type { StructuredLog } from "./interfaces/StructuredLog"; +import { jsonReporter } from "./reporters/consola/jsonReporter"; // We do not want to load the .env in the browser and in the edge runtime if (typeof window === "undefined" && process.env.NEXT_RUNTIME !== "edge") { @@ -39,16 +40,7 @@ const createConsolaStructuredLogger = ( const buildJsonReporter = () => { return { - log: (logObject) => { - if ( - process.env.NODE_ENV === "development" || - typeof window !== "undefined" - ) { - console.log(logObject.args[0].structuredLog); - } else { - console.log(JSON.stringify(logObject.args[0].structuredLog)); - } - }, + log: jsonReporter, }; }; diff --git a/packages/logger/src/reporters/consola/jsonReporter.ts b/packages/logger/src/reporters/consola/jsonReporter.ts new file mode 100644 index 0000000000..9974be53bd --- /dev/null +++ b/packages/logger/src/reporters/consola/jsonReporter.ts @@ -0,0 +1,13 @@ +import type { LogObject } from "consola"; + +export const jsonReporter = (logObject: LogObject) => { + const defLogType = "log"; + const logType = logObject?.type ?? defLogType; + const logFn = console[logType] ?? console[defLogType]; + + if (process.env.NODE_ENV === "development" || typeof window !== "undefined") { + logFn(logObject.args[0].structuredLog); + } else { + logFn(JSON.stringify(logObject.args[0].structuredLog)); + } +};