Zum Hauptinhalt springen

Log & Error Handling

Protokollierung

Casbin verwendet standardmäßig das eingebaute log, um Protokolle auf der Konsole auszugeben, wie:

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

Die Protokollierung ist standardmäßig nicht aktiviert. Sie können es über Enforcer.EnableLog() oder den letzten Parameter von NewEnforcer() umschalten.

notiz

Wir unterstützen bereits die Protokollierung des Modells, der Durchsetzungsanforderung, der Rolle und der Richtlinie in Golang. Sie können Ihr eigenes Protokoll für die Protokollierung von Casbin definieren. Wenn Sie Python verwenden, nutzt pycasbin den standardmäßigen Python-Protokollierungsmechanismus. Das pycasbin-Paket ruft logging.getLogger() auf, um den Logger zu setzen. Es ist keine spezielle Protokollierungskonfiguration erforderlich, außer der Initialisierung des Loggers in der übergeordneten Anwendung. Wenn in der übergeordneten Anwendung keine Protokollierung initialisiert wird, sehen Sie keine Protokollnachrichten von pycasbin. Gleichzeitig, wenn Sie das Protokoll in pycasbin aktivieren, wird es die Standardprotokollkonfiguration verwenden. Für andere pycasbin-Erweiterungen können Sie sich auf die Django-Protokollierungsdokumentation beziehen, wenn Sie ein Django-Benutzer sind. Für andere Python-Benutzer sollten Sie sich auf die Python-Protokollierungsdokumentation beziehen, um den Logger zu konfigurieren.

Verwenden Sie verschiedene Logger für verschiedene Durchsetzer

Jeder Durchsetzer kann seinen eigenen Logger haben, um Informationen zu protokollieren, und er kann zur Laufzeit geändert werden.

Und Sie können einen geeigneten Logger über den letzten Parameter von NewEnforcer() verwenden. Wenn Sie auf diese Weise Ihren Durchsetzer initialisieren, müssen Sie den aktivierten Parameter nicht verwenden, da die Priorität des aktivierten Feldes im Logger höher ist.

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

Unterstützte Logger

Wir bieten einige Logger an, um Ihnen bei der Protokollierung von Informationen zu helfen.

LoggerAutorBeschreibung
Standard-Logger (eingebaut)CasbinDer Standard-Logger verwendet Golang-Log.
Zap-LoggerCasbinVerwendet zap, bietet json-kodierten Log und Sie können mehr mit Ihrem eigenen Zap-Logger anpassen.

Wie man einen Logger schreibt

Ihr Logger sollte das Logger Interface implementieren.

MethodeTypBeschreibung
EnableLog()obligatorischSteuern Sie, ob die Nachricht gedruckt werden soll.
IsEnabled()obligatorischZeigen Sie den aktuellen aktivierten Status des Loggers an.
LogModel()obligatorischProtokollieren Sie Informationen, die sich auf das Modell beziehen.
LogEnforce()obligatorischProtokollieren Sie Informationen, die sich auf die Durchsetzung beziehen.
LogRole()obligatorischProtokollieren Sie Informationen, die sich auf die Rolle beziehen.
LogPolicy()obligatorischProtokollieren Sie Informationen, die sich auf die Richtlinie beziehen.

Sie können Ihren benutzerdefinierten logger an Enforcer.SetLogger() übergeben.

Hier ist ein Beispiel, wie man einen Logger für Golang anpasst:

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

Fehlerbehandlung

Fehler oder Paniken können auftreten, wenn Sie Casbin aus Gründen wie folgenden verwenden:

  1. Ungültige Syntax in der Modell-Datei (.conf).
  2. Ungültige Syntax in der Richtliniendatei (.csv).
  3. Benutzerdefinierte Fehler von Speicheradaptern, z.B., MySQL kann keine Verbindung herstellen.
  4. Casbins Fehler.

Es gibt fünf Hauptfunktionen, auf die Sie bei Fehlern oder Paniken aufmerksam sein sollten:

FunktionVerhalten bei Fehler
NewEnforcer()Gibt einen Fehler zurück
LoadModel()Gibt einen Fehler zurück
LoadPolicy()Gibt einen Fehler zurück
SavePolicy()Gibt einen Fehler zurück
Enforce()Gibt einen Fehler zurück
notiz

NewEnforcer() ruft intern LoadModel() und LoadPolicy() auf. Sie müssen also die beiden letzteren nicht aufrufen, wenn Sie NewEnforcer() verwenden.

Aktivieren und Deaktivieren

Der Durchsetzer kann über die Funktion Enforcer.EnableEnforce() deaktiviert werden. Wenn er deaktiviert ist, wird Enforcer.Enforce() immer true zurückgeben. Andere Operationen wie das Hinzufügen oder Entfernen von Richtlinien sind nicht betroffen. Hier ist ein Beispiel:

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