generated from adobe/aem-boilerplate
-
Notifications
You must be signed in to change notification settings - Fork 175
/
Copy pathlog.js
138 lines (123 loc) · 3.46 KB
/
log.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import { LOG_NAMESPACE } from './constants.js';
import { getParameter, isFunction, toBoolean } from './external.js';
import { lanaAppender } from './lana.js';
import { MiloEnv } from './settings.js';
const DEBUG = 'debug';
const ERROR = 'error';
const INFO = 'info';
const WARN = 'warn';
const epoch = Date.now();
/** @type {Set<(record: Commerce.Log.Entry) => boolean>} */
const appenders = new Set();
/** @type {Set<(record: Commerce.Log.Entry) => void>} */
const filters = new Set();
/** @type {Map<string, number>} */
const indexes = new Map();
const Level = Object.freeze({
DEBUG,
ERROR,
INFO,
WARN,
});
/* c8 ignore start */
const consoleAppender = {
append({ level, message, params, timestamp, source }) {
console[level](
`${timestamp}ms [${source}] %c${message}`,
'font-weight: bold;',
...params,
);
/* c8 ignore stop */
},
};
const debugFilter = { filter: ({ level }) => level !== DEBUG };
const quietFilter = { filter: () => false };
/* c8 ignore start */
function createEntry(level, message, namespace, params, source) {
return {
level,
message,
namespace,
get params() {
// Handle lazy param factory: a single function in the `params` array
if (params.length === 1) {
const [param] = params;
if (isFunction(param)) {
// Call lazy param factory and replace the factory with its result
params = param();
// Ensure `params` is an array of values
if (!Array.isArray(params)) params = [params];
}
}
return params;
},
source,
timestamp: Date.now() - epoch,
};
}
function handleEntry(entry) {
if ([...filters].every((filter) => filter(entry))) {
appenders.forEach((appender) => appender(entry));
}
}
/* c8 ignore stop */
function createLog(namespace) {
const index = (indexes.get(namespace) ?? 0) + 1;
indexes.set(namespace, index);
const id = `${namespace} #${index}`;
const createHandler =
(level) =>
(message, ...params) =>
handleEntry(createEntry(level, message, namespace, params, id));
const log = Object.seal({
id,
namespace,
module(name) {
return createLog(`${log.namespace}/${name}`);
},
debug: createHandler(Level.DEBUG),
error: createHandler(Level.ERROR),
info: createHandler(Level.INFO),
warn: createHandler(Level.WARN),
});
return log;
}
function use(...plugins) {
plugins.forEach((plugin) => {
const { append, filter } = plugin;
if (isFunction(filter)) {
filters.add(filter);
} else if (isFunction(append)) {
appenders.add(append);
}
});
}
function init(env = {}) {
const { name } = env;
const debug = toBoolean(
getParameter('commerce.debug', { search: true, storage: true }),
name === MiloEnv.LOCAL,
);
if (debug) use(consoleAppender);
else use(debugFilter);
if (name === MiloEnv.PROD) use(lanaAppender);
return Log;
}
function reset() {
appenders.clear();
filters.clear();
}
/** @type {Commerce.Log.Root} */
export const Log = {
...createLog(LOG_NAMESPACE),
Level,
Plugins: {
consoleAppender,
debugFilter,
quietFilter,
lanaAppender,
},
init,
reset,
use,
};