UNPKG

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