日志 & 错误处理
日志
Casbin uses the built-in log
to print logs to the console by default, like:
2017/07/15 19:43:56 [Request: alice, data1, read ---> true]
Logging is not enabled by default. 您可以通过调用 Enforcer.EnableLog()
或 NewEnforcer()
函数中的最后一个参数来切换它。
We already support logging the model, enforce request, role, and policy in Golang. 您可以定义您自己的日志来记录Casbin。 如果您正在使用 Python, pycasbin 会影响默认的 Python 日志机制。 The pycasbin package makes a call to logging.getLogger()
to set the logger. 除了初始化父应用程序中的日志记录器外,不需要特殊配置的日志。 If no logging is initialized within the parent application, you will not see any log messages from pycasbin. At the same time, when you enable log in pycasbin, it will use the default log configuration. For other pycasbin extensions, you can refer to the Django logging docs if you are a Django user. For other Python users, you should refer to the Python logging docs to configure the logger. :::
Use different loggers for different enforcers
Every enforcer can have its own logger to log information, and it can be changed at runtime.
And you can use a proper logger via the last parameter of NewEnforcer()
. If you are using this way to initialize your enforcer, you don't need to use the enabled parameter because the priority of the enabled field in the logger is higher.
// 设置默认记录器作为执行器e1的记录器。
// This operation can also be seen as changing the logger of e1 at runtime.
e1.SetLogger(&Log.DefaultLogger{})
// 设置另一个记录器作为执行器e2的日志记录器。
e2.SetLogger(&YouOwnLogger)
// Set your logger when initializing enforcer e3.
e3, _ := casbin.NewEnforcer("examples/rbac_model.conf", a, logger)
支持的记录器
我们提供了一些记录器来帮助您记录信息。
- Go
- PHP
记录器 | 作者 | 描述 |
---|---|---|
Default logger (built-in) | Casbin | 默认使用golang日志。 |
Zap logger | Casbin | Using zap, provide json encoded log and you can customize more with your own zap-logger. |
记录器 | 作者 | 描述 |
---|---|---|
psr3-bridge 记录器 | Casbin | 提供一个 PSR-3 兼容桥。 |
如何编写一个记录器
您的记录器应该实现 Logger 接口。
接口名 | 实现要素 | 描述 |
---|---|---|
EnableLog() | 必须 | Control whether to print the message. |
IsEnabled() | 必须 | 显示当前日志启用的状态。 |
LogModel() | 必须 | Log info related to the model. |
LogEnforce() | 必须 | Log info related to enforcing. |
LogRole() | 必须 | Log info related to the role. |
LogPolicy() | mandatory | Log info related to the policy. |
您可以将您的自定义 记录器
传给 Enforcer.SetLogger()
函数。
Here is an example of how to customize a logger for Golang:
import (
"fmt"
"log"
"strings"
)
// 默认日志是使用golang日志的日志实现的。
type DefaultLogger struct {
enabled bool
}
func (l *DefaultLogger) EnableLog(enable bool) {
l.enabled = enable
}
func (l *DefaultLogger) IsEnabled() bool {
return l.enabled
}
func (l *DefaultLogger) LogModel(model [][]string) {
if !l.enabled {
return
}
var str strings.Builder
str.WriteString("Model: ")
for _, v := range model {
str.WriteString(fmt.Sprintf("%v\n", v))
}
log.Println(str.String())
}
func (l *DefaultLogger) LogEnforce(matcher string, request []interface{}, result bool, explains [][]string) {
if !l.enabled {
return
}
var reqStr strings.Builder
reqStr.WriteString("Request: ")
for i, rval := range request {
if i != len(request)-1 {
reqStr.WriteString(fmt.Sprintf("%v, ", rval))
} else {
reqStr.WriteString(fmt.Sprintf("%v", rval))
}
}
reqStr.WriteString(fmt.Sprintf(" ---> %t\n", result))
reqStr.WriteString("Hit Policy: ")
for i, pval := range explains {
if i != len(explains)-1 {
reqStr.WriteString(fmt.Sprintf("%v, ", pval))
} else {
reqStr.WriteString(fmt.Sprintf("%v \n", pval))
}
}
log.Println(reqStr.String())
}
func (l *DefaultLogger) LogPolicy(policy map[string][][]string) {
if !l.enabled {
return
}
var str strings.Builder
str.WriteString("Policy: ")
for k, v := range policy {
str.WriteString(fmt.Sprintf("%s : %v\n", k, v))
}
log.Println(str.String())
}
func (l *DefaultLogger) LogRole(roles []string) {
if !l.enabled {
return
}
log.Println("Roles: ", roles)
}
错误处理
Errors or panics may occur when you use Casbin for reasons like:
- Invalid syntax in the model file (.conf).
- Invalid syntax in the policy file (.csv).
- Custom errors from storage adapters, e.g., MySQL fails to connect.
- Casbin的bug。
There are five main functions you may need to be aware of for errors or panics:
Function | 异常时表现 |
---|---|
NewEnforcer() | Returns an error |
LoadModel() | Returns an error |
LoadPolicy() | Returns an error |
SavePolicy() | Returns an error |
Enforce() | Returns an error |
NewEnforcer()
calls LoadModel()
and LoadPolicy()
internally. So you don't have to call the latter two when using NewEnforcer()
.
:::
Enable and disable
可以通过 Encer.EnableEnforcece()
函数禁用执行器。 当它被禁用时, Enforcer.Enforce()
将总是返回 true
。 Other operations like adding or removing policies are not affected. 下面是一个示例:
e := casbin.NewEnforcer("examples/basic_model.conf", "examples/basic_policy.csv")
// 将会返回false
// 默认情况下enforcer是启用的
e.Enforce("non-authorized-user", "data1", "read")
// Disable the enforcer at runtime.
e.EnableEnforce(false)
// 对任何请求都返回true
e.Enforce("non-authorized-user", "data1", "read")
// 打开enforcer
e.EnableEnforce(true)
// 将会返回false
e.Enforce("non-authorized-user", "data1", "read")