Logging & Error Handling
Логирование
Casbin can log requests, model load, and policy changes. Logging is off by default. Turn it on with Enforcer.EnableLog() or via the logger parameter to NewEnforcer(). Example output:
2017/07/15 19:43:56 [Request: alice, data1, read ---> true]
Go: You can plug in a custom logger; Casbin logs models, requests, roles, and policies through it.
Python: PyCasbin uses the standard logging module. Configure your app’s logging as usual; PyCasbin uses logging.getLogger(). Optional logging_config is documented in pycasbin/util/log.py. See Python logging and Django logging for setup.
Configure Separate Loggers for Different Enforcers
Each enforcer can have its own logger, and loggers can be changed at runtime.
You can specify a logger using the last parameter of NewEnforcer(). When using this method, the logger's enabled field takes precedence over the enforcer's enabled parameter.
// Set a default logger as enforcer e1's logger.
// This operation can also be seen as changing the logger of e1 at runtime.
e1.SetLogger(&Log.DefaultLogger{})
// Set another logger as enforcer e2's logger.
e2.SetLogger(&YouOwnLogger)
// Set your logger when initializing enforcer e3.
e3, _ := casbin.NewEnforcer("examples/rbac_model.conf", a, logger)
Supported Loggers
Casbin provides several logger implementations:
| Logger | Автор | Описание |
|---|---|---|
| Стандартный логгер (встроенный) | Casbin | The default logger using Go's standard log package. |
| Zap логгер | Casbin | Uses zap for JSON-encoded logs with additional customization options via zap-logger. |
| Logger | Автор | Описание |
|---|---|---|
| psr3-bridge logger | Casbin | Предоставляет совместимый с PSR-3 мост. |
Implementing Custom Loggers
Custom loggers must implement the Logger interface.
| Метод | Тип | Описание |
|---|---|---|
| EnableLog() | обязательный | Controls whether messages are printed. |
| IsEnabled() | обязательный | Returns the current logger's enabled status. |
| LogModel() | обязательный | Logs model-related information. |
| LogEnforce() | обязательный | Logs enforcement-related information. |
| LogRole() | обязательный | Logs role-related information. |
| LogPolicy() | обязательный | Logs policy-related information. |
Pass your custom logger to Enforcer.SetLogger().
Here's a Go example of implementing a custom logger:
import (
"fmt"
"log"
"strings"
)
// DefaultLogger is the implementation for a Logger using golang log.
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)
}
Error Handling
Errors or panics can occur in Casbin for several reasons:
- Неверный синтаксис в файле модели (.conf)
- Неверный синтаксис в файле политики (.csv)
- Custom errors from storage adapters (e.g., MySQL connection failures)
- Casbin bugs
Five primary functions may produce errors or panics:
| Функция | Behavior on Error |
|---|---|
| NewEnforcer() | Возвращает ошибку |
| LoadModel() | Возвращает ошибку |
| LoadPolicy() | Возвращает ошибку |
| SavePolicy() | Возвращает ошибку |
| Enforce() | Возвращает ошибку |
NewEnforcer() calls both LoadModel() and LoadPolicy() internally, so you don't need to call them separately when using NewEnforcer().
Enabling and Disabling Enforcement
You can disable the enforcer using Enforcer.EnableEnforce(). When disabled, Enforcer.Enforce() always returns true. Other operations like policy management remain unaffected. Пример:
e := casbin.NewEnforcer("examples/basic_model.conf", "examples/basic_policy.csv")
// Will return false.
// By default, the enforcer is enabled.
e.Enforce("non-authorized-user", "data1", "read")
// Disable the enforcer at runtime.
e.EnableEnforce(false)
// Will return true for any request.
e.Enforce("non-authorized-user", "data1", "read")
// Enable the enforcer again.
e.EnableEnforce(true)
// Will return false.
e.Enforce("non-authorized-user", "data1", "read")
Comments are powered by giscus and GitHub Discussions. They load from giscus.app and GitHub only after you click the button below.