@eggjs/logger 0.0.0 → 4.0.1-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017-present Alibaba Group Holding Limited and other contributors.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,16 @@
1
+ import { EggConsoleLoggerOptions } from "../utils.js";
2
+ import { Logger } from "../logger.js";
3
+
4
+ //#region src/egg/console_logger.d.ts
5
+
6
+ /**
7
+ * Terminal Logger: sends all log output to console.
8
+ * Uses egg's server environment (EGG_SERVER_ENV or options.env) to determine default level.
9
+ * Production (prod) defaults to INFO; other environments default to WARN.
10
+ */
11
+ declare class EggConsoleLogger extends Logger {
12
+ constructor(options?: Partial<EggConsoleLoggerOptions>);
13
+ get defaults(): Partial<EggConsoleLoggerOptions>;
14
+ }
15
+ //#endregion
16
+ export { EggConsoleLogger };
@@ -0,0 +1,34 @@
1
+ import { Logger } from "../logger.js";
2
+ import { assign, consoleFormatter } from "../utils.js";
3
+ import { ConsoleTransport } from "../transports/console.js";
4
+
5
+ //#region src/egg/console_logger.ts
6
+ /**
7
+ * Terminal Logger: sends all log output to console.
8
+ * Uses egg's server environment (EGG_SERVER_ENV or options.env) to determine default level.
9
+ * Production (prod) defaults to INFO; other environments default to WARN.
10
+ */
11
+ var EggConsoleLogger = class extends Logger {
12
+ constructor(options) {
13
+ super();
14
+ const opts = assign({}, this.defaults, options);
15
+ const env = opts.env ?? process.env.EGG_SERVER_ENV ?? "";
16
+ const envLevel = process.env.NODE_CONSOLE_LOGGER_LEVEL;
17
+ const defaultLevel = env === "prod" ? "INFO" : "WARN";
18
+ const level = opts.level ?? envLevel ?? defaultLevel;
19
+ this.set("console", new ConsoleTransport({
20
+ level,
21
+ formatter: consoleFormatter,
22
+ maxCauseChainLength: opts.maxCauseChainLength
23
+ }));
24
+ }
25
+ get defaults() {
26
+ return {
27
+ encoding: "utf8",
28
+ maxCauseChainLength: 10
29
+ };
30
+ }
31
+ };
32
+
33
+ //#endregion
34
+ export { EggConsoleLogger };
@@ -0,0 +1,10 @@
1
+ import { EggLogger } from "./logger.js";
2
+
3
+ //#region src/egg/custom_logger.d.ts
4
+
5
+ /**
6
+ * Custom Logger: same as EggLogger but named for clarity.
7
+ */
8
+ declare class EggCustomLogger extends EggLogger {}
9
+ //#endregion
10
+ export { EggCustomLogger };
@@ -0,0 +1,10 @@
1
+ import { EggLogger } from "./logger.js";
2
+
3
+ //#region src/egg/custom_logger.ts
4
+ /**
5
+ * Custom Logger: same as EggLogger but named for clarity.
6
+ */
7
+ var EggCustomLogger = class extends EggLogger {};
8
+
9
+ //#endregion
10
+ export { EggCustomLogger };
@@ -0,0 +1,13 @@
1
+ import { EggLoggerOptions } from "../utils.js";
2
+ import { EggLogger } from "./logger.js";
3
+
4
+ //#region src/egg/error_logger.d.ts
5
+
6
+ /**
7
+ * Error Logger: only prints ERROR level and above.
8
+ */
9
+ declare class EggErrorLogger extends EggLogger {
10
+ constructor(options?: Partial<EggLoggerOptions>);
11
+ }
12
+ //#endregion
13
+ export { EggErrorLogger };
@@ -0,0 +1,23 @@
1
+ import { levels } from "../level.js";
2
+ import "../utils.js";
3
+ import { EggLogger } from "./logger.js";
4
+
5
+ //#region src/egg/error_logger.ts
6
+ /**
7
+ * Error Logger: only prints ERROR level and above.
8
+ */
9
+ var EggErrorLogger = class extends EggLogger {
10
+ constructor(options) {
11
+ const opts = options ?? {};
12
+ opts.level = getMinLevel(opts.level);
13
+ opts.consoleLevel = getMinLevel(opts.consoleLevel);
14
+ super(opts);
15
+ }
16
+ };
17
+ function getMinLevel(level) {
18
+ if (!level) return "ERROR";
19
+ return levels[level] >= levels.ERROR ? level : "ERROR";
20
+ }
21
+
22
+ //#endregion
23
+ export { EggErrorLogger };
@@ -0,0 +1,20 @@
1
+ import { LoggerLevel } from "../level.js";
2
+ import { EggLoggerOptions } from "../utils.js";
3
+ import { Logger } from "../logger.js";
4
+
5
+ //#region src/egg/logger.d.ts
6
+
7
+ /**
8
+ * Egg Logger: supports File, BufferedFile and Console transports.
9
+ */
10
+ declare class EggLogger extends Logger {
11
+ readonly opts: EggLoggerOptions;
12
+ constructor(options?: Partial<EggLoggerOptions>);
13
+ get level(): LoggerLevel;
14
+ set level(level: LoggerLevel);
15
+ get consoleLevel(): LoggerLevel;
16
+ set consoleLevel(level: LoggerLevel);
17
+ get defaults(): Partial<EggLoggerOptions>;
18
+ }
19
+ //#endregion
20
+ export { EggLogger };
@@ -0,0 +1,92 @@
1
+ import { Logger } from "../logger.js";
2
+ import { assign, consoleFormatter, defaultFormatter } from "../utils.js";
3
+ import { ConsoleTransport } from "../transports/console.js";
4
+ import { FileTransport } from "../transports/file.js";
5
+ import { FileBufferTransport } from "../transports/file_buffer.js";
6
+ import path from "node:path";
7
+
8
+ //#region src/egg/logger.ts
9
+ /**
10
+ * Egg Logger: supports File, BufferedFile and Console transports.
11
+ */
12
+ var EggLogger = class extends Logger {
13
+ opts;
14
+ constructor(options) {
15
+ super();
16
+ this.opts = assign({}, this.defaults, options);
17
+ this.options = this.opts;
18
+ const { opts } = this;
19
+ if (opts.file && opts.dir && !path.isAbsolute(opts.file)) opts.file = path.join(opts.dir, opts.file);
20
+ if (opts.outputJSON === true && opts.file) opts.jsonFile = opts.file.replace(/\.log$/, ".json.log");
21
+ const EggFileTransport = opts.buffer === true ? FileBufferTransport : FileTransport;
22
+ if (!opts.outputJSONOnly && opts.file) this.set("file", new EggFileTransport({
23
+ file: opts.file,
24
+ level: opts.level ?? "INFO",
25
+ encoding: opts.encoding,
26
+ formatter: opts.formatter,
27
+ contextFormatter: opts.contextFormatter,
28
+ paddingMessageFormatter: opts.paddingMessageFormatter,
29
+ flushInterval: opts.flushInterval,
30
+ eol: opts.eol,
31
+ localStorage: opts.localStorage,
32
+ dateISOFormat: opts.dateISOFormat,
33
+ maxCauseChainLength: opts.maxCauseChainLength
34
+ }));
35
+ if (opts.jsonFile) this.set("jsonFile", new EggFileTransport({
36
+ file: opts.jsonFile,
37
+ level: opts.level ?? "INFO",
38
+ encoding: opts.encoding,
39
+ flushInterval: opts.flushInterval,
40
+ json: true,
41
+ eol: opts.eol,
42
+ localStorage: opts.localStorage,
43
+ dateISOFormat: opts.dateISOFormat,
44
+ maxCauseChainLength: opts.maxCauseChainLength
45
+ }));
46
+ this.set("console", new ConsoleTransport({
47
+ level: opts.consoleLevel ?? "NONE",
48
+ formatter: consoleFormatter,
49
+ contextFormatter: opts.contextFormatter,
50
+ paddingMessageFormatter: opts.paddingMessageFormatter,
51
+ eol: opts.eol,
52
+ localStorage: opts.localStorage,
53
+ dateISOFormat: opts.dateISOFormat,
54
+ maxCauseChainLength: opts.maxCauseChainLength
55
+ }));
56
+ }
57
+ get level() {
58
+ return this.opts.level;
59
+ }
60
+ set level(level) {
61
+ this.opts.level = level;
62
+ for (const transport of this.values()) {
63
+ if (transport instanceof ConsoleTransport) continue;
64
+ transport.level = level;
65
+ }
66
+ }
67
+ get consoleLevel() {
68
+ return this.opts.consoleLevel;
69
+ }
70
+ set consoleLevel(level) {
71
+ this.opts.consoleLevel = level;
72
+ for (const transport of this.values()) if (transport instanceof ConsoleTransport) transport.level = level;
73
+ }
74
+ get defaults() {
75
+ return {
76
+ file: null,
77
+ encoding: "utf8",
78
+ level: "INFO",
79
+ consoleLevel: "NONE",
80
+ formatter: defaultFormatter,
81
+ buffer: true,
82
+ outputJSON: false,
83
+ outputJSONOnly: false,
84
+ dateISOFormat: false,
85
+ jsonFile: "",
86
+ maxCauseChainLength: 10
87
+ };
88
+ }
89
+ };
90
+
91
+ //#endregion
92
+ export { EggLogger };
@@ -0,0 +1,18 @@
1
+ import { EggLoggersConfig } from "../utils.js";
2
+ import { Logger } from "../logger.js";
3
+
4
+ //#region src/egg/loggers.d.ts
5
+
6
+ /**
7
+ * Logger Manager - creates and manages multiple loggers based on configuration.
8
+ */
9
+ declare class EggLoggers extends Map<string, Logger> {
10
+ [key: string]: unknown;
11
+ constructor(config: EggLoggersConfig);
12
+ set(name: string, logger: Logger): this;
13
+ disableConsole(): void;
14
+ reload(): void;
15
+ setConcentrateError(name: string, logger: Logger): void;
16
+ }
17
+ //#endregion
18
+ export { EggLoggers };
@@ -0,0 +1,98 @@
1
+ import { assign } from "../utils.js";
2
+ import { EggLogger } from "./logger.js";
3
+ import { EggErrorLogger } from "./error_logger.js";
4
+ import { EggCustomLogger } from "./custom_logger.js";
5
+ import { debuglog } from "node:util";
6
+ import assert from "node:assert";
7
+
8
+ //#region src/egg/loggers.ts
9
+ const debug = debuglog("egg:logger");
10
+ const defaults = {
11
+ env: "default",
12
+ type: "",
13
+ dir: "",
14
+ encoding: "utf8",
15
+ level: "INFO",
16
+ outputJSON: false,
17
+ outputJSONOnly: false,
18
+ buffer: true,
19
+ appLogName: "",
20
+ coreLogName: "",
21
+ agentLogName: "",
22
+ errorLogName: "",
23
+ concentrateError: "duplicate",
24
+ concentrateErrorLoggerName: "errorLogger"
25
+ };
26
+ /**
27
+ * Logger Manager - creates and manages multiple loggers based on configuration.
28
+ */
29
+ var EggLoggers = class extends Map {
30
+ constructor(config) {
31
+ super();
32
+ const loggerConfig = assign({}, defaults, config.logger);
33
+ if (loggerConfig.consoleLevel === void 0) {
34
+ const env = loggerConfig.env ?? "default";
35
+ loggerConfig.consoleLevel = env === "local" || env === "unittest" ? "INFO" : "NONE";
36
+ }
37
+ const customLoggerConfig = config.customLogger ?? {};
38
+ debug("Init loggers with options %j", loggerConfig);
39
+ assert(loggerConfig.type, "should pass config.logger.type");
40
+ assert(loggerConfig.dir, "should pass config.logger.dir");
41
+ assert(loggerConfig.appLogName, "should pass config.logger.appLogName");
42
+ assert(loggerConfig.coreLogName, "should pass config.logger.coreLogName");
43
+ assert(loggerConfig.agentLogName, "should pass config.logger.agentLogName");
44
+ assert(loggerConfig.errorLogName, "should pass config.logger.errorLogName");
45
+ const errorLogger = new EggErrorLogger(assign({}, loggerConfig, { file: loggerConfig.errorLogName }));
46
+ this.set("errorLogger", errorLogger);
47
+ let coreLogger;
48
+ let logger;
49
+ if (loggerConfig.type === "agent") {
50
+ logger = new EggLogger(assign({}, loggerConfig, { file: loggerConfig.agentLogName }));
51
+ coreLogger = new EggLogger(assign({}, loggerConfig, loggerConfig.coreLogger, { file: loggerConfig.agentLogName }));
52
+ } else {
53
+ logger = new EggLogger(assign({}, loggerConfig, { file: loggerConfig.appLogName }));
54
+ coreLogger = new EggLogger(assign({}, loggerConfig, loggerConfig.coreLogger, { file: loggerConfig.coreLogName }));
55
+ }
56
+ this.set("logger", logger);
57
+ this.set("coreLogger", coreLogger);
58
+ for (const name in customLoggerConfig) {
59
+ const customLogger = new EggCustomLogger(assign({}, loggerConfig, customLoggerConfig[name]));
60
+ this.set(name, customLogger);
61
+ }
62
+ this.setConcentrateError("logger", logger);
63
+ this.setConcentrateError("coreLogger", coreLogger);
64
+ for (const name in customLoggerConfig) this.setConcentrateError(name, this.get(name));
65
+ }
66
+ set(name, logger) {
67
+ if (this.has(name)) return this;
68
+ this[name] = logger;
69
+ super.set(name, logger);
70
+ return this;
71
+ }
72
+ disableConsole() {
73
+ for (const logger of this.values()) logger.disable("console");
74
+ }
75
+ reload() {
76
+ for (const logger of this.values()) logger.reload();
77
+ }
78
+ setConcentrateError(name, logger) {
79
+ if (name === "errorLogger") return;
80
+ const opts = logger.opts;
81
+ const concentrateLoggerName = opts.concentrateErrorLoggerName ?? "errorLogger";
82
+ const concentrateLogger = this.get(concentrateLoggerName);
83
+ if (!concentrateLogger) return;
84
+ switch (opts.concentrateError) {
85
+ case "duplicate":
86
+ logger.duplicate("ERROR", concentrateLogger, { excludes: ["console"] });
87
+ break;
88
+ case "redirect":
89
+ logger.redirect("ERROR", concentrateLogger);
90
+ break;
91
+ case "ignore": break;
92
+ default: break;
93
+ }
94
+ }
95
+ };
96
+
97
+ //#endregion
98
+ export { EggLoggers };
@@ -0,0 +1,13 @@
1
+ import { ALL, DEBUG, ERROR, INFO, LoggerLevel, NONE, WARN, levels } from "./level.js";
2
+ import { ConsoleTransportOptions, EggConsoleLoggerOptions, EggLoggerOptions, EggLoggersConfig, EggLoggersOptions, FileTransportOptions, LoggerMeta, TransportOptions, consoleFormatter, defaultContextPaddingMessage, defaultFormatter, formatError } from "./utils.js";
3
+ import { Transport } from "./transports/transport.js";
4
+ import { Logger } from "./logger.js";
5
+ import { EggConsoleLogger } from "./egg/console_logger.js";
6
+ import { EggLogger } from "./egg/logger.js";
7
+ import { EggCustomLogger } from "./egg/custom_logger.js";
8
+ import { EggErrorLogger } from "./egg/error_logger.js";
9
+ import { EggLoggers } from "./egg/loggers.js";
10
+ import { ConsoleTransport } from "./transports/console.js";
11
+ import { FileTransport } from "./transports/file.js";
12
+ import { FileBufferTransport } from "./transports/file_buffer.js";
13
+ export { ALL, ConsoleTransport, type ConsoleTransportOptions, DEBUG, ERROR, EggConsoleLogger, type EggConsoleLoggerOptions, EggCustomLogger, EggErrorLogger, EggLogger, type EggLoggerOptions, EggLoggers, type EggLoggersConfig, type EggLoggersOptions, FileBufferTransport, FileTransport, type FileTransportOptions, INFO, Logger, type LoggerLevel, type LoggerMeta, NONE, Transport, type TransportOptions, WARN, consoleFormatter, defaultContextPaddingMessage, defaultFormatter, formatError, levels };
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ import { ALL, DEBUG, ERROR, INFO, NONE, WARN, levels } from "./level.js";
2
+ import { Logger } from "./logger.js";
3
+ import { consoleFormatter, defaultContextPaddingMessage, defaultFormatter, formatError } from "./utils.js";
4
+ import { Transport } from "./transports/transport.js";
5
+ import { ConsoleTransport } from "./transports/console.js";
6
+ import { FileTransport } from "./transports/file.js";
7
+ import { FileBufferTransport } from "./transports/file_buffer.js";
8
+ import { EggLogger } from "./egg/logger.js";
9
+ import { EggErrorLogger } from "./egg/error_logger.js";
10
+ import { EggConsoleLogger } from "./egg/console_logger.js";
11
+ import { EggCustomLogger } from "./egg/custom_logger.js";
12
+ import { EggLoggers } from "./egg/loggers.js";
13
+
14
+ export { ALL, ConsoleTransport, DEBUG, ERROR, EggConsoleLogger, EggCustomLogger, EggErrorLogger, EggLogger, EggLoggers, FileBufferTransport, FileTransport, INFO, Logger, NONE, Transport, WARN, consoleFormatter, defaultContextPaddingMessage, defaultFormatter, formatError, levels };
@@ -0,0 +1,15 @@
1
+ //#region src/level.d.ts
2
+ declare const ALL: number;
3
+ /** Debug log for execute tracing */
4
+ declare const DEBUG: number;
5
+ /** Normal information logging */
6
+ declare const INFO: number;
7
+ /** Warning information logging */
8
+ declare const WARN: number;
9
+ /** Error or exception logging */
10
+ declare const ERROR: number;
11
+ declare const NONE: number;
12
+ type LoggerLevel = "ALL" | "DEBUG" | "INFO" | "WARN" | "ERROR" | "NONE";
13
+ declare const levels: Record<string, number>;
14
+ //#endregion
15
+ export { ALL, DEBUG, ERROR, INFO, LoggerLevel, NONE, WARN, levels };
package/dist/level.js ADDED
@@ -0,0 +1,22 @@
1
+ //#region src/level.ts
2
+ const ALL = -Infinity;
3
+ /** Debug log for execute tracing */
4
+ const DEBUG = 0;
5
+ /** Normal information logging */
6
+ const INFO = 1;
7
+ /** Warning information logging */
8
+ const WARN = 2;
9
+ /** Error or exception logging */
10
+ const ERROR = 3;
11
+ const NONE = Infinity;
12
+ const levels = {
13
+ ALL,
14
+ DEBUG,
15
+ INFO,
16
+ WARN,
17
+ ERROR,
18
+ NONE
19
+ };
20
+
21
+ //#endregion
22
+ export { ALL, DEBUG, ERROR, INFO, NONE, WARN, levels };
@@ -0,0 +1,41 @@
1
+ import { LoggerMeta } from "./utils.js";
2
+ import { Transport } from "./transports/transport.js";
3
+
4
+ //#region src/logger.d.ts
5
+ interface DuplicateLoggerEntry {
6
+ logger: Logger;
7
+ options: {
8
+ excludes?: string[];
9
+ };
10
+ }
11
+ /**
12
+ * Base class for all Logger classes.
13
+ * It extends Map and can contain multiple Transports.
14
+ */
15
+ declare class Logger<T extends Transport = Transport> extends Map<string, T> {
16
+ options: Record<string, unknown>;
17
+ name: string;
18
+ redirectLoggers: Map<string, Logger>;
19
+ duplicateLoggers: Map<string, DuplicateLoggerEntry>;
20
+ constructor(options?: Record<string, unknown>);
21
+ disable(name: string): void;
22
+ enable(name: string): void;
23
+ log(level: string, args: unknown[], meta?: LoggerMeta): void;
24
+ write(msg: string, ...rest: unknown[]): void;
25
+ redirect(level: string, logger: Logger): void;
26
+ unredirect(level: string): void;
27
+ duplicate(level: string, logger: Logger, options?: {
28
+ excludes?: string[];
29
+ }): void;
30
+ unduplicate(level: string): void;
31
+ reload(): void;
32
+ close(): void;
33
+ /** @deprecated use close() instead */
34
+ end(): void;
35
+ error(...args: unknown[]): void;
36
+ warn(...args: unknown[]): void;
37
+ info(...args: unknown[]): void;
38
+ debug(...args: unknown[]): void;
39
+ }
40
+ //#endregion
41
+ export { DuplicateLoggerEntry, Logger };
package/dist/logger.js ADDED
@@ -0,0 +1,95 @@
1
+ import util from "node:util";
2
+
3
+ //#region src/logger.ts
4
+ /**
5
+ * Base class for all Logger classes.
6
+ * It extends Map and can contain multiple Transports.
7
+ */
8
+ var Logger = class Logger extends Map {
9
+ options;
10
+ name;
11
+ redirectLoggers;
12
+ duplicateLoggers;
13
+ constructor(options) {
14
+ super();
15
+ this.options = Object.assign({}, options);
16
+ this.name = this.constructor.name;
17
+ this.redirectLoggers = /* @__PURE__ */ new Map();
18
+ this.duplicateLoggers = /* @__PURE__ */ new Map();
19
+ }
20
+ disable(name) {
21
+ const transport = this.get(name);
22
+ if (transport) transport.disable();
23
+ }
24
+ enable(name) {
25
+ const transport = this.get(name);
26
+ if (transport) transport.enable();
27
+ }
28
+ log(level, args, meta) {
29
+ let excludes;
30
+ const dupEntry = this.duplicateLoggers.get(level);
31
+ let dupLogger;
32
+ if (dupEntry) {
33
+ excludes = dupEntry.options.excludes;
34
+ dupLogger = dupEntry.logger;
35
+ dupLogger.log(level, args, meta);
36
+ } else {
37
+ const redirectLogger = this.redirectLoggers.get(level);
38
+ if (redirectLogger) {
39
+ redirectLogger.log(level, args, meta);
40
+ return;
41
+ }
42
+ }
43
+ for (const [key, transport] of this.entries()) if (transport.shouldLog(level) && !(excludes && excludes.includes(key))) transport.log(level, args, meta);
44
+ }
45
+ write(msg, ...rest) {
46
+ if (rest.length > 0) msg = util.format(msg, ...rest);
47
+ this.log("NONE", [msg], { raw: true });
48
+ }
49
+ redirect(level, logger) {
50
+ const lvl = level.toUpperCase();
51
+ if (!this.redirectLoggers.has(lvl) && logger instanceof Logger) this.redirectLoggers.set(lvl, logger);
52
+ }
53
+ unredirect(level) {
54
+ this.redirectLoggers.delete(level.toUpperCase());
55
+ }
56
+ duplicate(level, logger, options = {}) {
57
+ const lvl = level.toUpperCase();
58
+ if (!this.duplicateLoggers.has(lvl) && logger instanceof Logger) this.duplicateLoggers.set(lvl, {
59
+ logger,
60
+ options
61
+ });
62
+ }
63
+ unduplicate(level) {
64
+ this.duplicateLoggers.delete(level.toUpperCase());
65
+ }
66
+ reload() {
67
+ for (const transport of this.values()) transport.reload();
68
+ }
69
+ close() {
70
+ for (const transport of this.values()) transport.close();
71
+ }
72
+ /** @deprecated use close() instead */
73
+ end() {
74
+ process.emitWarning("logger.end() is deprecated, use logger.close()", {
75
+ type: "DeprecationWarning",
76
+ code: "DEP_EGG_LOGGER_END"
77
+ });
78
+ this.close();
79
+ }
80
+ error(...args) {
81
+ this.log("ERROR", args);
82
+ }
83
+ warn(...args) {
84
+ this.log("WARN", args);
85
+ }
86
+ info(...args) {
87
+ this.log("INFO", args);
88
+ }
89
+ debug(...args) {
90
+ this.log("DEBUG", args);
91
+ }
92
+ };
93
+
94
+ //#endregion
95
+ export { Logger };
@@ -0,0 +1,17 @@
1
+ import { ConsoleTransportOptions, LoggerMeta } from "../utils.js";
2
+ import { Transport } from "./transport.js";
3
+
4
+ //#region src/transports/console.d.ts
5
+
6
+ /**
7
+ * Output log to console.
8
+ * EGG_LOG env variable has the highest priority for log level.
9
+ */
10
+ declare class ConsoleTransport extends Transport {
11
+ options: ConsoleTransportOptions;
12
+ constructor(options?: Partial<ConsoleTransportOptions>);
13
+ get defaults(): Partial<ConsoleTransportOptions>;
14
+ log(level: string, args: unknown[], meta?: LoggerMeta): string | Buffer;
15
+ }
16
+ //#endregion
17
+ export { ConsoleTransport };
@@ -0,0 +1,31 @@
1
+ import { levels } from "../level.js";
2
+ import { normalizeLevel } from "../utils.js";
3
+ import { Transport } from "./transport.js";
4
+
5
+ //#region src/transports/console.ts
6
+ /**
7
+ * Output log to console.
8
+ * EGG_LOG env variable has the highest priority for log level.
9
+ */
10
+ var ConsoleTransport = class extends Transport {
11
+ constructor(options) {
12
+ super(options);
13
+ this.options.stderrLevel = normalizeLevel(this.options.stderrLevel);
14
+ if (process.env.EGG_LOG) this.options.level = normalizeLevel(process.env.EGG_LOG);
15
+ }
16
+ get defaults() {
17
+ return {
18
+ ...super.defaults,
19
+ stderrLevel: "ERROR"
20
+ };
21
+ }
22
+ log(level, args, meta) {
23
+ const msg = super.log(level, args, meta);
24
+ if (levels[level] >= this.options.stderrLevel && levels[level] < levels["NONE"]) process.stderr.write(msg);
25
+ else process.stdout.write(msg);
26
+ return msg;
27
+ }
28
+ };
29
+
30
+ //#endregion
31
+ export { ConsoleTransport };
@@ -0,0 +1,26 @@
1
+ import { FileTransportOptions, LoggerMeta } from "../utils.js";
2
+ import { Transport } from "./transport.js";
3
+ import fs from "node:fs";
4
+
5
+ //#region src/transports/file.d.ts
6
+ type WriteStream = fs.WriteStream & {
7
+ _onError?: (err: Error) => void;
8
+ };
9
+ /**
10
+ * Output log to file.
11
+ */
12
+ declare class FileTransport extends Transport {
13
+ options: FileTransportOptions;
14
+ _stream: WriteStream | null;
15
+ constructor(options?: Partial<FileTransportOptions>);
16
+ get defaults(): Partial<FileTransportOptions>;
17
+ reload(): void;
18
+ log(level: string, args: unknown[], meta?: LoggerMeta): string | Buffer;
19
+ close(): void;
20
+ get writable(): boolean;
21
+ _write(buf: string | Buffer): void;
22
+ _createStream(): WriteStream;
23
+ _closeStream(): void;
24
+ }
25
+ //#endregion
26
+ export { FileTransport };
@@ -0,0 +1,71 @@
1
+ import "../utils.js";
2
+ import { Transport } from "./transport.js";
3
+ import { logDate } from "utility";
4
+ import assert from "node:assert";
5
+ import fs from "node:fs";
6
+ import path from "node:path";
7
+
8
+ //#region src/transports/file.ts
9
+ /**
10
+ * Output log to file.
11
+ */
12
+ var FileTransport = class extends Transport {
13
+ constructor(options) {
14
+ super(options);
15
+ assert(this.options.file, "should pass options.file");
16
+ this._stream = null;
17
+ this.reload();
18
+ }
19
+ get defaults() {
20
+ return {
21
+ ...super.defaults,
22
+ file: null,
23
+ level: "INFO"
24
+ };
25
+ }
26
+ reload() {
27
+ this._closeStream();
28
+ this._stream = this._createStream();
29
+ }
30
+ log(level, args, meta) {
31
+ if (!this.writable) {
32
+ const err = /* @__PURE__ */ new Error(`${this.options.file} log stream had been closed`);
33
+ console.error(err.stack);
34
+ return "";
35
+ }
36
+ const buf = super.log(level, args, meta);
37
+ if (buf.length) this._write(buf);
38
+ return buf;
39
+ }
40
+ close() {
41
+ this._closeStream();
42
+ }
43
+ get writable() {
44
+ return !!(this._stream && !this._stream.closed && this._stream.writable && !this._stream.destroyed);
45
+ }
46
+ _write(buf) {
47
+ this._stream.write(buf);
48
+ }
49
+ _createStream() {
50
+ fs.mkdirSync(path.dirname(this.options.file), { recursive: true });
51
+ const stream = fs.createWriteStream(this.options.file, { flags: "a" });
52
+ const onError = (err) => {
53
+ console.error("%s ERROR %s [egg-logger] [%s] %s", logDate(","), process.pid, this.options.file, err.stack);
54
+ this.reload();
55
+ console.warn("%s WARN %s [egg-logger] [%s] reloaded", logDate(","), process.pid, this.options.file);
56
+ };
57
+ stream.once("error", onError);
58
+ stream._onError = onError;
59
+ return stream;
60
+ }
61
+ _closeStream() {
62
+ if (this._stream) {
63
+ this._stream.end();
64
+ if (this._stream._onError) this._stream.removeListener("error", this._stream._onError);
65
+ this._stream = null;
66
+ }
67
+ }
68
+ };
69
+
70
+ //#endregion
71
+ export { FileTransport };
@@ -0,0 +1,23 @@
1
+ import { FileTransportOptions } from "../utils.js";
2
+ import { FileTransport } from "./file.js";
3
+
4
+ //#region src/transports/file_buffer.d.ts
5
+
6
+ /**
7
+ * Extends FileTransport, saves log in memory and flushes to file at intervals.
8
+ */
9
+ declare class FileBufferTransport extends FileTransport {
10
+ _bufSize: number;
11
+ _buf: Array<string | Buffer>;
12
+ _timer: ReturnType<typeof setInterval> | null;
13
+ constructor(options?: Partial<FileTransportOptions>);
14
+ get defaults(): Partial<FileTransportOptions>;
15
+ close(): void;
16
+ flush(): void;
17
+ _closeStream(): void;
18
+ _write(buf: string | Buffer): void;
19
+ _createInterval(): ReturnType<typeof setInterval>;
20
+ _closeInterval(): void;
21
+ }
22
+ //#endregion
23
+ export { FileBufferTransport };
@@ -0,0 +1,57 @@
1
+ import "../utils.js";
2
+ import { FileTransport } from "./file.js";
3
+
4
+ //#region src/transports/file_buffer.ts
5
+ /**
6
+ * Extends FileTransport, saves log in memory and flushes to file at intervals.
7
+ */
8
+ var FileBufferTransport = class extends FileTransport {
9
+ constructor(options) {
10
+ super(options);
11
+ this._bufSize = 0;
12
+ this._buf = [];
13
+ this._timer = this._createInterval();
14
+ }
15
+ get defaults() {
16
+ return {
17
+ ...super.defaults,
18
+ flushInterval: 1e3,
19
+ maxBufferLength: 1e3
20
+ };
21
+ }
22
+ close() {
23
+ this._closeInterval();
24
+ super.close();
25
+ }
26
+ flush() {
27
+ if (this._buf.length > 0 && this.writable) {
28
+ if (this.options.encoding === "utf8") this._stream.write(this._buf.join(""));
29
+ else this._stream.write(Buffer.concat(this._buf, this._bufSize));
30
+ this._buf = [];
31
+ this._bufSize = 0;
32
+ }
33
+ }
34
+ _closeStream() {
35
+ if (this._buf && this._buf.length > 0) this.flush();
36
+ super._closeStream();
37
+ }
38
+ _write(buf) {
39
+ this._bufSize += typeof buf === "string" ? Buffer.byteLength(buf) : buf.length;
40
+ this._buf.push(buf);
41
+ if (this._buf.length > (this.options.maxBufferLength ?? 1e3)) this.flush();
42
+ }
43
+ _createInterval() {
44
+ const timer = setInterval(() => this.flush(), this.options.flushInterval ?? 1e3);
45
+ timer.unref();
46
+ return timer;
47
+ }
48
+ _closeInterval() {
49
+ if (this._timer) {
50
+ clearInterval(this._timer);
51
+ this._timer = null;
52
+ }
53
+ }
54
+ };
55
+
56
+ //#endregion
57
+ export { FileBufferTransport };
@@ -0,0 +1,28 @@
1
+ import { LoggerLevel } from "../level.js";
2
+ import { LoggerMeta, TransportOptions } from "../utils.js";
3
+
4
+ //#region src/transports/transport.d.ts
5
+
6
+ /**
7
+ * Transport is an output channel of the log that can be output to a file,
8
+ * console or service.
9
+ * A Logger can configure multiple Transports to meet a variety of complex needs.
10
+ */
11
+ declare class Transport {
12
+ #private;
13
+ options: TransportOptions;
14
+ constructor(options?: Partial<TransportOptions>);
15
+ get defaults(): Partial<TransportOptions>;
16
+ get enabled(): boolean;
17
+ enable(): void;
18
+ disable(): void;
19
+ set level(level: LoggerLevel | number);
20
+ get level(): number;
21
+ shouldLog(level: string): boolean;
22
+ log(level: string, args: unknown[], meta?: LoggerMeta): string | Buffer;
23
+ reload(): void;
24
+ close(): void;
25
+ end(): void;
26
+ }
27
+ //#endregion
28
+ export { Transport, type TransportOptions };
@@ -0,0 +1,67 @@
1
+ import { levels } from "../level.js";
2
+ import { assign, formatLog, normalizeLevel } from "../utils.js";
3
+ import os from "node:os";
4
+
5
+ //#region src/transports/transport.ts
6
+ /**
7
+ * Transport is an output channel of the log that can be output to a file,
8
+ * console or service.
9
+ * A Logger can configure multiple Transports to meet a variety of complex needs.
10
+ */
11
+ var Transport = class {
12
+ options;
13
+ #enabled = true;
14
+ constructor(options) {
15
+ this.options = assign({}, this.defaults, options);
16
+ if (this.options.encoding === "utf-8") this.options.encoding = "utf8";
17
+ const normalizedLevel = normalizeLevel(this.options.level);
18
+ if (normalizedLevel !== void 0) this.options.level = normalizedLevel;
19
+ }
20
+ get defaults() {
21
+ return {
22
+ level: "NONE",
23
+ formatter: null,
24
+ contextFormatter: null,
25
+ json: false,
26
+ encoding: "utf8",
27
+ eol: os.EOL
28
+ };
29
+ }
30
+ get enabled() {
31
+ return this.#enabled;
32
+ }
33
+ enable() {
34
+ this.#enabled = true;
35
+ }
36
+ disable() {
37
+ this.#enabled = false;
38
+ }
39
+ set level(level) {
40
+ const normalized = normalizeLevel(level);
41
+ if (normalized !== void 0) this.options.level = normalized;
42
+ }
43
+ get level() {
44
+ return this.options.level;
45
+ }
46
+ shouldLog(level) {
47
+ if (!this.#enabled) return false;
48
+ if (this.options.level === levels["NONE"]) return false;
49
+ return this.options.level <= levels[level];
50
+ }
51
+ log(level, args, meta) {
52
+ if (!meta?.ctx && this.options.localStorage) {
53
+ const ctx = this.options.localStorage.getStore();
54
+ if (ctx) meta = {
55
+ ...meta,
56
+ ctx
57
+ };
58
+ }
59
+ return formatLog(level, args, meta, this.options);
60
+ }
61
+ reload() {}
62
+ close() {}
63
+ end() {}
64
+ };
65
+
66
+ //#endregion
67
+ export { Transport };
@@ -0,0 +1,75 @@
1
+ import { LoggerLevel } from "./level.js";
2
+ import { AsyncLocalStorage } from "node:async_hooks";
3
+
4
+ //#region src/utils.d.ts
5
+ interface LoggerMeta {
6
+ level?: string;
7
+ date?: string;
8
+ pid?: number;
9
+ hostname?: string;
10
+ message?: string;
11
+ paddingMessage?: string;
12
+ ctx?: unknown;
13
+ raw?: boolean;
14
+ formatter?: (meta: LoggerMeta) => string;
15
+ [key: string]: unknown;
16
+ }
17
+ interface TransportOptions {
18
+ level?: LoggerLevel | number;
19
+ formatter?: ((meta: LoggerMeta) => string) | null;
20
+ contextFormatter?: ((meta: LoggerMeta) => string) | null;
21
+ paddingMessageFormatter?: ((ctx: unknown) => string) | null;
22
+ json?: boolean;
23
+ dateISOFormat?: boolean;
24
+ encoding?: string;
25
+ eol?: string;
26
+ localStorage?: AsyncLocalStorage<unknown>;
27
+ maxCauseChainLength?: number;
28
+ }
29
+ interface FileTransportOptions extends TransportOptions {
30
+ file?: string | null;
31
+ flushInterval?: number;
32
+ maxBufferLength?: number;
33
+ }
34
+ interface ConsoleTransportOptions extends TransportOptions {
35
+ stderrLevel?: LoggerLevel | number;
36
+ }
37
+ interface EggLoggerOptions extends Omit<TransportOptions, "level"> {
38
+ level?: LoggerLevel;
39
+ consoleLevel?: LoggerLevel;
40
+ file?: string | null;
41
+ dir?: string;
42
+ buffer?: boolean;
43
+ outputJSON?: boolean;
44
+ outputJSONOnly?: boolean;
45
+ jsonFile?: string;
46
+ concentrateError?: "duplicate" | "redirect" | "ignore";
47
+ concentrateErrorLoggerName?: string;
48
+ flushInterval?: number;
49
+ [key: string]: unknown;
50
+ }
51
+ interface EggLoggersOptions extends EggLoggerOptions {
52
+ type: string;
53
+ env?: string;
54
+ appLogName: string;
55
+ coreLogName: string;
56
+ agentLogName: string;
57
+ errorLogName: string;
58
+ coreLogger?: Partial<EggLoggersOptions>;
59
+ }
60
+ interface EggConsoleLoggerOptions extends TransportOptions {
61
+ env?: string;
62
+ }
63
+ interface EggLoggersConfig {
64
+ logger: EggLoggersOptions;
65
+ customLogger?: Record<string, EggLoggerOptions>;
66
+ }
67
+ declare function normalizeLevel(level?: LoggerLevel | number | string): number | undefined;
68
+ declare function defaultContextPaddingMessage(ctx: Record<string, unknown>): string;
69
+ declare function defaultFormatter(meta: LoggerMeta): string;
70
+ declare function consoleFormatter(meta: LoggerMeta): string;
71
+ declare function formatLog(level: string, args: unknown[], meta: LoggerMeta | undefined, options: TransportOptions): string | Buffer;
72
+ declare function assign<T>(target: Partial<T>, ...sources: Array<Partial<T> | null | undefined>): T;
73
+ declare function formatError(err: Error, options?: TransportOptions, causeLength?: number): string;
74
+ //#endregion
75
+ export { ConsoleTransportOptions, EggConsoleLoggerOptions, EggLoggerOptions, EggLoggersConfig, EggLoggersOptions, FileTransportOptions, LoggerMeta, TransportOptions, assign, consoleFormatter, defaultContextPaddingMessage, defaultFormatter, formatError, formatLog, normalizeLevel };
package/dist/utils.js ADDED
@@ -0,0 +1,146 @@
1
+ import { levels } from "./level.js";
2
+ import util from "node:util";
3
+ import os from "node:os";
4
+ import { performance } from "node:perf_hooks";
5
+ import { FrameworkBaseError, FrameworkErrorFormatter } from "@eggjs/errors";
6
+ import chalk from "chalk";
7
+ import circularJSON from "circular-json-for-egg";
8
+ import iconv from "iconv-lite";
9
+ import { logDate } from "utility";
10
+
11
+ //#region src/utils.ts
12
+ const hostname = os.hostname();
13
+ const durationRegexp = /\b(\d+ms)\b/g;
14
+ const categoryRegexp = /(\[[\w\-_.:]+\])/g;
15
+ const httpMethodRegexp = /(GET|POST|PUT|PATCH|HEAD|DELETE) /g;
16
+ function normalizeLevel(level) {
17
+ if (typeof level === "number") return level;
18
+ if (typeof level === "string" && level) return levels[level.toUpperCase()];
19
+ }
20
+ function defaultContextPaddingMessage(ctx) {
21
+ const userId = ctx.userId || "-";
22
+ const traceId = ctx.tracer?.traceId || "-";
23
+ let use = 0;
24
+ if (ctx.performanceStarttime) use = Math.floor((performance.now() - ctx.performanceStarttime) * 1e3) / 1e3;
25
+ else if (ctx.starttime) use = Date.now() - ctx.starttime;
26
+ return "[" + userId + "/" + ctx.ip + "/" + traceId + "/" + use + "ms " + ctx.method + " " + ctx.url + "]";
27
+ }
28
+ function defaultFormatter(meta) {
29
+ let paddingMessage = " ";
30
+ if (meta.paddingMessage) paddingMessage = ` ${meta.paddingMessage} `;
31
+ else {
32
+ const ctx = meta.ctx;
33
+ if (ctx) paddingMessage = ` ${defaultContextPaddingMessage(ctx)} `;
34
+ }
35
+ return meta.date + " " + meta.level + " " + meta.pid + paddingMessage + meta.message;
36
+ }
37
+ function consoleFormatter(meta) {
38
+ let paddingMessage = " ";
39
+ if (meta.paddingMessage) paddingMessage = ` ${meta.paddingMessage} `;
40
+ let msg = meta.date + " " + meta.level + " " + meta.pid + paddingMessage + meta.message;
41
+ if (chalk.level === 0) return msg;
42
+ if (meta.level === "ERROR") return chalk.red(msg);
43
+ if (meta.level === "WARN") return chalk.yellow(msg);
44
+ msg = msg.replace(durationRegexp, chalk.green("$1"));
45
+ msg = msg.replace(categoryRegexp, chalk.blue("$1"));
46
+ msg = msg.replace(httpMethodRegexp, chalk.cyan("$1 "));
47
+ return msg;
48
+ }
49
+ function formatLog(level, args, meta, options) {
50
+ meta = meta ?? {};
51
+ let message;
52
+ let output;
53
+ let formatter = meta.formatter ?? options.formatter;
54
+ if (meta.ctx) {
55
+ if (options.contextFormatter) {
56
+ formatter = options.contextFormatter;
57
+ if (!meta.paddingMessage) meta.paddingMessage = options.paddingMessageFormatter ? options.paddingMessageFormatter(meta.ctx) : defaultContextPaddingMessage(meta.ctx);
58
+ } else if (options.paddingMessageFormatter && !meta.paddingMessage) meta.paddingMessage = options.paddingMessageFormatter(meta.ctx);
59
+ }
60
+ if (args[0] instanceof Error) message = formatError(args[0], options);
61
+ else message = util.format(...args);
62
+ if (meta.raw === true) output = message;
63
+ else if (options.json === true || formatter) {
64
+ meta.level = level;
65
+ meta.date = options.dateISOFormat ? (/* @__PURE__ */ new Date()).toISOString() : logDate(",");
66
+ meta.pid = process.pid;
67
+ meta.hostname = hostname;
68
+ meta.message = message;
69
+ if (options.json === true) {
70
+ const outputMeta = {
71
+ ...meta,
72
+ ctx: void 0
73
+ };
74
+ output = JSON.stringify(outputMeta);
75
+ } else output = formatter(meta);
76
+ } else output = message;
77
+ if (!output) return Buffer.from("");
78
+ output += options.eol;
79
+ return options.encoding === "utf8" ? output : iconv.encode(output, options.encoding);
80
+ }
81
+ function assign(target, ...sources) {
82
+ const t = target;
83
+ for (const source of sources) {
84
+ if (source == null) continue;
85
+ const s = source;
86
+ for (const key of Object.keys(s)) {
87
+ const val = s[key];
88
+ if (val !== void 0) t[key] = val;
89
+ }
90
+ }
91
+ return target;
92
+ }
93
+ function formatError(err, options, causeLength) {
94
+ if (FrameworkBaseError.isFrameworkError(err)) return FrameworkErrorFormatter.format(err);
95
+ const msg = errorToString(err, options, causeLength);
96
+ return util.format("%s\npid: %s\nhostname: %s\n", msg, process.pid, hostname);
97
+ }
98
+ function errorToString(err, options, causeLength = 0) {
99
+ if (causeLength > (options?.maxCauseChainLength ?? 10)) return "too long cause chain";
100
+ const e = err;
101
+ let errName = e.name || "no_name";
102
+ if (e.name === "Error" && typeof e.code === "string") errName = e.code + errName;
103
+ let errMessage = e.message || "no_message";
104
+ if (e.host) errMessage += ` (${e.host})`;
105
+ const errStack = e.stack || "no_stack";
106
+ const errProperties = Object.keys(e).map((key) => inspectProp(key, e[key])).join("\n");
107
+ let errorString = util.format("nodejs.%s: %s\n%s\n%s", errName, errMessage, errStack.substring(errStack.indexOf("\n") + 1), errProperties);
108
+ if (e.name === "AggregateError" && e.errors) for (let i = 0; i < e.errors.length; i++) {
109
+ const subErrorMsg = errorToString(e.errors[i], options, causeLength + 1);
110
+ errorString = util.format("%s\n[error-%d]:\n\n%s", errorString, i, subErrorMsg);
111
+ }
112
+ if (e.cause) {
113
+ const causeMsg = errorToString(e.cause, options, causeLength + 1);
114
+ errorString = util.format("%s\ncause:\n\n%s", errorString, causeMsg);
115
+ }
116
+ return errorString;
117
+ }
118
+ function inspectProp(key, value) {
119
+ return `${key}: ${formatObject(value)}`;
120
+ }
121
+ function formatString(str) {
122
+ if (str.length > 1e4) return `${str.substring(0, 1e4)}...(${str.length})`;
123
+ return str;
124
+ }
125
+ function formatBuffer(buf) {
126
+ const tail = buf.data.length > 50 ? ` ...(${buf.data.length}) ` : "";
127
+ return `<Buffer ${buf.data.slice(0, 50).map((i) => {
128
+ const hex = i.toString(16);
129
+ return hex.length === 1 ? `0${hex}` : hex;
130
+ }).join(" ")}${tail}>`;
131
+ }
132
+ function formatObject(obj) {
133
+ try {
134
+ return circularJSON.stringify(obj, (_key, v) => {
135
+ if (typeof v === "string") return formatString(v);
136
+ if (v && v.type === "Buffer" && Array.isArray(v.data)) return formatBuffer(v);
137
+ if (v instanceof RegExp) return util.inspect(v);
138
+ return v;
139
+ });
140
+ } catch {
141
+ return String(obj);
142
+ }
143
+ }
144
+
145
+ //#endregion
146
+ export { assign, consoleFormatter, defaultContextPaddingMessage, defaultFormatter, formatError, formatLog, normalizeLevel };
@@ -0,0 +1,8 @@
1
+ //#region src/vendor.d.ts
2
+ declare module 'circular-json-for-egg' {
3
+ const circularJSON: {
4
+ stringify(obj: unknown, replacer?: (key: string, value: unknown) => unknown, space?: string | number): string;
5
+ parse(text: string): unknown;
6
+ };
7
+ export default circularJSON;
8
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eggjs/logger",
3
- "version": "0.0.0",
3
+ "version": "4.0.1-beta.0",
4
4
  "description": "egg logger",
5
5
  "keywords": [
6
6
  "egg",
@@ -17,15 +17,59 @@
17
17
  "url": "git+https://github.com/eggjs/egg.git",
18
18
  "directory": "packages/logger"
19
19
  },
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "type": "module",
24
+ "main": "./dist/index.js",
25
+ "module": "./dist/index.js",
26
+ "types": "./dist/index.d.ts",
27
+ "exports": {
28
+ ".": "./dist/index.js",
29
+ "./egg/console_logger": "./dist/egg/console_logger.js",
30
+ "./egg/custom_logger": "./dist/egg/custom_logger.js",
31
+ "./egg/error_logger": "./dist/egg/error_logger.js",
32
+ "./egg/logger": "./dist/egg/logger.js",
33
+ "./egg/loggers": "./dist/egg/loggers.js",
34
+ "./level": "./dist/level.js",
35
+ "./logger": "./dist/logger.js",
36
+ "./transports/console": "./dist/transports/console.js",
37
+ "./transports/file": "./dist/transports/file.js",
38
+ "./transports/file_buffer": "./dist/transports/file_buffer.js",
39
+ "./transports/transport": "./dist/transports/transport.js",
40
+ "./utils": "./dist/utils.js",
41
+ "./package.json": "./package.json"
42
+ },
20
43
  "publishConfig": {
21
44
  "access": "public"
22
45
  },
23
46
  "dependencies": {
47
+ "chalk": "^5.4.1",
48
+ "circular-json-for-egg": "^1.0.0",
49
+ "iconv-lite": "^0.6.3",
50
+ "utility": "^2.5.0",
51
+ "@eggjs/errors": "3.0.1-beta.0"
24
52
  },
25
53
  "devDependencies": {
54
+ "@types/node": "^24.10.2",
55
+ "coffee": "5",
56
+ "mm": "^4.0.2",
57
+ "oxlint": "^1.32.0",
58
+ "rimraf": "^6.1.2",
59
+ "typescript": "^5.9.3",
60
+ "vitest": "^4.0.15",
61
+ "@eggjs/supertest": "9.0.1-beta.0",
62
+ "@eggjs/koa": "3.1.1-beta.0",
63
+ "@eggjs/tsconfig": "3.1.1-beta.0"
26
64
  },
27
65
  "engines": {
28
66
  "node": ">= 22.18.0"
67
+ },
68
+ "scripts": {
69
+ "build": "tsdown",
70
+ "clean": "rimraf dist",
71
+ "lint": "oxlint --type-aware",
72
+ "typecheck": "tsgo --noEmit",
73
+ "test": "vitest run"
29
74
  }
30
- }
31
-
75
+ }