-
-
Notifications
You must be signed in to change notification settings - Fork 178
/
main.go
129 lines (97 loc) · 2.49 KB
/
main.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
122
123
124
125
126
127
128
129
// Package main shows how to create a quite fast custom Log Formatter.
// Note that, this example requires a little more knowledge about Go.
package main
import (
"bytes"
"fmt"
"io"
"strconv"
"sync"
"time"
"github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/middleware/accesslog"
"github.com/kataras/iris/v12/middleware/requestid"
)
func logFields(ctx iris.Context, fields *accesslog.Fields) {
fields.Set("reqid", ctx.GetID())
}
func main() {
app := iris.New()
ac := accesslog.File("./access.log").
AddFields(logFields).
SetFormatter(newCustomFormatter(' ', "-\t\t\t\t\t"))
ac.RequestBody = false
ac.BytesReceivedBody = false
ac.BytesSentBody = false
defer ac.Close()
app.UseRouter(ac.Handler)
app.UseRouter(requestid.New())
app.OnErrorCode(iris.StatusNotFound, notFound)
app.Get("/", index)
app.Listen(":8080")
}
func notFound(ctx iris.Context) {
ctx.WriteString("The page you're looking for does not exist!")
}
func index(ctx iris.Context) {
ctx.WriteString("OK Index")
}
type customFormatter struct {
w io.Writer
bufPool *sync.Pool
delim byte
blank string
}
var _ accesslog.Formatter = (*customFormatter)(nil)
func newCustomFormatter(delim byte, blank string) *customFormatter {
return &customFormatter{delim: delim, blank: blank}
}
func (f *customFormatter) SetOutput(dest io.Writer) {
f.w = dest
f.bufPool = &sync.Pool{
New: func() interface{} {
return new(bytes.Buffer)
},
}
if f.delim == 0 {
f.delim = ' '
}
}
const newLine = '\n'
func (f *customFormatter) Format(log *accesslog.Log) (bool, error) {
buf := f.bufPool.Get().(*bytes.Buffer)
buf.WriteString(log.Now.Format(log.TimeFormat))
buf.WriteByte(f.delim)
reqid := log.Fields.GetString("reqid")
f.writeTextOrBlank(buf, reqid)
buf.WriteString(uniformDuration(log.Latency))
buf.WriteByte(f.delim)
buf.WriteString(log.IP)
buf.WriteByte(f.delim)
buf.WriteString(strconv.Itoa(log.Code))
buf.WriteByte(f.delim)
buf.WriteString(log.Method)
buf.WriteByte(f.delim)
buf.WriteString(log.Path)
buf.WriteByte(newLine)
// _, err := buf.WriteTo(f.w)
// or (to make sure that it resets on errors too):
_, err := f.w.Write(buf.Bytes())
buf.Reset()
f.bufPool.Put(buf)
return true, err
}
func (f *customFormatter) writeTextOrBlank(buf *bytes.Buffer, s string) {
if len(s) == 0 {
if len(f.blank) == 0 {
return
}
buf.WriteString(f.blank)
} else {
buf.WriteString(s)
}
buf.WriteByte(f.delim)
}
func uniformDuration(t time.Duration) string {
return fmt.Sprintf("%*s", 12, t.String())
}