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()
.
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.
- Go
- PHP
Logger | Autore | Descrizione |
---|---|---|
Logger predefinito (built-in) | Casbin | Il logger predefinito utilizzando il log di golang. |
Zap logger | Casbin | Utilizzando zap, fornisci log codificati in formato JSON e puoi personalizzare ulteriormente con il tuo zap-logger. |
Logger | Autore | Descrizione |
---|---|---|
psr3-bridge logger | Casbin | Fornisce una bridge conforme a PSR-3. |
Come scrivere un logger
Il tuo logger deve implementare l'interfaccia Logger.
Metodo | Tipo | Descrizione |
---|---|---|
EnableLog() | obbligatorio | Controlla se stampare il messaggio. |
IsEnabled() | obbligatorio | Mostra lo stato attuale di abilitazione del logger. |
LogModel() | obbligatorio | Registra informazioni relative al modello. |
LogEnforce() | obbligatorio | Registra informazioni relative all'applicazione. |
LogRole() | obbligatorio | Registra informazioni relative al ruolo. |
LogPolicy() | obbligatorio | Registra 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:
- Sintassi non valida nel file del modello (.conf).
- Sintassi non valida nel file della politica (.csv).
- Errori personalizzati dai adattatori di storage, ad esempio, la connessione a MySQL non riesce.
- Bug di Casbin.
Ci sono cinque funzioni principali di cui potresti aver bisogno di essere a conoscenza per errori o panico:
Funzione | Comportamento in caso di errore |
---|---|
NewEnforcer() | Restituisce un errore |
LoadModel() | Restituisce un errore |
LoadPolicy() | Restituisce un errore |
SavePolicy() | Restituisce un errore |
Enforce() | Restituisce un errore |
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")