diff --git a/.changeset/four-toes-lay.md b/.changeset/four-toes-lay.md new file mode 100644 index 000000000000..b160e0e7d1af --- /dev/null +++ b/.changeset/four-toes-lay.md @@ -0,0 +1,9 @@ +--- +"wrangler": patch +--- + +fix: make `WRANGLER_LOG` case-insensitive, warn on unexpected values, and fallback to `log` if invalid + +Previously, levels set via the `WRANGLER_LOG` environment-variable were case-sensitive. +If an unexpected level was set, Wrangler would fallback to `none`, hiding all logs. +The fallback has now been switched to `log`, and lenient case-insensitive matching is used when setting the level. diff --git a/packages/wrangler/src/__tests__/logger.test.ts b/packages/wrangler/src/__tests__/logger.test.ts index 348076a69721..fbe91842e418 100644 --- a/packages/wrangler/src/__tests__/logger.test.ts +++ b/packages/wrangler/src/__tests__/logger.test.ts @@ -1,10 +1,11 @@ -import { logger } from "../logger"; +import { Logger } from "../logger"; import { mockConsoleMethods } from "./helpers/mock-console"; describe("logger", () => { const std = mockConsoleMethods(); it("should add colored markers to error and warning messages", () => { + const logger = new Logger(); logger.loggerLevel = "debug"; logger.debug("This is a debug message"); logger.log("This is a log message"); @@ -27,6 +28,7 @@ describe("logger", () => { describe("loggerLevel=debug", () => { it("should render messages that are at or above the log level set in the logger", () => { + const logger = new Logger(); logger.loggerLevel = "debug"; logger.debug("This is a debug message"); logger.log("This is a log message"); @@ -50,6 +52,7 @@ describe("logger", () => { describe("loggerLevel=log", () => { it("should render messages that are at or above the log level set in the logger", () => { + const logger = new Logger(); logger.loggerLevel = "log"; logger.debug("This is a debug message"); logger.log("This is a log message"); @@ -73,6 +76,7 @@ describe("logger", () => { describe("loggerLevel=warn", () => { it("should render messages that are at or above the log level set in the logger", () => { + const logger = new Logger(); logger.loggerLevel = "warn"; logger.debug("This is a debug message"); logger.log("This is a log message"); @@ -96,6 +100,7 @@ describe("logger", () => { describe("loggerLevel=error", () => { it("should render messages that are at or above the log level set in the logger", () => { + const logger = new Logger(); logger.loggerLevel = "error"; logger.debug("This is a debug message"); logger.log("This is a log message"); @@ -122,7 +127,7 @@ describe("logger", () => { }); it("should render messages that are at or above the log level set in the env var", () => { - logger.loggerLevel = "error"; + const logger = new Logger(); logger.debug("This is a debug message"); logger.log("This is a log message"); logger.warn("This is a warn message"); @@ -138,4 +143,65 @@ describe("logger", () => { `); }); }); + + describe("loggerLevelFromEnvVar case-insensitive", () => { + beforeEach(() => { + process.env.WRANGLER_LOG = "wARn"; + }); + afterEach(() => { + process.env.WRANGLER_LOG = undefined; + }); + + it("should render messages that are at or above the log level set in the env var", () => { + const logger = new Logger(); + logger.debug("This is a debug message"); + logger.log("This is a log message"); + logger.warn("This is a warn message"); + logger.error("This is a error message"); + + expect(std.debug).toMatchInlineSnapshot(`""`); + expect(std.out).toMatchInlineSnapshot(`""`); + expect(std.warn).toMatchInlineSnapshot(` + "▲ [WARNING] This is a warn message + + " + `); + expect(std.err).toMatchInlineSnapshot(` + "X [ERROR] This is a error message + + " + `); + }); + }); + + describe("loggerLevelFromEnvVar falls back to log on invalid level", () => { + beforeEach(() => { + process.env.WRANGLER_LOG = "everything"; + }); + afterEach(() => { + process.env.WRANGLER_LOG = undefined; + }); + + it("should render messages that are at or above the log level set in the env var", () => { + const logger = new Logger(); + logger.debug("This is a debug message"); + logger.log("This is a log message"); + logger.warn("This is a warn message"); + logger.error("This is a error message"); + + expect(std.debug).toMatchInlineSnapshot(`""`); + expect(std.out).toMatchInlineSnapshot(`"This is a log message"`); + expect(std.warn).toMatchInlineSnapshot(` + "Unrecognised WRANGLER_LOG value \\"everything\\", expected \\"none\\" | \\"error\\" | \\"warn\\" | \\"info\\" | \\"log\\" | \\"debug\\", defaulting to \\"log\\"... + ▲ [WARNING] This is a warn message + + " + `); + expect(std.err).toMatchInlineSnapshot(` + "X [ERROR] This is a error message + + " + `); + }); + }); }); diff --git a/packages/wrangler/src/logger.ts b/packages/wrangler/src/logger.ts index c4c663f7b440..5f7ebab6a303 100644 --- a/packages/wrangler/src/logger.ts +++ b/packages/wrangler/src/logger.ts @@ -26,15 +26,30 @@ const LOGGER_LEVEL_FORMAT_TYPE_MAP = { const getLogLevelFromEnv = getEnvironmentVariableFactory({ variableName: "WRANGLER_LOG", - defaultValue: () => "log", }); +function getLoggerLevel(): LoggerLevel { + const fromEnv = getLogLevelFromEnv()?.toLowerCase(); + if (fromEnv !== undefined) { + if (fromEnv in LOGGER_LEVELS) return fromEnv as LoggerLevel; + const expected = Object.keys(LOGGER_LEVELS) + .map((level) => `"${level}"`) + .join(" | "); + console.warn( + `Unrecognised WRANGLER_LOG value ${JSON.stringify( + fromEnv + )}, expected ${expected}, defaulting to "log"...` + ); + } + return "log"; +} + export type TableRow = Record; -class Logger { +export class Logger { constructor() {} - loggerLevel: LoggerLevel = (getLogLevelFromEnv() as LoggerLevel) ?? "log"; + loggerLevel = getLoggerLevel(); columns = process.stdout.columns; debug = (...args: unknown[]) => this.doLog("debug", args);