UNPKG

2.67 kBJavaScriptView Raw
1
2"use strict";
3
4
5var enableRe
6, currentLevel = 2
7, namespaces = log.namespaces = {}
8, filters = []
9, slice = filters.slice
10, lastLog = {}
11, formatFns = {}
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
30
31
32
33function log(name, enable) {
34 var binded = namespaces[name] || (namespaces[name] = function log() {
35 if (log.enabled === true) log.debug.apply(log, arguments)
36 })
37 binded.enabled = typeof enable === "boolean" ? enable : !!(enableRe && enableRe.test(name))
38 setLevels(name)
39 return binded
40}
41
42function level(newLevel) {
43 if (newLevel >= 0 && newLevel < Object.keys(log.levels).length) {
44 currentLevel = newLevel | 0
45 }
46 Object.keys(namespaces).forEach(setLevels)
47 return currentLevel
48}
49
50function setLevels(name) {
51 var level
52 , levels = log.levels
53 , binded = namespaces[name]
54 for (level in levels) {
55 binded[level] = (
56 binded.enabled || levels[level] <= currentLevel ?
57 _log.bind(binded, name, level) :
58 log.nop
59 )
60 }
61}
62
63function _log(name, level, msg) {
64 var len, undef, out, tmp
65 , now = Date.now()
66 , argi = arguments.length
67 , args = argi > 3 ? slice.call(arguments, 3) : null
68
69 if (msg instanceof Error) {
70 msg = msg.stack || msg.message
71 }
72
73 if (log.rawStream) {
74 log.rawStream.write([now, name, level, msg, args])
75 }
76
77 if (log.prettyStream) {
78 tmp = now - (lastLog[name] || now)
79 out = new Date(now).toISOString() + " " + name + " +" + (
80 tmp > 36e4 ? (tmp / 36e4).toFixed(1) + "h" :
81 tmp > 6e4 ? (tmp / 6e4).toFixed(1) + "m" :
82 tmp > 1e3 ? (tmp / 1e3 | 0) + "s" :
83 tmp + "ms"
84 ).replace(".0", "")
85 if (args === null) {
86 out += " " + msg
87 } else {
88 out += " " + format(msg, args)
89 }
90
91 log.prettyStream.write(out + "\n")
92 }
93
94 lastLog[name] = now
95}
96
97function debug(filter) {
98 enableRe = filter && RegExp(
99 "^(" +
100 filter
101 .replace(/[.+?^${}()|[\]\\]/g, "\\$&")
102 .replace(/\*/g, ".*?")
103 .replace(/[\s,]+/g, "|") +
104 ")$"
105 )
106 Object.keys(namespaces).forEach(log)
107}
108
109function format(msg, args) {
110 var tmp
111 , out = ""
112 , i = 0
113 , last = 0
114 , replaced = 0
115 , msgi = msg.length - 1
116 , argi = args.length
117
118 for (; i < msgi && replaced < argi; ) {
119 if (msg.charCodeAt(i++) === 37) { // 37 = %
120 tmp = msg.charCodeAt(i)
121 if (tmp === 115) { // 115 = s
122 out += msg.slice(last, i - 1) + args[replaced++]
123 last = ++i
124 }
125 }
126 }
127 if (last <= msgi) {
128 out += msg.slice(last)
129 }
130
131 if (replaced < argi) {
132 for (; replaced < argi; ) {
133 out += " " + args[replaced++]
134 }
135 }
136 return out
137}
138
139
140
141