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)
지원되는 로거들
우리는 정보를 로그에 기록하는 데 도움이 될 몇 가지 로거를 제공합니다.
- Go
- PHP
로거 | 저자 | 설명 |
---|---|---|
기본 로거 (내장) | Casbin | golang 로그를 사용하는 기본 로거입니다. |
Zap 로거 | Casbin | zap를 사용하여 json 인코딩 로그를 제공하며, 자신만의 zap-logger로 더 많은 것을 사용자 정의할 수 있습니다. |
로거 | 저자 | 설명 |
---|---|---|
psr3-bridge logger | Casbin | PSR-3 호환 브리지를 제공합니다. |
로거 작성 방법
로거는 Logger 인터페이스를 구현해야 합니다.
방법 | 유형 | 설명 |
---|---|---|
EnableLog() | 필수 | 메시지를 출력할지 여부를 제어합니다. |
IsEnabled() | 필수 | 현재 로거의 활성화 상태를 표시합니다. |
LogModel() | 필수 | 모델과 관련된 로그 정보. |
LogEnforce() | 필수 | 강제 실행과 관련된 로그 정보. |
LogRole() | 필수 | 역할과 관련된 로그 정보. |
LogPolicy() | 필수 | 정책과 관련된 로그 정보. |
Enforcer.SetLogger()
에 사용자 정의 logger
를 전달할 수 있습니다.
다음은 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을 사용할 때 오류 또는 패닉이 발생할 수 있습니다:
- 모델 파일 (.conf)의 구문이 잘못되었습니다.
- 정책 파일 (.csv)의 구문이 잘못되었습니다.
- 저장소 어댑터에서의 사용자 정의 오류, 예를 들어, MySQL이 연결에 실패한 경우.
- 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")