التخطي إلى المحتوى الرئيسي

Log & Error Handling

التسجيل

Casbin يستخدم الأمر المدمج log لطباعة السجلات إلى وحدة التحكم بشكل افتراضي، مثل:

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

التسجيل غير مفعل بشكل افتراضي. يمكنك تبديل ذلك عبر Enforcer.EnableLog() أو الوسيط الأخير لـ NewEnforcer().

ملاحظة

لقد قمنا بدعم التسجيل للنموذج، طلب التنفيذ، الدور، والسياسة في Golang. يمكنك تعريف سجل خاص بك لتسجيل الدخول لـ Casbin. إذا كنت تستخدم Python، يستخدم pycasbin آلية التسجيل الافتراضية في Python. يقوم حزمة pycasbin بالاتصال بـ logging.getLogger() لضبط المسجل. لا حاجة لتكوين خاص للتسجيل غير تهيئة المسجل في التطبيق الأصل. إذا لم يتم تهيئة التسجيل داخل التطبيق الأصل، فلن ترى أي رسائل سجل من pycasbin. في الوقت نفسه، عند تفعيل السجل في pycasbin، سيستخدم تكوين السجل الافتراضي. بالنسبة لامتدادات pycasbin الأخرى، يمكنك الرجوع إلى وثائق تسجيل Django إذا كنت مستخدم Django. بالنسبة لمستخدمي Python الآخرين، يجب الرجوع إلى وثائق تسجيل Python لضبط المسجل.

استخدام مسجلات مختلفة لمنفذين مختلفين

يمكن لكل منفذ أن يمتلك مسجله الخاص لتسجيل المعلومات، ويمكن تغييره أثناء التشغيل.

ويمكنك استخدام مسجل مناسب عبر الوسيط الأخير لـ NewEnforcer(). إذا كنت تستخدم هذه الطريقة لتهيئة منفذك، لا تحتاج إلى استخدام الوسيط المفعل لأن أولوية حقل المفعل في المسجل أعلى.

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

المسجلات المدعومة

نحن نوفر بعض المسجلات لمساعدتك على تسجيل المعلومات.

المسجلالمؤلفالوصف
المسجل الافتراضي (مدمج)Casbinالمسجل الافتراضي باستخدام سجل golang.
مسجل ZapCasbinباستخدام zap، يوفر سجل مشفر بصيغة json ويمكنك تخصيص المزيد مع مسجل zap الخاص بك.

كيفية كتابة مسجل

يجب أن ينفذ مسجلك واجهة Logger.

الطريقةالنوعالوصف
EnableLog()إلزاميالتحكم في ما إذا كان سيتم طباعة الرسالة.
IsEnabled()إلزامييعرض حالة تفعيل المسجل الحالي.
LogModel()إلزاميتسجيل المعلومات المتعلقة بالنموذج.
LogEnforce()إلزاميسجل المعلومات المتعلقة بالتنفيذ.
LogRole()إلزاميسجل المعلومات المتعلقة بالدور.
LogPolicy()إلزاميسجل المعلومات المتعلقة بالسياسة.

يمكنك تمرير logger مخصص إلى Enforcer.SetLogger().

إليك مثال على كيفية تخصيص مسجل للغة 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)
}

معالجة الأخطاء

قد تحدث أخطاء أو انهيارات عند استخدام Casbin لأسباب مثل:

  1. صياغة غير صحيحة في ملف النموذج (.conf).
  2. صياغة غير صحيحة في ملف السياسة (.csv).
  3. أخطاء مخصصة من محولات التخزين، مثل فشل MySQL في الاتصال.
  4. خطأ في Casbin.

هناك خمس وظائف رئيسية قد تحتاج إلى الانتباه إليها للأخطاء أو الانهيارات:

وظيفةالسلوك عند حدوث خطأ
NewEnforcer()يعيد خطأ
LoadModel()يعيد خطأ
LoadPolicy()يعيد خطأ
SavePolicy()يعيد خطأ
Enforce()يعيد خطأ
ملاحظة

NewEnforcer() يستدعي LoadModel() و LoadPolicy() داخليًا. لذا لا تحتاج إلى استدعاء الاثنين الأخيرين عند استخدام NewEnforcer().

تمكين وتعطيل

يمكن تعطيل المنفذ عبر وظيفة Enforcer.EnableEnforce(). عند تعطيله، سيعيد Enforcer.Enforce() دائمًا true. العمليات الأخرى مثل إضافة أو إزالة السياسات لا تتأثر. إليك مثال:

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