-
Notifications
You must be signed in to change notification settings - Fork 0
/
middleware.go
90 lines (79 loc) · 2.33 KB
/
middleware.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
package giris
import (
"encoding/json"
"net/http"
"time"
"github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/context"
"github.com/kataras/iris/v12/middleware/accesslog"
"github.com/kataras/iris/v12/middleware/rate"
"github.com/glibtools/libs/j2rpc"
"github.com/glibtools/libs/util"
)
type midLogger struct {
logger *accesslog.AccessLog
webLogger util.ItfLogger
}
func (m *midLogger) Constructor() { m.webLogger = util.ZapLogger("web", "debug") }
// Logger ......
func (m *midLogger) Logger() *accesslog.AccessLog {
ac := accesslog.New(m.WebLogger().Writer())
// The default configuration:
ac.Delim = '|'
ac.TimeFormat = "2006-01-02 15:04:05.000"
ac.Async = false
ac.IP = true
ac.BytesReceivedBody = true
ac.BytesSentBody = true
ac.BytesReceived = true
ac.BytesSent = true
ac.BodyMinify = true
ac.RequestBody = true
ac.ResponseBody = false
ac.KeepMultiLineError = true
ac.PanicLog = accesslog.LogHandler
// Default line format if formatter is missing:
// Time|Latency|Code|Method|Path|IP|Path Params Query Fields|Bytes Received|Bytes Sent|Request|Response|
//
// Set Custom Formatter:
//ac.SetFormatter(&accesslog.JSON{Indent: "", HumanTime: true})
// ac.SetFormatter(&accesslog.CSV{})
const defaultTmplText = "{{.Now.Format .TimeFormat}} | {{.Latency}}" +
" | {{.Code}} | {{.Method}} | {{.Path}} | {{.IP}}" +
" | {{.RequestValuesLine}} | {{.BytesReceivedLine}} | {{.BytesSentLine}}" +
" | {{.Request}} | {{.Response}} |\n"
ac.SetFormatter(&accesslog.Template{Text: defaultTmplText})
m.logger = ac
return m.logger
}
func (m *midLogger) WebLogger() util.ItfLogger {
return m.webLogger
}
func ConcurrentLimit(n int) iris.Handler {
ch := make(chan struct{}, n)
return func(c iris.Context) {
select {
case ch <- struct{}{}:
c.Next()
<-ch
default:
_ = c.StopWithJSON(http.StatusTooManyRequests, &j2rpc.RPCMessage{
ID: json.RawMessage("1"),
Error: j2rpc.NewError(http.StatusTooManyRequests, "系统繁忙,请稍后再试"),
})
}
}
}
func RateLimiter() context.Handler {
return rate.Limit(
10,
30,
rate.PurgeEvery(5*time.Minute, 15*time.Minute),
rate.ExceedHandler(func(c iris.Context) {
_ = c.StopWithJSON(http.StatusTooManyRequests, &j2rpc.RPCMessage{
ID: json.RawMessage("1"),
Error: j2rpc.NewError(http.StatusTooManyRequests, "请求过于频繁"),
})
}),
)
}