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