UNPKG

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