Log & Error Handling
Registro
Casbin utiliza el log
incorporado para imprimir registros en la consola por defecto, como:
2017/07/15 19:43:56 [Request: alice, data1, read ---> true]
El registro no está habilitado por defecto. Puedes activarlo mediante Enforcer.EnableLog()
o el último parámetro de NewEnforcer()
.
Ya admitimos el registro del modelo, solicitud de aplicación, rol y política en Golang. Puedes definir tu propio registro para registrar Casbin.
Si estás utilizando Python, pycasbin aprovecha el mecanismo de registro de Python por defecto. El paquete pycasbin hace una llamada a logging.getLogger()
para configurar el registrador. No se necesita ninguna configuración especial de registro aparte de inicializar el registrador en la aplicación principal. Si no se inicializa ningún registro dentro de la aplicación principal, no verás ningún mensaje de registro de pycasbin. Al mismo tiempo, cuando habilitas el registro en pycasbin, utilizará la configuración de registro por defecto. Para otras extensiones de pycasbin, puedes consultar la documentación de registro de Django si eres usuario de Django. Para otros usuarios de Python, debes consultar la documentación de registro de Python para configurar el registrador.
Usar diferentes registradores para diferentes ejecutores
Cada ejecutor puede tener su propio registrador para registrar información, y se puede cambiar en tiempo de ejecución.
Y puedes usar un registrador adecuado mediante el último parámetro de NewEnforcer()
. Si estás utilizando esta forma de inicializar tu ejecutor, no necesitas usar el parámetro habilitado porque la prioridad del campo habilitado en el registrador es más alta.
// 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)
Registradores admitidos
Proporcionamos algunos registradores para ayudarte a registrar información.
- Go
- PHP
Registrador | Autor | Descripción |
---|---|---|
Registrador por defecto (incorporado) | Casbin | El registrador por defecto utilizando log de golang. |
Registrador Zap | Casbin | Utilizando zap, proporciona registro codificado en json y puedes personalizar más con tu propio zap-logger. |
Registrador | Autor | Descripción |
---|---|---|
Registrador psr3-bridge | Casbin | Proporciona un puente compatible con PSR-3. |
Cómo escribir un registrador
Tu registrador debe implementar la interfaz Logger.
Método | Tipo | Descripción |
---|---|---|
EnableLog() | obligatorio | Controla si imprimir el mensaje. |
IsEnabled() | obligatorio | Muestra el estado habilitado del registrador actual. |
LogModel() | obligatorio | Registra información relacionada con el modelo. |
LogEnforce() | obligatorio | Información de registro relacionada con la aplicación. |
LogRole() | obligatorio | Información de registro relacionada con el rol. |
LogPolicy() | obligatorio | Información de registro relacionada con la política. |
Puede pasar su logger
personalizado a Enforcer.SetLogger()
.
Aquí hay un ejemplo de cómo personalizar un logger para 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)
}
Manejo de errores
Pueden ocurrir errores o pánicos cuando usa Casbin por razones como:
- Sintaxis inválida en el archivo del modelo (.conf).
- Sintaxis inválida en el archivo de políticas (.csv).
- Errores personalizados de adaptadores de almacenamiento, por ejemplo, MySQL no logra conectar.
- Bug de Casbin.
Hay cinco funciones principales que es posible que necesite conocer para errores o pánicos:
Función | Comportamiento en caso de error |
---|---|
NewEnforcer() | Devuelve un error |
LoadModel() | Devuelve un error |
LoadPolicy() | Devuelve un error |
SavePolicy() | Devuelve un error |
Enforce() | Devuelve un error |
NewEnforcer()
llama internamente a LoadModel()
y LoadPolicy()
. Así que no tiene que llamar a estos dos últimos al usar NewEnforcer()
.
Habilitar y deshabilitar
El enforcer se puede deshabilitar a través de la función Enforcer.EnableEnforce()
. Cuando está deshabilitado, Enforcer.Enforce()
siempre devolverá true
. Otras operaciones como agregar o eliminar políticas no se ven afectadas. Aquí hay un ejemplo:
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")