UNPKG

3.64 kBJavaScriptView Raw
1import { xglobal } from '@polkadot/x-global';
2import { formatDate } from './format/formatDate.js';
3import { isBn } from './is/bn.js';
4import { isBuffer } from './is/buffer.js';
5import { isFunction } from './is/function.js';
6import { isObject } from './is/object.js';
7import { isU8a } from './is/u8a.js';
8import { u8aToHex } from './u8a/toHex.js';
9import { u8aToU8a } from './u8a/toU8a.js';
10import { hasProcess } from './has.js';
11import { noop } from './noop.js';
12const logTo = {
13 debug: 'log',
14 error: 'error',
15 log: 'log',
16 warn: 'warn'
17};
18function formatOther(value) {
19 if (value && isObject(value) && value.constructor === Object) {
20 const result = {};
21 for (const [k, v] of Object.entries(value)) {
22 result[k] = loggerFormat(v);
23 }
24 return result;
25 }
26 return value;
27}
28export function loggerFormat(value) {
29 if (Array.isArray(value)) {
30 return value.map(loggerFormat);
31 }
32 else if (isBn(value)) {
33 return value.toString();
34 }
35 else if (isU8a(value) || isBuffer(value)) {
36 return u8aToHex(u8aToU8a(value));
37 }
38 return formatOther(value);
39}
40function formatWithLength(maxLength) {
41 return (v) => {
42 if (maxLength <= 0) {
43 return v;
44 }
45 const r = `${v}`;
46 return r.length < maxLength
47 ? v
48 : `${r.substring(0, maxLength)} ...`;
49 };
50}
51function apply(log, type, values, maxSize = -1) {
52 if (values.length === 1 && isFunction(values[0])) {
53 const fnResult = values[0]();
54 return apply(log, type, Array.isArray(fnResult) ? fnResult : [fnResult], maxSize);
55 }
56 console[logTo[log]](formatDate(new Date()), type, ...values
57 .map(loggerFormat)
58 .map(formatWithLength(maxSize)));
59}
60function isDebugOn(e, type) {
61 return !!e && (e === '*' ||
62 type === e ||
63 (e.endsWith('*') &&
64 type.startsWith(e.slice(0, -1))));
65}
66function isDebugOff(e, type) {
67 return !!e && (e.startsWith('-') &&
68 (type === e.slice(1) ||
69 (e.endsWith('*') &&
70 type.startsWith(e.slice(1, -1)))));
71}
72function getDebugFlag(env, type) {
73 let flag = false;
74 for (const e of env) {
75 if (isDebugOn(e, type)) {
76 flag = true;
77 }
78 else if (isDebugOff(e, type)) {
79 flag = false;
80 }
81 }
82 return flag;
83}
84function parseEnv(type) {
85 const env = (hasProcess ? xglobal.process : {}).env || {};
86 const maxSize = parseInt(env['DEBUG_MAX'] || '-1', 10);
87 return [
88 getDebugFlag((env['DEBUG'] || '').toLowerCase().split(','), type),
89 isNaN(maxSize)
90 ? -1
91 : maxSize
92 ];
93}
94/**
95 * @name Logger
96 * @summary Creates a consistent log interface for messages
97 * @description
98 * Returns a `Logger` that has `.log`, `.error`, `.warn` and `.debug` (controlled with environment `DEBUG=typeA,typeB`) methods. Logging is done with a consistent prefix (type of logger, date) followed by the actual message using the underlying console.
99 * @example
100 * <BR>
101 *
102 * ```javascript
103 * import { logger } from '@polkadot/util';
104 *
105 * const l = logger('test');
106 * ```
107 */
108export function logger(origin) {
109 const type = `${origin.toUpperCase()}:`.padStart(16);
110 const [isDebug, maxSize] = parseEnv(origin.toLowerCase());
111 return {
112 debug: isDebug
113 ? (...values) => apply('debug', type, values, maxSize)
114 : noop,
115 error: (...values) => apply('error', type, values),
116 log: (...values) => apply('log', type, values),
117 noop,
118 warn: (...values) => apply('warn', type, values)
119 };
120}