본문으로 건너뛰기

로깅 및 오류 처리

로깅​

Casbin은 요청, 모델 로딩 및 정책 변경 사항을 기록할 수 있습니다. 로깅은 기본적으로 비활성화되어 있습니다. Enforcer.EnableLog() 또는 NewEnforcer()의 logger 매개변수를 통해 활성화하세요. 출력 예시:

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

Go: 사용자 정의 로거를 연결할 수 있습니다. Casbin은 이를 통해 모델, 요청, 역할 및 정책을 기록합니다.

노트

Python: PyCasbin은 표준 logging 모듈을 사용합니다. 앱의 로깅을 평소처럼 설정하면 됩니다. PyCasbin은 logging.getLogger()를 사용합니다. 선택 사항인 logging_config는 pycasbin/util/log.py에 문서화되어 있습니다. 설정 방법은 Python logging 및 Django logging을 참조하세요.

다양한 Enforcers용 별도 로거 구성​

각 enforcer는 자체 로거를 가질 수 있으며, 런타임에 로거를 변경할 수 있습니다.

NewEnforcer()의 마지막 매개변수를 사용하여 로거를 지정할 수 있습니다. 이 방법을 사용할 때 로거의 enabled 필드가 enforcer의 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)

지원되는 로거​

Casbin은 여러 로거 구현체를 제공합니다:

로거작성자설명
기본 로거 (내장)CasbinGo의 표준 log 패키지를 사용하는 기본 로거입니다.
Zap 로거CasbinJSON 인코딩 로그와 zap-logger를 통한 추가 사용자 정의 옵션을 위해 zap을 사용합니다.

사용자 정의 로거 구현​

사용자 정의 로거는 Logger 인터페이스를 구현해야 합니다.

메서드유형설명
EnableLog()필수메시지 출력을 제어합니다.
IsEnabled()필수현재 로거의 활성화 상태를 반환합니다.
LogModel()필수모델 관련 정보를 기록합니다.
LogEnforce()필수인가 관련 정보를 기록합니다.
LogRole()필수역할 관련 정보를 기록합니다.
LogPolicy()필수정책 관련 정보를 기록합니다.

사용자 정의 로거를 Enforcer.SetLogger()에 전달하세요.

사용자 정의 로거 구현을 위한 Go 예제입니다:

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가지 주요 함수는 오류(error) 또는 패닉(panic)을 발생시킬 수 있습니다:

FunctionBehavior on Error
NewEnforcer()Returns an error
LoadModel()Returns an error
LoadPolicy()Returns an error
SavePolicy()Returns an error
Enforce()Returns an error
노트

NewEnforcer()는 내부적으로 LoadModel()과 LoadPolicy()를 모두 호출하므로, NewEnforcer()를 사용할 때 이들을 별도로 호출할 필요가 없습니다.

강제 적용 활성화 및 비활성화​

Enforcer.EnableEnforce()를 사용하여 enforcer를 비활성화할 수 있습니다. 비활성화된 상태에서는 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")

Comments are powered by giscus and GitHub Discussions. They load from giscus.app and GitHub only after you click the button below.