forked from jaytaylor/shipbuilder
/
logger.go
121 lines (108 loc) · 2.29 KB
/
logger.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
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
package main
import (
"bytes"
"fmt"
"io"
"math"
"net"
"sync"
"time"
)
type (
MessageWriter struct {
conn net.Conn
}
Logger struct {
writer io.Writer
prefix func() string
suffix func() string
written bool
lastEndedWithNewline bool
lock sync.Mutex
}
NilLogger struct{}
Format byte
)
const (
DIM Format = 2
RED Format = 31
GREEN Format = 32
YELLOW Format = 33
)
func (this *NilLogger) Write(bs []byte) (int, error) {
return len(bs), nil
}
func (this *MessageWriter) Write(p []byte) (n int, err error) {
err = Send(this.conn, Message{Log, string(p)})
n = len(p)
return
}
func NewMessageLogger(conn net.Conn) io.Writer {
return &MessageWriter{conn}
}
func NewLogger(writer io.Writer, prefix string) io.Writer {
return &Logger{
writer: writer,
prefix: func() string {
return prefix
},
suffix: func() string {
return ""
},
}
}
func NewFormatter(writer io.Writer, format Format) io.Writer {
return &Logger{
writer: writer,
prefix: func() string {
return fmt.Sprint("\033[", format, "m")
},
suffix: func() string {
return fmt.Sprint("\033[0m")
},
}
}
func NewTimeLogger(writer io.Writer) io.Writer {
start := time.Now()
return &Logger{
writer: writer,
prefix: func() string {
now := time.Now()
seconds := int(math.Ceil(now.Sub(start).Seconds()))
minutes := seconds / 60
seconds -= minutes * 60
return fmt.Sprintf("%d:%02d ", minutes, seconds)
},
suffix: func() string {
return ""
},
}
}
func (this *Logger) Write(bs []byte) (int, error) {
this.lock.Lock()
defer this.lock.Unlock()
prefix := this.prefix()
suffix := this.suffix()
final := bs
if !this.written || this.lastEndedWithNewline {
this.written = true
final = append([]byte(prefix), final...)
}
if bytes.HasSuffix(final, []byte{byte('\n')}) {
final = final[:len(final)-1]
this.lastEndedWithNewline = true
} else {
this.lastEndedWithNewline = false
}
final = bytes.Replace(final, []byte("\r\n"), []byte("\n"), -1)
final = bytes.Replace(final, []byte("\n"), []byte(suffix+"\n"+prefix), -1)
if this.lastEndedWithNewline {
final = append(final, []byte(suffix)...)
final = append(final, '\n')
}
n, err := this.writer.Write(final)
if n > len(bs) {
n = len(bs)
}
return n, err
}