Перейти к основному контенту

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)

Поддерживаемые логгеры

Мы предоставляем некоторые логгеры, чтобы помочь вам записывать информацию.

ЛоггерАвторОписание
Стандартный логгер (встроенный)CasbinСтандартный логгер, использующий golang log.
Zap логгерCasbinИспользуя zap, предоставляет лог в формате json, и вы можете настроить его еще больше с помощью вашего собственного zap-логгера.

Как написать логгер

Ваш логгер должен реализовывать интерфейс 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 по причинам, таким как:

  1. Неверный синтаксис в файле модели (.conf).
  2. Неверный синтаксис в файле политики (.csv).
  3. Пользовательские ошибки от адаптеров хранения, например, MySQL не может подключиться.
  4. Ошибка 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")