メインコンテンツにスキップ

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()の最後のパラメータを通じて適切なロガーを使用することができます。 この方法を使用してエンフォーサーを初期化している場合、ロガーのenabledフィールドの優先度が高いため、enabledパラメータを使用する必要はありません。

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

サポートされているロガー

情報をログに記録するためのいくつかのロガーを提供しています。

ロガー著者説明
デフォルトのロガー(組み込み)Casbingolangのlogを使用したデフォルトのロガー。
ZapロガーCasbinzapを使用し、jsonエンコードされたログを提供し、独自のzap-loggerでさらにカスタマイズすることができます。

ロガーの書き方

あなたのロガーはLoggerインターフェースを実装するべきです。

メソッドタイプ説明
EnableLog()必須メッセージを印刷するかどうかを制御します。
IsEnabled()必須現在のロガーの有効状態を表示します。
LogModel()必須モデルに関連する情報をログに記録します。
LogEnforce()必須強制に関連する情報をログに記録します。
LogRole()必須ロールに関連する情報をログに記録します。
LogPolicy()必須ポリシーに関連する情報をログに記録します。

あなたのカスタムloggerEnforcer.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のバグ。

エラーやパニックについては、以下の5つの主要な関数を認識しておく必要があります:

関数エラー時の動作
NewEnforcer()エラーを返します
LoadModel()エラーを返します
LoadPolicy()エラーを返します
SavePolicy()エラーを返します
Enforce()エラーを返します
メモ

NewEnforcer()は内部でLoadModel()LoadPolicy()を呼び出します。 したがって、NewEnforcer()を使用するときには後者の2つを呼び出す必要はありません。

有効と無効

エンフォーサーは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")