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)
Підтримувані логери
Ми надаємо деякі логери, щоб допомогти вам логувати інформацію.
- Go
- PHP
Логер | Автор | Опис |
---|---|---|
Стандартний логер (вбудований) | Casbin | Стандартний логер, що використовує golang log. |
Логер Zap | Casbin | Використовуючи zap, надає json-кодований лог, і ви можете налаштувати більше з власним zap-логером. |
Логер | Автор | Опис |
---|---|---|
psr3-bridge логер | 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")