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

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 для налаштування логера.

Використання різних логерів для різних enforcers

Кожен enforcer може мати свій власний логер для логування інформації, і його можна змінити в режимі реального часу.

І ви можете використовувати відповідний логер через останній параметр NewEnforcer(). Якщо ви використовуєте цей спосіб ініціалізації вашого enforcer, вам не потрібно використовувати параметр enabled, оскільки пріоритет поля enabled у логері вищий.

// 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.
Логер ZapCasbinВикористовуючи 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")