Ir al contenido principal

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().

nota

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.

RegistradorAutorDescripción
Registrador por defecto (incorporado)CasbinEl registrador por defecto utilizando log de golang.
Registrador ZapCasbinUtilizando zap, proporciona registro codificado en json y puedes personalizar más con tu propio zap-logger.

Cómo escribir un registrador

Tu registrador debe implementar la interfaz Logger.

MétodoTipoDescripción
EnableLog()obligatorioControla si imprimir el mensaje.
IsEnabled()obligatorioMuestra el estado habilitado del registrador actual.
LogModel()obligatorioRegistra información relacionada con el modelo.
LogEnforce()obligatorioInformación de registro relacionada con la aplicación.
LogRole()obligatorioInformación de registro relacionada con el rol.
LogPolicy()obligatorioInformació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:

  1. Sintaxis inválida en el archivo del modelo (.conf).
  2. Sintaxis inválida en el archivo de políticas (.csv).
  3. Errores personalizados de adaptadores de almacenamiento, por ejemplo, MySQL no logra conectar.
  4. Bug de Casbin.

Hay cinco funciones principales que es posible que necesite conocer para errores o pánicos:

FunciónComportamiento en caso de error
NewEnforcer()Devuelve un error
LoadModel()Devuelve un error
LoadPolicy()Devuelve un error
SavePolicy()Devuelve un error
Enforce()Devuelve un error
nota

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")