-
Notifications
You must be signed in to change notification settings - Fork 0
/
log.go
75 lines (71 loc) · 1.79 KB
/
log.go
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
package log
import (
"encoding/json"
"os"
"runtime"
"runtime/debug"
"strconv"
"sync"
)
// Output is exported so that stdout can be synchronized with external printing functions
var Output sync.Mutex
// JSON encodes & print v on stdout as a JSON Lines object. Encodes :
// - nil as {}
// - string as {"Message":string}
// - error as {"Message":error.Error(),"Error":error}
// - non-object serializable type :
// - {"Item":v}
// - object serializable type :
// - v
// Its also adds a field "File" that is "path/to/file.go:line" of the caller, but can be overridden.
func JSON(v interface{}) {
Output.Lock()
defer Output.Unlock()
obj := map[string]interface{}{}
if _, file, line, ok := runtime.Caller(1); ok {
obj["File"] = file + ":" + strconv.Itoa(line)
}
switch item := v.(type) {
case nil:
case string:
obj["Message"] = item
case error:
obj["Message"] = item.Error()
obj["Error"] = item
default:
b, err := json.Marshal(item)
if err != nil {
panic(err)
}
// Is item is not serializable as a JSON object, put it in a field
if json.Unmarshal(b, &obj) != nil {
obj["Item"] = item
}
}
if err := json.NewEncoder(os.Stdout).Encode(obj); err != nil {
panic(err)
}
}
// Recover recovers panics and write a JSON Lines formatted entry
// Use it like this :
// func main() { // or func handler(w http.ResponseWriter, r *http.Request) {
// defer log.Recover()
func Recover() {
if r := recover(); r != nil {
Output.Lock()
if err, ok := r.(error); ok {
json.NewEncoder(os.Stdout).Encode(struct {
Message string
Error error
Stack string
}{err.Error(), err, string(debug.Stack())})
} else {
json.NewEncoder(os.Stdout).Encode(struct {
Error interface{}
Stack string
}{r, string(debug.Stack())})
}
Output.Unlock()
os.Exit(1)
}
}