Log & Error Handling
Логирование
Casbin по умолчанию использует встроенный log
для вывода логов в консоль, например:
2017/07/15 19:43:56 [Request: alice, data1, read ---> true]
Логирование по умолчанию не включено. Вы можете включить его с помощью Enforcer.EnableLog()
или последнего параметра NewEnforcer()
.
Мы уже поддерживаем логирование модели, запроса на принудительное выполнение, роли и политики в Golang. Вы можете определить свой собственный лог для логирования Casbin.
Если вы используете Python, pycasbin использует стандартный механизм логирования Python. Пакет pycasbin вызывает logging.getLogger()
для установки логгера. Для настройки логирования не требуется никакой специальной конфигурации, кроме инициализации логгера в родительском приложении. Если в родительском приложении не инициализировано логирование, вы не увидите никаких сообщений лога от pycasbin. В то же время, когда вы включаете лог в pycasbin, он будет использовать стандартную конфигурацию лога. Для других расширений pycasbin вы можете обратиться к документации по логированию Django, если вы пользователь Django. Для других пользователей Python вы должны обратиться к документации по логированию Python для настройки логгера.
Используйте разные логгеры для разных принудителей
У каждого принудителя может быть свой собственный логгер для записи информации, и он может быть изменен во время выполнения.
И вы можете использовать подходящий логгер через последний параметр NewEnforcer()
. Если вы используете этот способ для инициализации вашего принудителя, вам не нужно использовать параметр включения, потому что приоритет поля включения в логгере выше.
// 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)
Поддерживаемые логгеры
Мы предоставляем некоторые логгеры, чтобы помочь вам записывать информацию.
- Go
- PHP
Логгер | Автор | Описание |
---|---|---|
Стандартный логгер (встроенный) | Casbin | Стандартный логгер, использующий golang log. |
Zap логгер | Casbin | Используя zap, предоставляет лог в формате json, и вы можете настроить его еще больше с помощью вашего собственного zap-логгера. |
Logger | Автор | Описание |
---|---|---|
psr3-bridge logger | Casbin | Предоставляет совместимый с PSR-3 мост. |
Как написать логгер
Ваш логгер должен реализовывать интерфейс Logger.
Метод | Тип | Описание |
---|---|---|
EnableLog() | обязательный | Контролировать, следует ли печатать сообщение. |
IsEnabled() | обязательный | Показать текущий статус включения логгера. |
LogModel() | обязательный | Запись информации, связанной с моделью. |
LogEnforce() | обязательный | Запись информации, связанной с принудительным выполнением. |
LogRole() | обязательный | Запись информации, связанной с ролью. |
LogPolicy() | обязательный | Запись информации, связанной с политикой. |
Вы можете передать свой собственный logger
в Enforcer.SetLogger()
.
Вот пример того, как настроить логгер для Golang:
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)
}
Обработка ошибок
Ошибки или паника могут произойти при использовании Casbin по причинам, таким как:
- Неверный синтаксис в файле модели (.conf).
- Неверный синтаксис в файле политики (.csv).
- Пользовательские ошибки от адаптеров хранения, например, MySQL не может подключиться.
- Ошибка Casbin.
Есть пять основных функций, о которых вам, возможно, следует знать для ошибок или паники:
Функция | Поведение при ошибке |
---|---|
NewEnforcer() | Возвращает ошибку |
LoadModel() | Возвращает ошибку |
LoadPolicy() | Возвращает ошибку |
SavePolicy() | Возвращает ошибку |
Enforce() | Возвращает ошибку |
NewEnforcer()
вызывает LoadModel()
и LoadPolicy()
внутри себя. Поэтому вам не нужно вызывать последние две при использовании NewEnforcer()
.
Включение и отключение
Принудительное выполнение можно отключить с помощью функции Enforcer.EnableEnforce()
. Когда он отключен, Enforcer.Enforce()
всегда возвращает true
. Другие операции, такие как добавление или удаление политик, не затрагиваются. Вот пример:
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")