UNPKG

3.31 kBJavaScriptView Raw
1
2"use strict"
3
4var enableRe
5, currentLevel = 2
6, namespaces = log.namespaces = {}
7, slice = [].slice
8, date = new Date()
9, color = (process.stdout || /* c8 ignore next */ process).isTTY && process.argv.indexOf("--no-color") < 0
10, green = "\x1b[32m"
11, reset = "\x1b[0m"
12
13if (!color) green = reset = ""
14
15log.levels = {
16 "error": 0,
17 "warn": 1,
18 "info": 2,
19 "debug": 3
20}
21
22module.exports = log
23
24log.debug = debug
25log.level = level
26// expose nop for testing
27log.nop = function nop() {}
28log.format = format
29
30log.rawStream = null
31log.prettyStream = process.stdout
32log.errorStream = process.stderr
33
34
35
36function log(name, enable) {
37 var binded = namespaces[name] || (namespaces[name] = function log() {
38 if (log.enabled === true) log.debug.apply(log, arguments)
39 })
40 binded.enabled = typeof enable === "boolean" ? enable : !!(enableRe && enableRe.test(name))
41 setLevels(name)
42 return binded
43}
44
45function level(newLevel) {
46 if (newLevel >= 0 && newLevel < Object.keys(log.levels).length) {
47 currentLevel = newLevel | 0
48 }
49 Object.keys(namespaces).forEach(setLevels)
50 return currentLevel
51}
52
53function setLevels(name) {
54 var level
55 , levels = log.levels
56 , binded = namespaces[name]
57 for (level in levels) {
58 binded[level] = (
59 binded.enabled || levels[level] <= currentLevel ?
60 Log.bind(binded, name, level) :
61 log.nop
62 )
63 }
64}
65
66function Log(name, level, msg) {
67 var args = arguments.length > 3 ? slice.call(arguments, 3) : null
68 , now = date.setTime(Date.now())
69 , tmp = now - (this.last || now)
70 , out = date.toISOString() + " " + name
71
72 if (log.rawStream) {
73 log.rawStream.write([now, name, level, msg, args])
74 }
75
76 if (msg instanceof Error) {
77 if (log.errorStream) {
78 log.errorStream.write(
79 date.toISOString() + " " + name + " " + msg.stack + "\n"
80 )
81 msg = msg.message
82 } else {
83 msg = msg.stack || msg.message
84 }
85 }
86
87 out += " " + (args === null ? msg : format(msg, args)) + green + " +" + (
88 tmp > 36e4 ? (tmp / 36e4).toFixed(1) + "h" :
89 tmp > 6e4 ? (tmp / 6e4).toFixed(1) + "m" :
90 tmp > 1e3 ? (tmp / 1e3 | 0) + "s" :
91 tmp + "ms"
92 ).replace(".0", "") + reset
93
94 if (log.prettyStream) {
95 log.prettyStream.write(out + "\n")
96 } else {
97 console.log(out)
98 }
99
100 this.last = now
101}
102
103function debug(filter) {
104
105 enableRe = filter && RegExp( // jshint ignore:line
106 "^(" +
107 filter
108 .replace(/[.+?^${}()|[\]\\]/g, "\\$&")
109 .replace(/\*/g, ".*?")
110 .replace(/[\s,]+/g, "|") +
111 ")$"
112 )
113 Object.keys(namespaces).forEach(log)
114}
115
116function format(msg, args) {
117 var tmp
118 , out = ""
119 , i = 0
120 , last = 0
121 , replaced = 0
122 , msgi = msg.length - 1
123 , argi = args.length
124
125 for (; i < msgi && replaced < argi; ) {
126 // 37=% 115=s 102=f 100=d 105=i 111=o
127 if (msg.charCodeAt(i++) === 37) {
128 tmp = msg.charCodeAt(i)
129 if (tmp === 115 || tmp === 100 || tmp === 102) {
130 out += msg.slice(last, i - 1) + args[replaced++]
131 last = ++i
132 } else if (tmp === 105) {
133 out += msg.slice(last, i - 1) + (args[replaced++]|0)
134 last = ++i
135 } else if (tmp === 111) {
136 out += msg.slice(last, i - 1) + JSON.stringify(args[replaced++])
137 last = ++i
138 } else if (tmp === 37) {
139 out += msg.slice(last, i)
140 last = ++i
141 }
142 }
143 }
144 if (last <= msgi) {
145 out += msg.slice(last)
146 }
147
148 if (replaced < argi) {
149 for (; replaced < argi; ) {
150 out += " " + args[replaced++]
151 }
152 }
153 return out
154}
155
156
157
158