Vai al contenuto principale

Log & Error Handling

Registrazione

Casbin utilizza il log incorporato per stampare i log sulla console per impostazione predefinita, come:

2017/07/15 19:43:56 [Request: alice, data1, read ---> true]

La registrazione non è abilitata per impostazione predefinita. Puoi attivarla o disattivarla tramite Enforcer.EnableLog() o l'ultimo parametro di NewEnforcer().

nota

Supportiamo già la registrazione del modello, della richiesta di applicazione, del ruolo e dei criteri in Golang. Puoi definire il tuo log personalizzato per registrare Casbin. Se stai utilizzando Python, pycasbin sfrutta il meccanismo di logging predefinito di Python. Il pacchetto pycasbin effettua una chiamata a logging.getLogger() per impostare il logger. Non è necessaria alcuna configurazione speciale del logging oltre all'inizializzazione del logger nell'applicazione principale. Se non viene inizializzato alcun logging all'interno dell'applicazione principale, non vedrai alcun messaggio di log da pycasbin. Allo stesso tempo, quando abiliti il log in pycasbin, utilizzerà la configurazione predefinita del log. Per altre estensioni di pycasbin, puoi fare riferimento alla documentazione sul logging di Django se sei un utente di Django. Per altri utenti Python, dovresti fare riferimento alla documentazione sul logging di Python per configurare il logger.

Utilizza diversi logger per diversi enforcer

Ogni enforcer può avere il proprio logger per registrare informazioni e può essere modificato a runtime.

E puoi utilizzare un logger appropriato tramite l'ultimo parametro di NewEnforcer(). Se stai utilizzando questo modo per inizializzare il tuo enforcer, non è necessario utilizzare il parametro abilitato perché la priorità del campo abilitato nel logger è più 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)

Logger supportati

Forniamo alcuni logger per aiutarti a registrare le informazioni.

LoggerAutoreDescrizione
Logger predefinito (built-in)CasbinIl logger predefinito utilizzando il log di golang.
Zap loggerCasbinUtilizzando zap, fornisci log codificati in formato JSON e puoi personalizzare ulteriormente con il tuo zap-logger.

Come scrivere un logger

Il tuo logger deve implementare l'interfaccia Logger.

MetodoTipoDescrizione
EnableLog()obbligatorioControlla se stampare il messaggio.
IsEnabled()obbligatorioMostra lo stato attuale di abilitazione del logger.
LogModel()obbligatorioRegistra informazioni relative al modello.
LogEnforce()obbligatorioRegistra informazioni relative all'applicazione.
LogRole()obbligatorioRegistra informazioni relative al ruolo.
LogPolicy()obbligatorioRegistra informazioni relative alla politica.

Puoi passare il tuo logger personalizzato a Enforcer.SetLogger().

Ecco un esempio di come personalizzare un logger per 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)
}

Gestione degli errori

Possono verificarsi errori o panici quando si utilizza Casbin per motivi come:

  1. Sintassi non valida nel file del modello (.conf).
  2. Sintassi non valida nel file della politica (.csv).
  3. Errori personalizzati dai adattatori di storage, ad esempio, la connessione a MySQL non riesce.
  4. Bug di Casbin.

Ci sono cinque funzioni principali di cui potresti aver bisogno di essere a conoscenza per errori o panico:

FunzioneComportamento in caso di errore
NewEnforcer()Restituisce un errore
LoadModel()Restituisce un errore
LoadPolicy()Restituisce un errore
SavePolicy()Restituisce un errore
Enforce()Restituisce un errore
nota

NewEnforcer() chiama internamente LoadModel() e LoadPolicy(). Quindi non è necessario chiamare questi ultimi due quando si utilizza NewEnforcer().

Abilitare e disabilitare

L'enforcer può essere disabilitato tramite la funzione Enforcer.EnableEnforce(). Quando è disabilitato, Enforcer.Enforce() restituirà sempre true. Altre operazioni come l'aggiunta o la rimozione di policy non sono influenzate. Ecco un esempio:

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