@rawnodes/logger 2.8.0 → 2.10.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/README.md +127 -17
- package/dist/index.d.mts +32 -230
- package/dist/index.d.ts +32 -230
- package/dist/index.js +233 -110
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +233 -111
- package/dist/index.mjs.map +1 -1
- package/dist/transports/relay.d.mts +14 -0
- package/dist/transports/relay.d.ts +14 -0
- package/dist/transports/relay.js +368 -0
- package/dist/transports/relay.js.map +1 -0
- package/dist/transports/relay.mjs +363 -0
- package/dist/transports/relay.mjs.map +1 -0
- package/dist/types-lfJLhC8J.d.mts +280 -0
- package/dist/types-lfJLhC8J.d.ts +280 -0
- package/package.json +21 -5
package/dist/index.js
CHANGED
|
@@ -167,8 +167,10 @@ var DEFAULT_OPTIONS = {
|
|
|
167
167
|
var BaseHttpTransport = class {
|
|
168
168
|
buffer;
|
|
169
169
|
onErrorCallback;
|
|
170
|
+
masker;
|
|
170
171
|
constructor(opts = {}) {
|
|
171
172
|
this.onErrorCallback = opts.onError;
|
|
173
|
+
this.masker = opts.masker;
|
|
172
174
|
this.buffer = new MessageBuffer({
|
|
173
175
|
batchSize: opts.batchSize ?? DEFAULT_OPTIONS.batchSize,
|
|
174
176
|
flushInterval: opts.flushInterval ?? DEFAULT_OPTIONS.flushInterval,
|
|
@@ -203,12 +205,16 @@ var BaseHttpTransport = class {
|
|
|
203
205
|
}
|
|
204
206
|
transformMessage(info) {
|
|
205
207
|
const { level, message, timestamp, context, ...meta } = info;
|
|
208
|
+
let resolvedMeta;
|
|
209
|
+
if (Object.keys(meta).length > 0) {
|
|
210
|
+
resolvedMeta = this.masker ? this.masker(meta) : meta;
|
|
211
|
+
}
|
|
206
212
|
return {
|
|
207
213
|
level,
|
|
208
214
|
message: String(message),
|
|
209
215
|
timestamp: timestamp instanceof Date ? timestamp : timestamp ? new Date(String(timestamp)) : /* @__PURE__ */ new Date(),
|
|
210
216
|
context,
|
|
211
|
-
meta:
|
|
217
|
+
meta: resolvedMeta
|
|
212
218
|
};
|
|
213
219
|
}
|
|
214
220
|
handleError(error, messages) {
|
|
@@ -255,7 +261,7 @@ var DEFAULT_REQUEST_TIMEOUT_MS = 1e4;
|
|
|
255
261
|
var DiscordTransport = class extends BaseHttpTransport {
|
|
256
262
|
config;
|
|
257
263
|
requestTimeout;
|
|
258
|
-
constructor(config) {
|
|
264
|
+
constructor(config, masker) {
|
|
259
265
|
super({
|
|
260
266
|
batchSize: config.batchSize ?? 10,
|
|
261
267
|
flushInterval: config.flushInterval ?? 2e3,
|
|
@@ -264,7 +270,8 @@ var DiscordTransport = class extends BaseHttpTransport {
|
|
|
264
270
|
maxQueueSize: config.maxQueueSize,
|
|
265
271
|
dropPolicy: config.dropPolicy,
|
|
266
272
|
onDrop: config.onDrop,
|
|
267
|
-
onError: config.onError
|
|
273
|
+
onError: config.onError,
|
|
274
|
+
masker
|
|
268
275
|
});
|
|
269
276
|
this.config = config;
|
|
270
277
|
this.requestTimeout = config.requestTimeout ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
@@ -404,7 +411,7 @@ var TelegramTransport = class extends BaseHttpTransport {
|
|
|
404
411
|
config;
|
|
405
412
|
apiUrl;
|
|
406
413
|
requestTimeout;
|
|
407
|
-
constructor(config) {
|
|
414
|
+
constructor(config, masker) {
|
|
408
415
|
super({
|
|
409
416
|
batchSize: config.batchSize ?? 20,
|
|
410
417
|
flushInterval: config.flushInterval ?? 1e3,
|
|
@@ -413,7 +420,8 @@ var TelegramTransport = class extends BaseHttpTransport {
|
|
|
413
420
|
maxQueueSize: config.maxQueueSize,
|
|
414
421
|
dropPolicy: config.dropPolicy,
|
|
415
422
|
onDrop: config.onDrop,
|
|
416
|
-
onError: config.onError
|
|
423
|
+
onError: config.onError,
|
|
424
|
+
masker
|
|
417
425
|
});
|
|
418
426
|
this.config = config;
|
|
419
427
|
this.apiUrl = `https://api.telegram.org/bot${config.botToken}`;
|
|
@@ -518,7 +526,7 @@ var ZohoCliqTransport = class extends BaseHttpTransport {
|
|
|
518
526
|
config;
|
|
519
527
|
endpoint;
|
|
520
528
|
requestTimeout;
|
|
521
|
-
constructor(config) {
|
|
529
|
+
constructor(config, masker) {
|
|
522
530
|
super({
|
|
523
531
|
batchSize: config.batchSize ?? 20,
|
|
524
532
|
flushInterval: config.flushInterval ?? 2e3,
|
|
@@ -527,7 +535,8 @@ var ZohoCliqTransport = class extends BaseHttpTransport {
|
|
|
527
535
|
maxQueueSize: config.maxQueueSize,
|
|
528
536
|
dropPolicy: config.dropPolicy,
|
|
529
537
|
onDrop: config.onDrop,
|
|
530
|
-
onError: config.onError
|
|
538
|
+
onError: config.onError,
|
|
539
|
+
masker
|
|
531
540
|
});
|
|
532
541
|
this.config = config;
|
|
533
542
|
this.requestTimeout = config.requestTimeout ?? DEFAULT_REQUEST_TIMEOUT_MS3;
|
|
@@ -649,7 +658,8 @@ var CloudWatchTransport = class extends BaseHttpTransport {
|
|
|
649
658
|
initialized = false;
|
|
650
659
|
initPromise = null;
|
|
651
660
|
resolvedLogStreamName;
|
|
652
|
-
|
|
661
|
+
maskReplacer;
|
|
662
|
+
constructor(config, configHostname, maskReplacerFn) {
|
|
653
663
|
super({
|
|
654
664
|
batchSize: config.batchSize ?? 100,
|
|
655
665
|
flushInterval: config.flushInterval ?? 1e3,
|
|
@@ -660,6 +670,7 @@ var CloudWatchTransport = class extends BaseHttpTransport {
|
|
|
660
670
|
onDrop: config.onDrop,
|
|
661
671
|
onError: config.onError
|
|
662
672
|
});
|
|
673
|
+
this.maskReplacer = maskReplacerFn;
|
|
663
674
|
this.config = config;
|
|
664
675
|
this.resolvedLogStreamName = resolveLogStreamName(config.logStreamName, configHostname);
|
|
665
676
|
this.client = new clientCloudwatchLogs.CloudWatchLogsClient({
|
|
@@ -672,6 +683,7 @@ var CloudWatchTransport = class extends BaseHttpTransport {
|
|
|
672
683
|
}
|
|
673
684
|
async sendBatch(messages) {
|
|
674
685
|
await this.ensureInitialized();
|
|
686
|
+
const replacer = this.maskReplacer;
|
|
675
687
|
const logEvents = messages.map((msg) => ({
|
|
676
688
|
timestamp: msg.timestamp.getTime(),
|
|
677
689
|
message: JSON.stringify({
|
|
@@ -679,7 +691,7 @@ var CloudWatchTransport = class extends BaseHttpTransport {
|
|
|
679
691
|
message: msg.message,
|
|
680
692
|
context: msg.context,
|
|
681
693
|
...msg.meta
|
|
682
|
-
})
|
|
694
|
+
}, replacer)
|
|
683
695
|
}));
|
|
684
696
|
logEvents.sort((a, b) => (a.timestamp ?? 0) - (b.timestamp ?? 0));
|
|
685
697
|
const command = new clientCloudwatchLogs.PutLogEventsCommand({
|
|
@@ -789,13 +801,27 @@ function getLevelName(levelNum) {
|
|
|
789
801
|
if (levelNum >= 20) return "debug";
|
|
790
802
|
return "silly";
|
|
791
803
|
}
|
|
792
|
-
|
|
804
|
+
var DEFAULT_RESPECTS_OVERRIDES = {
|
|
805
|
+
console: true,
|
|
806
|
+
file: true,
|
|
807
|
+
cloudwatch: true,
|
|
808
|
+
relay: true,
|
|
809
|
+
discord: false,
|
|
810
|
+
telegram: false,
|
|
811
|
+
zohoCliq: false
|
|
812
|
+
};
|
|
813
|
+
function resolveRespectsOverrides(kind, configFlag) {
|
|
814
|
+
return configFlag ?? DEFAULT_RESPECTS_OVERRIDES[kind];
|
|
815
|
+
}
|
|
816
|
+
function shouldPassTransport(log, level, rules, state, respectOverrides) {
|
|
793
817
|
const logLevel = getLevelName(log.level);
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
if (embeddedOverride === "
|
|
797
|
-
|
|
798
|
-
|
|
818
|
+
if (respectOverrides) {
|
|
819
|
+
const embeddedOverride = log.__or;
|
|
820
|
+
if (typeof embeddedOverride === "string") {
|
|
821
|
+
if (embeddedOverride === "off") return false;
|
|
822
|
+
const overrideLevel = embeddedOverride;
|
|
823
|
+
return LOG_LEVELS[logLevel] <= LOG_LEVELS[overrideLevel];
|
|
824
|
+
}
|
|
799
825
|
}
|
|
800
826
|
const context = log.context;
|
|
801
827
|
if (rules && rules.length > 0) {
|
|
@@ -817,12 +843,12 @@ function shouldPassTransport(log, level, rules, state) {
|
|
|
817
843
|
return LOG_LEVELS[logLevel] <= LOG_LEVELS[effectiveLevel];
|
|
818
844
|
}
|
|
819
845
|
var RESERVED_LOG_FIELDS = /* @__PURE__ */ new Set(["level", "time", "msg", "context", "__or"]);
|
|
820
|
-
function formatLog(log, format,
|
|
846
|
+
function formatLog(log, format, state) {
|
|
821
847
|
const levelName = getLevelName(log.level);
|
|
822
848
|
const timestamp = new Date(log.time).toISOString();
|
|
823
849
|
const context = log.context || "APP";
|
|
824
850
|
const message = log.msg || "";
|
|
825
|
-
const storeContext = store.getStore();
|
|
851
|
+
const storeContext = state.store.getStore();
|
|
826
852
|
const meta = {};
|
|
827
853
|
for (const [key, value] of Object.entries(log)) {
|
|
828
854
|
if (!RESERVED_LOG_FIELDS.has(key)) {
|
|
@@ -832,6 +858,7 @@ function formatLog(log, format, store) {
|
|
|
832
858
|
if (storeContext) {
|
|
833
859
|
Object.assign(meta, storeContext);
|
|
834
860
|
}
|
|
861
|
+
const replacer = state.maskReplacer;
|
|
835
862
|
if (format === "json") {
|
|
836
863
|
return JSON.stringify({
|
|
837
864
|
level: levelName,
|
|
@@ -839,7 +866,7 @@ function formatLog(log, format, store) {
|
|
|
839
866
|
context,
|
|
840
867
|
message,
|
|
841
868
|
...meta
|
|
842
|
-
}) + "\n";
|
|
869
|
+
}, replacer) + "\n";
|
|
843
870
|
}
|
|
844
871
|
if (format === "plain") {
|
|
845
872
|
const LEVEL_COLORS = {
|
|
@@ -855,10 +882,11 @@ function formatLog(log, format, store) {
|
|
|
855
882
|
const color = LEVEL_COLORS[levelName] || "";
|
|
856
883
|
const coloredLevel = color ? `${color}${levelName}${RESET}` : levelName;
|
|
857
884
|
const formatValue = (key, value) => {
|
|
858
|
-
|
|
859
|
-
|
|
885
|
+
const masked = replacer ? replacer.call(void 0, key, value) : value;
|
|
886
|
+
if (typeof masked === "string" && masked.includes("\n")) {
|
|
887
|
+
return "\n " + masked.split("\n").join("\n ");
|
|
860
888
|
}
|
|
861
|
-
return JSON.stringify(
|
|
889
|
+
return JSON.stringify(masked, replacer);
|
|
862
890
|
};
|
|
863
891
|
const metaStr = Object.keys(meta).length > 0 ? "\n " + Object.entries(meta).map(([k, v]) => `${k}: ${formatValue(k, v)}`).join("\n ") : "";
|
|
864
892
|
return `[${timestamp}] ${coloredLevel} [${context}] ${message}${metaStr}
|
|
@@ -867,14 +895,15 @@ function formatLog(log, format, store) {
|
|
|
867
895
|
if (format === "logfmt") {
|
|
868
896
|
const parts = [`level=${levelName}`, `msg="${message}"`, `context=${context}`, `ts=${timestamp}`];
|
|
869
897
|
for (const [k, v] of Object.entries(meta)) {
|
|
870
|
-
|
|
898
|
+
const masked = replacer ? replacer.call(void 0, k, v) : v;
|
|
899
|
+
parts.push(`${k}=${JSON.stringify(masked, replacer)}`);
|
|
871
900
|
}
|
|
872
901
|
return parts.join(" ") + "\n";
|
|
873
902
|
}
|
|
874
903
|
return `[${timestamp}] ${levelName}: ${message}
|
|
875
904
|
`;
|
|
876
905
|
}
|
|
877
|
-
function createFormattedFilterStream(format, level, rules, state, destination) {
|
|
906
|
+
function createFormattedFilterStream(format, level, rules, state, destination, respectOverrides) {
|
|
878
907
|
return new stream.Transform({
|
|
879
908
|
transform(chunk, _encoding, callback) {
|
|
880
909
|
const line = chunk.toString().trim();
|
|
@@ -887,11 +916,11 @@ function createFormattedFilterStream(format, level, rules, state, destination) {
|
|
|
887
916
|
callback();
|
|
888
917
|
return;
|
|
889
918
|
}
|
|
890
|
-
if (!shouldPassTransport(log, level, rules, state)) {
|
|
919
|
+
if (!shouldPassTransport(log, level, rules, state, respectOverrides)) {
|
|
891
920
|
callback();
|
|
892
921
|
return;
|
|
893
922
|
}
|
|
894
|
-
const formatted = formatLog(log, format, state
|
|
923
|
+
const formatted = formatLog(log, format, state);
|
|
895
924
|
destination.write(formatted);
|
|
896
925
|
callback();
|
|
897
926
|
}
|
|
@@ -905,7 +934,8 @@ function createStreams(config, state) {
|
|
|
905
934
|
config.console.level,
|
|
906
935
|
config.console.rules,
|
|
907
936
|
state,
|
|
908
|
-
process.stdout
|
|
937
|
+
process.stdout,
|
|
938
|
+
resolveRespectsOverrides("console", config.console.respectRuntimeOverrides)
|
|
909
939
|
);
|
|
910
940
|
streams.push({
|
|
911
941
|
level: "trace",
|
|
@@ -938,7 +968,8 @@ function createStreams(config, state) {
|
|
|
938
968
|
fileConfig.level,
|
|
939
969
|
fileConfig.rules,
|
|
940
970
|
state,
|
|
941
|
-
rotatingStream
|
|
971
|
+
rotatingStream,
|
|
972
|
+
resolveRespectsOverrides("file", fileConfig.respectRuntimeOverrides)
|
|
942
973
|
);
|
|
943
974
|
streams.push({
|
|
944
975
|
level: "trace",
|
|
@@ -946,36 +977,60 @@ function createStreams(config, state) {
|
|
|
946
977
|
});
|
|
947
978
|
}
|
|
948
979
|
for (const discordConfig of toArray(config.discord)) {
|
|
949
|
-
const transport = new DiscordTransport(discordConfig);
|
|
980
|
+
const transport = new DiscordTransport(discordConfig, state.maskerFn);
|
|
950
981
|
transports.push(transport);
|
|
951
|
-
const discordStream = createHttpTransportStream(
|
|
982
|
+
const discordStream = createHttpTransportStream(
|
|
983
|
+
transport,
|
|
984
|
+
discordConfig.level,
|
|
985
|
+
discordConfig.rules,
|
|
986
|
+
state,
|
|
987
|
+
resolveRespectsOverrides("discord", discordConfig.respectRuntimeOverrides)
|
|
988
|
+
);
|
|
952
989
|
streams.push({
|
|
953
990
|
level: "trace",
|
|
954
991
|
stream: discordStream
|
|
955
992
|
});
|
|
956
993
|
}
|
|
957
994
|
for (const telegramConfig of toArray(config.telegram)) {
|
|
958
|
-
const transport = new TelegramTransport(telegramConfig);
|
|
995
|
+
const transport = new TelegramTransport(telegramConfig, state.maskerFn);
|
|
959
996
|
transports.push(transport);
|
|
960
|
-
const telegramStream = createHttpTransportStream(
|
|
997
|
+
const telegramStream = createHttpTransportStream(
|
|
998
|
+
transport,
|
|
999
|
+
telegramConfig.level,
|
|
1000
|
+
telegramConfig.rules,
|
|
1001
|
+
state,
|
|
1002
|
+
resolveRespectsOverrides("telegram", telegramConfig.respectRuntimeOverrides)
|
|
1003
|
+
);
|
|
961
1004
|
streams.push({
|
|
962
1005
|
level: "trace",
|
|
963
1006
|
stream: telegramStream
|
|
964
1007
|
});
|
|
965
1008
|
}
|
|
966
1009
|
for (const zohoCliqConfig of toArray(config.zohoCliq)) {
|
|
967
|
-
const transport = new ZohoCliqTransport(zohoCliqConfig);
|
|
1010
|
+
const transport = new ZohoCliqTransport(zohoCliqConfig, state.maskerFn);
|
|
968
1011
|
transports.push(transport);
|
|
969
|
-
const zohoStream = createHttpTransportStream(
|
|
1012
|
+
const zohoStream = createHttpTransportStream(
|
|
1013
|
+
transport,
|
|
1014
|
+
zohoCliqConfig.level,
|
|
1015
|
+
zohoCliqConfig.rules,
|
|
1016
|
+
state,
|
|
1017
|
+
resolveRespectsOverrides("zohoCliq", zohoCliqConfig.respectRuntimeOverrides)
|
|
1018
|
+
);
|
|
970
1019
|
streams.push({
|
|
971
1020
|
level: "trace",
|
|
972
1021
|
stream: zohoStream
|
|
973
1022
|
});
|
|
974
1023
|
}
|
|
975
1024
|
for (const cloudwatchConfig of toArray(config.cloudwatch)) {
|
|
976
|
-
const transport = new CloudWatchTransport(cloudwatchConfig, config.hostname);
|
|
1025
|
+
const transport = new CloudWatchTransport(cloudwatchConfig, config.hostname, state.maskReplacer);
|
|
977
1026
|
transports.push(transport);
|
|
978
|
-
const cwStream = createHttpTransportStream(
|
|
1027
|
+
const cwStream = createHttpTransportStream(
|
|
1028
|
+
transport,
|
|
1029
|
+
cloudwatchConfig.level,
|
|
1030
|
+
cloudwatchConfig.rules,
|
|
1031
|
+
state,
|
|
1032
|
+
resolveRespectsOverrides("cloudwatch", cloudwatchConfig.respectRuntimeOverrides)
|
|
1033
|
+
);
|
|
979
1034
|
streams.push({
|
|
980
1035
|
level: "trace",
|
|
981
1036
|
stream: cwStream
|
|
@@ -1000,7 +1055,7 @@ function toArray(value) {
|
|
|
1000
1055
|
if (!value) return [];
|
|
1001
1056
|
return Array.isArray(value) ? value : [value];
|
|
1002
1057
|
}
|
|
1003
|
-
function createHttpTransportStream(transport, level, rules, state) {
|
|
1058
|
+
function createHttpTransportStream(transport, level, rules, state, respectOverrides) {
|
|
1004
1059
|
return new stream.Writable({
|
|
1005
1060
|
write(chunk, _encoding, callback) {
|
|
1006
1061
|
const line = chunk.toString().trim();
|
|
@@ -1013,7 +1068,7 @@ function createHttpTransportStream(transport, level, rules, state) {
|
|
|
1013
1068
|
callback();
|
|
1014
1069
|
return;
|
|
1015
1070
|
}
|
|
1016
|
-
if (!shouldPassTransport(log, level, rules, state)) {
|
|
1071
|
+
if (!shouldPassTransport(log, level, rules, state, respectOverrides)) {
|
|
1017
1072
|
callback();
|
|
1018
1073
|
return;
|
|
1019
1074
|
}
|
|
@@ -1039,6 +1094,116 @@ function createHttpTransportStream(transport, level, rules, state) {
|
|
|
1039
1094
|
});
|
|
1040
1095
|
}
|
|
1041
1096
|
|
|
1097
|
+
// src/utils/mask-secrets.ts
|
|
1098
|
+
var DEFAULT_SECRET_PATTERNS = [
|
|
1099
|
+
"password",
|
|
1100
|
+
"secret",
|
|
1101
|
+
"token",
|
|
1102
|
+
"apikey",
|
|
1103
|
+
"api_key",
|
|
1104
|
+
"api-key",
|
|
1105
|
+
"auth",
|
|
1106
|
+
"credential",
|
|
1107
|
+
"private"
|
|
1108
|
+
];
|
|
1109
|
+
var DEFAULT_MASK = "***";
|
|
1110
|
+
var REGEX_ESCAPE_RE = /[.*+?^${}()|[\]\\]/g;
|
|
1111
|
+
function buildSecretRe(patterns) {
|
|
1112
|
+
const escaped = patterns.map((p) => p.replace(REGEX_ESCAPE_RE, "\\$&"));
|
|
1113
|
+
return new RegExp(escaped.join("|"), "i");
|
|
1114
|
+
}
|
|
1115
|
+
var DEFAULT_SECRET_RE = buildSecretRe(DEFAULT_SECRET_PATTERNS);
|
|
1116
|
+
var DEFAULT_RESOLVED = {
|
|
1117
|
+
secretRe: DEFAULT_SECRET_RE,
|
|
1118
|
+
mask: DEFAULT_MASK,
|
|
1119
|
+
deep: true
|
|
1120
|
+
};
|
|
1121
|
+
function resolveOptions(options) {
|
|
1122
|
+
if (options.patterns === void 0 && options.mask === void 0 && options.deep === void 0) {
|
|
1123
|
+
return DEFAULT_RESOLVED;
|
|
1124
|
+
}
|
|
1125
|
+
const { patterns = DEFAULT_SECRET_PATTERNS, mask = DEFAULT_MASK, deep = true } = options;
|
|
1126
|
+
return {
|
|
1127
|
+
secretRe: patterns === DEFAULT_SECRET_PATTERNS ? DEFAULT_SECRET_RE : buildSecretRe(patterns),
|
|
1128
|
+
mask,
|
|
1129
|
+
deep
|
|
1130
|
+
};
|
|
1131
|
+
}
|
|
1132
|
+
function isSecretKey(key, secretRe) {
|
|
1133
|
+
return secretRe.test(key);
|
|
1134
|
+
}
|
|
1135
|
+
function maskUrlCredentials(url, mask) {
|
|
1136
|
+
try {
|
|
1137
|
+
const parsed = new URL(url);
|
|
1138
|
+
if (parsed.password) {
|
|
1139
|
+
parsed.password = mask;
|
|
1140
|
+
}
|
|
1141
|
+
if (parsed.username && parsed.password) {
|
|
1142
|
+
parsed.username = mask;
|
|
1143
|
+
}
|
|
1144
|
+
return parsed.toString();
|
|
1145
|
+
} catch {
|
|
1146
|
+
return url;
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
function maskString(str, mask) {
|
|
1150
|
+
if (str.length < 10) return str;
|
|
1151
|
+
if (str.charCodeAt(0) !== 104) return str;
|
|
1152
|
+
if (!str.startsWith("http://") && !str.startsWith("https://")) return str;
|
|
1153
|
+
if (str.indexOf("@") === -1) return str;
|
|
1154
|
+
return maskUrlCredentials(str, mask);
|
|
1155
|
+
}
|
|
1156
|
+
function maskInternal(obj, opts) {
|
|
1157
|
+
if (obj === null || obj === void 0) return obj;
|
|
1158
|
+
const t = typeof obj;
|
|
1159
|
+
if (t === "string") return maskString(obj, opts.mask);
|
|
1160
|
+
if (t !== "object") return obj;
|
|
1161
|
+
if (Array.isArray(obj)) {
|
|
1162
|
+
return opts.deep ? obj.map((item) => maskInternal(item, opts)) : obj;
|
|
1163
|
+
}
|
|
1164
|
+
const { secretRe, mask, deep } = opts;
|
|
1165
|
+
const result = {};
|
|
1166
|
+
const syms = Object.getOwnPropertySymbols(obj);
|
|
1167
|
+
for (let i = 0; i < syms.length; i++) {
|
|
1168
|
+
const sym = syms[i];
|
|
1169
|
+
result[sym] = obj[sym];
|
|
1170
|
+
}
|
|
1171
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
1172
|
+
if (isSecretKey(key, secretRe)) {
|
|
1173
|
+
result[key] = mask;
|
|
1174
|
+
continue;
|
|
1175
|
+
}
|
|
1176
|
+
const vt = typeof value;
|
|
1177
|
+
if (vt === "string") {
|
|
1178
|
+
result[key] = maskString(value, mask);
|
|
1179
|
+
} else if (deep && vt === "object" && value !== null) {
|
|
1180
|
+
result[key] = maskInternal(value, opts);
|
|
1181
|
+
} else {
|
|
1182
|
+
result[key] = value;
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
return result;
|
|
1186
|
+
}
|
|
1187
|
+
function maskSecrets(obj, options = {}) {
|
|
1188
|
+
return maskInternal(obj, resolveOptions(options));
|
|
1189
|
+
}
|
|
1190
|
+
function createMasker(options = {}) {
|
|
1191
|
+
const opts = resolveOptions(options);
|
|
1192
|
+
return (obj) => maskInternal(obj, opts);
|
|
1193
|
+
}
|
|
1194
|
+
function maskReplacer(options = {}) {
|
|
1195
|
+
const { secretRe, mask } = resolveOptions(options);
|
|
1196
|
+
return function(key, value) {
|
|
1197
|
+
if (key !== "" && secretRe.test(key)) return mask;
|
|
1198
|
+
if (typeof value !== "string") return value;
|
|
1199
|
+
if (value.length < 10) return value;
|
|
1200
|
+
if (value.charCodeAt(0) !== 104) return value;
|
|
1201
|
+
if (!value.startsWith("http://") && !value.startsWith("https://")) return value;
|
|
1202
|
+
if (value.indexOf("@") === -1) return value;
|
|
1203
|
+
return maskUrlCredentials(value, mask);
|
|
1204
|
+
};
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1042
1207
|
// src/state.ts
|
|
1043
1208
|
var CUSTOM_LEVELS = {
|
|
1044
1209
|
http: 25,
|
|
@@ -1087,6 +1252,7 @@ function createState(config, store) {
|
|
|
1087
1252
|
levelOverrides.set(key, rule);
|
|
1088
1253
|
}
|
|
1089
1254
|
const { contextIndex, complexRules } = buildIndexes(levelOverrides);
|
|
1255
|
+
const maskOptions = config.maskSecrets === true ? {} : config.maskSecrets || void 0;
|
|
1090
1256
|
const state = {
|
|
1091
1257
|
pino: null,
|
|
1092
1258
|
store: loggerStore,
|
|
@@ -1095,7 +1261,9 @@ function createState(config, store) {
|
|
|
1095
1261
|
contextIndex,
|
|
1096
1262
|
complexRules,
|
|
1097
1263
|
callerConfig: void 0,
|
|
1098
|
-
transports: []
|
|
1264
|
+
transports: [],
|
|
1265
|
+
maskReplacer: maskOptions ? maskReplacer(maskOptions) : void 0,
|
|
1266
|
+
maskerFn: maskOptions ? createMasker(maskOptions) : void 0
|
|
1099
1267
|
};
|
|
1100
1268
|
const { destination, transports } = createStreams(config, state);
|
|
1101
1269
|
state.transports = transports;
|
|
@@ -1172,12 +1340,14 @@ var LevelRuleSchema = zod.z.object({
|
|
|
1172
1340
|
var ConsoleConfigSchema = zod.z.object({
|
|
1173
1341
|
format: LogFormatSchema,
|
|
1174
1342
|
level: LogLevelSchema.optional(),
|
|
1175
|
-
rules: zod.z.array(LevelRuleSchema).optional()
|
|
1343
|
+
rules: zod.z.array(LevelRuleSchema).optional(),
|
|
1344
|
+
respectRuntimeOverrides: zod.z.boolean().optional()
|
|
1176
1345
|
});
|
|
1177
1346
|
var FileConfigSchema = zod.z.object({
|
|
1178
1347
|
format: LogFormatSchema,
|
|
1179
1348
|
level: LogLevelSchema.optional(),
|
|
1180
1349
|
rules: zod.z.array(LevelRuleSchema).optional(),
|
|
1350
|
+
respectRuntimeOverrides: zod.z.boolean().optional(),
|
|
1181
1351
|
dirname: zod.z.string().min(1, "dirname is required"),
|
|
1182
1352
|
filename: zod.z.string().min(1, "filename is required"),
|
|
1183
1353
|
datePattern: zod.z.string().optional(),
|
|
@@ -1189,6 +1359,7 @@ var FileConfigSchema = zod.z.object({
|
|
|
1189
1359
|
var HttpTransportBaseConfigSchema = zod.z.object({
|
|
1190
1360
|
level: LogLevelSchema.optional(),
|
|
1191
1361
|
rules: zod.z.array(LevelRuleSchema).optional(),
|
|
1362
|
+
respectRuntimeOverrides: zod.z.boolean().optional(),
|
|
1192
1363
|
batchSize: zod.z.number().int().positive().optional(),
|
|
1193
1364
|
flushInterval: zod.z.number().int().positive().optional(),
|
|
1194
1365
|
maxRetries: zod.z.number().int().nonnegative().optional(),
|
|
@@ -1202,6 +1373,7 @@ var HttpTransportBaseConfigSchema = zod.z.object({
|
|
|
1202
1373
|
var DiscordConfigSchema = zod.z.object({
|
|
1203
1374
|
level: LogLevelSchema.optional(),
|
|
1204
1375
|
rules: zod.z.array(LevelRuleSchema).optional(),
|
|
1376
|
+
respectRuntimeOverrides: zod.z.boolean().optional(),
|
|
1205
1377
|
batchSize: zod.z.number().int().positive().optional(),
|
|
1206
1378
|
flushInterval: zod.z.number().int().positive().optional(),
|
|
1207
1379
|
maxRetries: zod.z.number().int().nonnegative().optional(),
|
|
@@ -1223,6 +1395,7 @@ var DiscordConfigSchema = zod.z.object({
|
|
|
1223
1395
|
var TelegramConfigSchema = zod.z.object({
|
|
1224
1396
|
level: LogLevelSchema.optional(),
|
|
1225
1397
|
rules: zod.z.array(LevelRuleSchema).optional(),
|
|
1398
|
+
respectRuntimeOverrides: zod.z.boolean().optional(),
|
|
1226
1399
|
batchSize: zod.z.number().int().positive().optional(),
|
|
1227
1400
|
flushInterval: zod.z.number().int().positive().optional(),
|
|
1228
1401
|
maxRetries: zod.z.number().int().nonnegative().optional(),
|
|
@@ -1260,6 +1433,7 @@ var LogStreamNameSchema = zod.z.union([
|
|
|
1260
1433
|
var CloudWatchConfigSchema = zod.z.object({
|
|
1261
1434
|
level: LogLevelSchema.optional(),
|
|
1262
1435
|
rules: zod.z.array(LevelRuleSchema).optional(),
|
|
1436
|
+
respectRuntimeOverrides: zod.z.boolean().optional(),
|
|
1263
1437
|
batchSize: zod.z.number().int().positive().optional(),
|
|
1264
1438
|
flushInterval: zod.z.number().int().positive().optional(),
|
|
1265
1439
|
maxRetries: zod.z.number().int().nonnegative().optional(),
|
|
@@ -1280,6 +1454,7 @@ var CloudWatchConfigSchema = zod.z.object({
|
|
|
1280
1454
|
var ZohoCliqConfigBaseSchema = zod.z.object({
|
|
1281
1455
|
level: LogLevelSchema.optional(),
|
|
1282
1456
|
rules: zod.z.array(LevelRuleSchema).optional(),
|
|
1457
|
+
respectRuntimeOverrides: zod.z.boolean().optional(),
|
|
1283
1458
|
batchSize: zod.z.number().int().positive().optional(),
|
|
1284
1459
|
flushInterval: zod.z.number().int().positive().optional(),
|
|
1285
1460
|
maxRetries: zod.z.number().int().nonnegative().optional(),
|
|
@@ -1312,7 +1487,17 @@ var RelayConfigSchema = zod.z.object({
|
|
|
1312
1487
|
pollInterval: zod.z.number().int().positive().optional(),
|
|
1313
1488
|
bufferSize: zod.z.number().int().positive().optional(),
|
|
1314
1489
|
reconnectDelay: zod.z.number().int().positive().optional(),
|
|
1315
|
-
maxReconnectDelay: zod.z.number().int().positive().optional()
|
|
1490
|
+
maxReconnectDelay: zod.z.number().int().positive().optional(),
|
|
1491
|
+
respectRuntimeOverrides: zod.z.boolean().optional(),
|
|
1492
|
+
allowedWsHosts: zod.z.array(zod.z.string()).optional(),
|
|
1493
|
+
maskSecrets: zod.z.union([
|
|
1494
|
+
zod.z.boolean(),
|
|
1495
|
+
zod.z.object({
|
|
1496
|
+
patterns: zod.z.array(zod.z.string()).optional(),
|
|
1497
|
+
mask: zod.z.string().optional(),
|
|
1498
|
+
deep: zod.z.boolean().optional()
|
|
1499
|
+
})
|
|
1500
|
+
]).optional()
|
|
1316
1501
|
});
|
|
1317
1502
|
var LevelConfigObjectSchema = zod.z.object({
|
|
1318
1503
|
default: LogLevelSchema,
|
|
@@ -1330,6 +1515,11 @@ var AutoShutdownConfigSchema = zod.z.object({
|
|
|
1330
1515
|
timeout: zod.z.number().int().positive().optional(),
|
|
1331
1516
|
signals: zod.z.array(zod.z.string()).optional()
|
|
1332
1517
|
});
|
|
1518
|
+
var MaskSecretsOptionsSchema = zod.z.object({
|
|
1519
|
+
patterns: zod.z.array(zod.z.string()).optional(),
|
|
1520
|
+
mask: zod.z.string().optional(),
|
|
1521
|
+
deep: zod.z.boolean().optional()
|
|
1522
|
+
});
|
|
1333
1523
|
var LoggerConfigSchema = zod.z.object({
|
|
1334
1524
|
level: LevelConfigSchema,
|
|
1335
1525
|
console: ConsoleConfigSchema,
|
|
@@ -1341,7 +1531,8 @@ var LoggerConfigSchema = zod.z.object({
|
|
|
1341
1531
|
relay: RelayConfigSchema.optional(),
|
|
1342
1532
|
caller: zod.z.union([zod.z.boolean(), CallerConfigSchema]).optional(),
|
|
1343
1533
|
hostname: zod.z.string().optional(),
|
|
1344
|
-
autoShutdown: zod.z.union([zod.z.boolean(), AutoShutdownConfigSchema]).optional()
|
|
1534
|
+
autoShutdown: zod.z.union([zod.z.boolean(), AutoShutdownConfigSchema]).optional(),
|
|
1535
|
+
maskSecrets: zod.z.union([zod.z.boolean(), MaskSecretsOptionsSchema]).optional()
|
|
1345
1536
|
});
|
|
1346
1537
|
function validateConfig(config) {
|
|
1347
1538
|
return LoggerConfigSchema.parse(config);
|
|
@@ -1879,75 +2070,6 @@ function getOrGenerateRequestId(headers, options = {}) {
|
|
|
1879
2070
|
return extractRequestId(headers) ?? generateRequestId(options);
|
|
1880
2071
|
}
|
|
1881
2072
|
|
|
1882
|
-
// src/utils/mask-secrets.ts
|
|
1883
|
-
var DEFAULT_SECRET_PATTERNS = [
|
|
1884
|
-
"password",
|
|
1885
|
-
"secret",
|
|
1886
|
-
"token",
|
|
1887
|
-
"apikey",
|
|
1888
|
-
"api_key",
|
|
1889
|
-
"api-key",
|
|
1890
|
-
"auth",
|
|
1891
|
-
"credential",
|
|
1892
|
-
"private"
|
|
1893
|
-
];
|
|
1894
|
-
var DEFAULT_MASK = "***";
|
|
1895
|
-
function isSecretKey(key, patterns) {
|
|
1896
|
-
const lowerKey = key.toLowerCase();
|
|
1897
|
-
return patterns.some((pattern) => lowerKey.includes(pattern.toLowerCase()));
|
|
1898
|
-
}
|
|
1899
|
-
function maskUrlCredentials(url, mask) {
|
|
1900
|
-
try {
|
|
1901
|
-
const parsed = new URL(url);
|
|
1902
|
-
if (parsed.password) {
|
|
1903
|
-
parsed.password = mask;
|
|
1904
|
-
}
|
|
1905
|
-
if (parsed.username && parsed.password) {
|
|
1906
|
-
parsed.username = mask;
|
|
1907
|
-
}
|
|
1908
|
-
return parsed.toString();
|
|
1909
|
-
} catch {
|
|
1910
|
-
return url;
|
|
1911
|
-
}
|
|
1912
|
-
}
|
|
1913
|
-
function maskSecrets(obj, options = {}) {
|
|
1914
|
-
const { patterns = DEFAULT_SECRET_PATTERNS, mask = DEFAULT_MASK, deep = true } = options;
|
|
1915
|
-
if (obj === null || obj === void 0) {
|
|
1916
|
-
return obj;
|
|
1917
|
-
}
|
|
1918
|
-
if (typeof obj === "string") {
|
|
1919
|
-
if (obj.startsWith("http://") || obj.startsWith("https://")) {
|
|
1920
|
-
return maskUrlCredentials(obj, mask);
|
|
1921
|
-
}
|
|
1922
|
-
return obj;
|
|
1923
|
-
}
|
|
1924
|
-
if (Array.isArray(obj)) {
|
|
1925
|
-
return deep ? obj.map((item) => maskSecrets(item, options)) : obj;
|
|
1926
|
-
}
|
|
1927
|
-
if (typeof obj === "object") {
|
|
1928
|
-
const result = {};
|
|
1929
|
-
for (const sym of Object.getOwnPropertySymbols(obj)) {
|
|
1930
|
-
result[sym] = obj[sym];
|
|
1931
|
-
}
|
|
1932
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
1933
|
-
if (isSecretKey(key, patterns)) {
|
|
1934
|
-
result[key] = mask;
|
|
1935
|
-
} else if (deep && typeof value === "object" && value !== null) {
|
|
1936
|
-
result[key] = maskSecrets(value, options);
|
|
1937
|
-
} else if (typeof value === "string") {
|
|
1938
|
-
result[key] = maskSecrets(value, options);
|
|
1939
|
-
} else {
|
|
1940
|
-
result[key] = value;
|
|
1941
|
-
}
|
|
1942
|
-
}
|
|
1943
|
-
return result;
|
|
1944
|
-
}
|
|
1945
|
-
return obj;
|
|
1946
|
-
}
|
|
1947
|
-
function createMasker(options = {}) {
|
|
1948
|
-
return (obj) => maskSecrets(obj, options);
|
|
1949
|
-
}
|
|
1950
|
-
|
|
1951
2073
|
// src/formatters.ts
|
|
1952
2074
|
var MAX_FLATTEN_DEPTH = 10;
|
|
1953
2075
|
var CIRCULAR_REF = "[Circular]";
|
|
@@ -2040,6 +2162,7 @@ exports.generateRequestId = generateRequestId;
|
|
|
2040
2162
|
exports.getCallerInfo = getCallerInfo;
|
|
2041
2163
|
exports.getOrGenerateRequestId = getOrGenerateRequestId;
|
|
2042
2164
|
exports.isValidLogLevel = isValidLogLevel;
|
|
2165
|
+
exports.maskReplacer = maskReplacer;
|
|
2043
2166
|
exports.maskSecrets = maskSecrets;
|
|
2044
2167
|
exports.matchesContext = matchesContext;
|
|
2045
2168
|
exports.measureAsync = measureAsync;
|