Skip to content

Commit 1487fd4

Browse files
authored
Merge pull request #1 from kocoler/master
Add zap logger
2 parents 0ae5966 + 0913461 commit 1487fd4

File tree

5 files changed

+314
-1
lines changed

5 files changed

+314
-1
lines changed

README.md

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,30 @@
1-
# zap-logger
1+
Zap Logger
2+
===
3+
4+
Zap logger is the [Zap](https://github.com/uber-go/zap) logger for [Casbin](https://github.com/casbin/casbin). With this library, Casbin can log information more powerful.
5+
6+
## Installation
7+
8+
go get github.com/casbin/zap-logger
9+
10+
## How to use it
11+
12+
You could let your enforcer use this logger when you first initialize your enforcer like:
13+
```go
14+
e, _ := casbin.NewEnforcer("examples/rbac_model.conf", a, zaplogger.NewLogger(true, true), true)
15+
```
16+
or with and existing zap instance.
17+
```go
18+
logger := zaplogger.NewLoggerByZap(yourZapLogger, true)
19+
e, _ := casbin.NewEnforcer("examples/rbac_model.conf", a, logger, true)
20+
```
21+
22+
And the method `NewLogger` have two params: enabled and jsonEncode, you could initialize logger's log status and decide whether to output information with json encoded or not.
23+
24+
## Getting Help
25+
26+
- [Casbin](https://github.com/casbin/casbin)
27+
28+
## License
29+
30+
This project is under Apache 2.0 License. See the [LICENSE](LICENSE) file for the full license text.

go.mod

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module github.com/casbin/zap-logger
2+
3+
go 1.14
4+
5+
require (
6+
github.com/casbin/casbin/v2 v2.16.0
7+
go.uber.org/zap v1.16.0
8+
)

go.sum

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
2+
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
3+
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
4+
github.com/casbin/casbin v1.9.1 h1:ucjbS5zTrmSLtH4XogqOG920Poe6QatdXtz1FEbApeM=
5+
github.com/casbin/casbin/v2 v2.16.0 h1:VMppcatpiqlzpRHWVFD1k3T/zZaA+0kFWnrugm3xwz0=
6+
github.com/casbin/casbin/v2 v2.16.0/go.mod h1:XXtYGrs/0zlOsJMeRteEdVi/FsB0ph7KgNfjoCoJUD8=
7+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
8+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
9+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
10+
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
11+
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
12+
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
13+
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
14+
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
15+
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
16+
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
17+
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
18+
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
19+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
20+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
21+
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
22+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
23+
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
24+
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
25+
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
26+
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
27+
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
28+
go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
29+
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
30+
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
31+
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
32+
go.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM=
33+
go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
34+
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
35+
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
36+
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
37+
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
38+
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
39+
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
40+
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
41+
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
42+
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
43+
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
44+
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
45+
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
46+
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
47+
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
48+
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
49+
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs=
50+
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
51+
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
52+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
53+
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
54+
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
55+
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
56+
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
57+
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
58+
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
59+
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=

logger.go

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
// Copyright 2020 The casbin Authors. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package zaplogger
16+
17+
import (
18+
"go.uber.org/zap"
19+
"go.uber.org/zap/zapcore"
20+
)
21+
22+
// Logger is the implementation for a Logger using zap.
23+
type Logger struct {
24+
enabled bool
25+
logger *zap.Logger
26+
}
27+
28+
// Mapping of event field.
29+
var logEventMap = map[int]string{
30+
0: "LogTypeGrantedAccessRequest",
31+
1: "LogTypeRejectedAccessRequest",
32+
2: "LogTypeLoadPolicy",
33+
3: "LogTypePrintModel",
34+
4: "LogTypePrintPolicy",
35+
5: "LogTypePrintRole",
36+
6: "LogTypeLinkRole",
37+
}
38+
39+
// NewLogger is the default constructor for Logger.
40+
// Params : enabled, jsonEncode
41+
// enabled initialize recording state, jsonEncode initialize log whether structured as json.
42+
func NewLogger(enabled, jsonEncode bool) *Logger {
43+
var encoderConfig = zapcore.EncoderConfig{
44+
TimeKey: "time",
45+
LevelKey: "level",
46+
MessageKey: "event",
47+
EncodeLevel: zapcore.LowercaseLevelEncoder,
48+
EncodeTime: zapcore.ISO8601TimeEncoder,
49+
EncodeDuration: zapcore.SecondsDurationEncoder,
50+
}
51+
atomicLevel := zap.NewAtomicLevel()
52+
atomicLevel.SetLevel(zap.InfoLevel) // default log level: info
53+
54+
encodeMethod := "json"
55+
if !jsonEncode {
56+
encodeMethod = "console"
57+
}
58+
59+
config := zap.Config{
60+
Level: atomicLevel,
61+
Development: true,
62+
Encoding: encodeMethod,
63+
EncoderConfig: encoderConfig,
64+
OutputPaths: []string{"stdout"},
65+
ErrorOutputPaths: []string{"stderr"},
66+
}
67+
68+
logger, err := config.Build()
69+
if err != nil {
70+
panic(err)
71+
}
72+
73+
return &Logger{enabled: enabled, logger: logger}
74+
}
75+
76+
// NewLoggerByZap creates zap-logger by an existing zap instance.
77+
func NewLoggerByZap(zapLogger *zap.Logger, enabled bool) *Logger {
78+
return &Logger{
79+
enabled: enabled,
80+
logger: zapLogger,
81+
}
82+
}
83+
84+
func (l *Logger) EnableLog(enable bool) {
85+
l.enabled = enable
86+
}
87+
88+
func (l *Logger) IsEnabled() bool {
89+
return l.enabled
90+
}
91+
92+
func (l *Logger) LogModel(event int, line []string, model [][]string) {
93+
if !l.enabled {
94+
return
95+
}
96+
97+
l.logger.Info(logEventMap[event], zap.Strings("line", line))
98+
}
99+
100+
func (l *Logger) LogEnforce(event int, line string, request *[]interface{}, policies *[]string, result *[]interface{}) {
101+
if !l.enabled {
102+
return
103+
}
104+
105+
l.logger.Info(logEventMap[event], zap.String("line", line))
106+
}
107+
108+
func (l *Logger) LogPolicy(event int, line string, pPolicyFormat []string, gPolicyFormat []string, pPolicy *[]interface{}, gPolicy *[]interface{}) {
109+
if !l.enabled {
110+
return
111+
}
112+
113+
if pPolicy != nil {
114+
for k, v := range *pPolicy {
115+
l.logger.Info(logEventMap[event], zap.String("line", line), zap.Any("pPolicyFormat", pPolicyFormat[k]), zap.Any("pPolicy", v))
116+
}
117+
}
118+
if gPolicy != nil {
119+
for k, v := range *gPolicy {
120+
l.logger.Info(logEventMap[event], zap.String("line", line), zap.Any("gPolicyFormat", gPolicyFormat[k]), zap.Any("gPolicy", v))
121+
}
122+
}
123+
}
124+
125+
func (l *Logger) LogRole(event int, line string, role []string) {
126+
if !l.enabled {
127+
return
128+
}
129+
130+
l.logger.Info(logEventMap[event], zap.String("line", line))
131+
}

logger_test.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// Copyright 2020 The casbin Authors. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package zaplogger
16+
17+
import (
18+
"os"
19+
"testing"
20+
21+
"github.com/casbin/casbin/v2/log"
22+
"go.uber.org/zap"
23+
"go.uber.org/zap/zapcore"
24+
)
25+
26+
func testNewLogger(t *testing.T) *Logger {
27+
logger := NewLogger(false, true)
28+
29+
if logger == nil {
30+
t.Error("initialize logger failed")
31+
}
32+
33+
return logger
34+
}
35+
36+
func testNewLoggerByZap(t *testing.T) *Logger {
37+
var encoderConfig = zapcore.EncoderConfig{
38+
TimeKey: "time",
39+
LevelKey: "level",
40+
MessageKey: "event",
41+
EncodeLevel: zapcore.LowercaseLevelEncoder,
42+
EncodeTime: zapcore.ISO8601TimeEncoder,
43+
EncodeDuration: zapcore.SecondsDurationEncoder,
44+
}
45+
46+
core := zapcore.NewCore(
47+
zapcore.NewJSONEncoder(encoderConfig),
48+
zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout)),
49+
zap.NewAtomicLevel(),
50+
)
51+
logger := NewLoggerByZap(zap.New(core), false)
52+
53+
if logger == nil {
54+
t.Error("initialize logger failed")
55+
}
56+
57+
return logger
58+
}
59+
60+
func testLoggerLog(t *testing.T, logger log.Logger) {
61+
for i := 0; i < 10000; i++ {
62+
logger.LogEnforce(1, "2", &[]interface{}{"3"}, &[]string{"4"}, &[]interface{}{"5"})
63+
logger.LogPolicy(2, "3", []string{"4"}, []string{"5"}, &[]interface{}{"6"}, &[]interface{}{"7"})
64+
logger.LogModel(3, []string{"4"}, [][]string{{"5"}, {"6"}})
65+
logger.LogRole(5, "6", []string{"7"})
66+
}
67+
}
68+
69+
func TestLogger(t *testing.T) {
70+
loggerByDefault := testNewLogger(t)
71+
loggerByZap := testNewLoggerByZap(t)
72+
73+
if loggerByDefault.IsEnabled() || loggerByZap.IsEnabled() {
74+
t.Error("IsEnabled logger error")
75+
}
76+
77+
loggerByDefault.EnableLog(true)
78+
loggerByZap.EnableLog(true)
79+
80+
if !loggerByDefault.IsEnabled() || !loggerByZap.IsEnabled() {
81+
t.Error("Enable logger error")
82+
}
83+
84+
testLoggerLog(t, loggerByDefault)
85+
testLoggerLog(t, loggerByZap)
86+
}

0 commit comments

Comments
 (0)