forked from rlidwka/sinopia
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathlogger.js
153 lines (135 loc) · 3.82 KB
/
logger.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
var Logger = require('bunyan')
var Error = require('http-errors')
var Stream = require('stream')
var Utils = require('./utils')
function getlvl(x) {
switch(true) {
case x < 15 : return 'trace'
case x < 25 : return 'debug'
case x < 35 : return 'info'
case x == 35 : return 'http'
case x < 45 : return 'warn'
case x < 55 : return 'error'
default : return 'fatal'
}
}
module.exports.setup = function(logs) {
var streams = []
if (logs == null) logs = [{ type: 'stdout', format: 'pretty', level: 'http' }]
logs.forEach(function(target) {
var stream = new Stream()
stream.writable = true
if (target.type === 'stdout' || target.type === 'stderr') {
// destination stream
var dest = target.type === 'stdout' ? process.stdout : process.stderr
if (target.format === 'pretty') {
// making fake stream for prettypritting
stream.write = function(obj) {
dest.write(print(obj.level, obj.msg, obj, dest.isTTY) + '\n')
}
} else {
stream.write = function(obj) {
dest.write(JSON.stringify(obj, Logger.safeCycles()) + '\n')
}
}
} else if (target.type === 'file') {
var dest = require('fs').createWriteStream(target.path, {flags: 'a', encoding: 'utf8'})
dest.on('error', function (err) {
Logger.emit('error', err)
})
stream.write = function(obj) {
if (target.format === 'pretty') {
dest.write(print(obj.level, obj.msg, obj, false) + '\n')
} else {
dest.write(JSON.stringify(obj, Logger.safeCycles()) + '\n')
}
}
} else {
throw Error('wrong target type for a log')
}
if (target.level === 'http') target.level = 35
streams.push({
type: 'raw',
level: target.level || 35,
stream: stream,
})
})
var logger = new Logger({
name: 'sinopia',
streams: streams,
serializers: {
err: Logger.stdSerializers.err,
req: Logger.stdSerializers.req,
res: Logger.stdSerializers.res,
},
})
module.exports.logger = logger
}
// adopted from socket.io
// this part was converted to coffee-script and back again over the years,
// so it might look weird
// level to color
var levels = {
fatal : 31,
error : 31,
warn : 33,
http : 35,
info : 36,
debug : 90,
trace : 90,
}
var max = 0
for (var l in levels) {
max = Math.max(max, l.length)
}
function pad(str) {
if (str.length < max) return str + ' '.repeat(max - str.length)
return str
}
var subsystems = [{
in : '\033[32m<--\033[39m',
out : '\033[33m-->\033[39m',
fs : '\033[90m-=-\033[39m',
default : '\033[34m---\033[39m',
}, {
in : '<--',
out : '-->',
fs : '-=-',
default : '---',
}]
function print(type, msg, obj, colors) {
if (typeof type === 'number') type = getlvl(type)
var finalmsg = msg.replace(/@{(!?[$A-Za-z_][$0-9A-Za-z\._]*)}/g, function(_, name) {
var str = obj, is_error
if (name[0] === '!') {
name = name.substr(1)
is_error = true
}
var _ref = name.split('.')
for (var _i = 0; _i < _ref.length; _i++) {
var id = _ref[_i]
if (Utils.is_object(str) || Array.isArray(str)) {
str = str[id]
} else {
str = undefined
}
}
if (typeof(str) === 'string') {
if (!colors || str.includes('\n')) {
return str
} else if (is_error) {
return '\033[31m' + str + '\033[39m'
} else {
return '\033[32m' + str + '\033[39m'
}
} else {
return require('util').inspect(str, null, null, colors)
}
})
var sub = subsystems[colors ? 0 : 1][obj.sub] || subsystems[+!colors].default
if (colors) {
return ' \033[' + levels[type] + 'm' + (pad(type)) + '\033[39m ' + sub + ' ' + finalmsg
} else {
return ' ' + (pad(type)) + ' ' + sub + ' ' + finalmsg
}
}