Logging Control

Overview

peer 응용 프로그램 및 shim 인터페이스에서 체인 코드 로깅은 github.com/op/go-logging 패키지에서 제공하는 기능을 사용하여 프로그래밍 됩니다. 이 패키지는

  • 메시지의 심각도를 기반으로 로깅 제어
  • 메시지를 생성하는 소프트웨어 모듈을 기반으로 한 로깅 제어
  • 메시지의 심각도를 기반으로 한 다양한 pretty-printing 옵션

모든 로그는 현재 stderr로 이동되며 pretty-printing은 현재 수정되었습니다. 그러나 심각도 별 로깅의 전역 및 모듈 수준 제어는 사용자와 개발자 모두에게 제공됩니다. 현재 각 심각도 수준에서 제공되는 정보 유형에 대한 형식화 된 규칙은 없지만 버그 보고서를 제출할 때 개발자는 전체 로그를 DEBUG 수준으로 보고 싶어 할 수 있습니다.

pretty-printing 로그에서 로깅 수준은 색상과 4 자리 코드로 표시됩니다 (예 : ERROR에 ERRO, DEBU에 DEBUG 등). 로깅 컨텍스트에서 모듈 은 임의의 이름 (문자열)입니다. 개발자가 관련 메시지 그룹에 제공합니다. 아래의 예에서, "peer", "rest"및 "main"로깅 모듈은 로그를 생성합니다.

16:47:09.634 [peer] GetLocalAddress -> INFO 033 Auto detected peer address: 9.3.158.178:7051
16:47:09.635 [rest] StartOpenchainRESTServer -> INFO 035 Initializing the REST service...
16:47:09.635 [main] serve -> INFO 036 Starting peer with id=name:"vp1" , network id=dev, address=9.3.158.178:7051, discovery.rootnode=, validator=true

런타임에 임의의 수의 로깅 모듈을 생성할 수 있으므로 모듈의 "마스터 목록"이 없고 로깅 제어 구조가 로깅 모듈이 실제로 존재하는지 또는 존재하는지 여부를 확인할 수 없습니다. 또한 로깅 모듈 시스템은 계층 구조 또는 와일드 카드를 이해하지 못합니다. 코드에서 "foo/bar"와 같은 모듈 이름을 볼 수 있지만 로깅 시스템은 플랫 문자열만 볼 수 있습니다. "foo/bar"는 어떤 식 으로든 "foo"와 관련이 있거나 "foo/*"가 foo의 모든 "하위 모듈"을 나타낼 수 있다는 것을 이해하지 못합니다.

peer

peer 명령의 로깅 수준은 --logging-level 플래그를 사용하여 각 호출에 대해 명령 줄에서 제어 할 수 있습니다 ( 예 :

peer node start --logging-level=debug

각 개별 peer 하위 명령의 기본 로깅 레벨은 core.yaml 파일에서 설정할 수도 있습니다. 예를 들어, 키 logging.node는 node 서브 커맨드의 기본 레벨을 설정합니다. 이 파일의 주석은 환경 변수를 사용하여 다양한 방법으로 로깅 수준을 재정의하는 방법을 설명합니다.

로깅 심각도 수준은 다음에서 선택된 대/소문자를 구분하지 않는 문자열을 사용하여 지정됩니다.

CRITICAL | ERROR | WARNING | NOTICE | INFO | DEBUG

peer의 전체 로깅 수준 사양은 다음과 같습니다.

[<module>[,<module>...]=]<level>[:[<module>[,<module>...]=]<level>...]

로깅 레벨 자체가 전체 기본값으로 간주됩니다. 그렇지 않으면 모듈의 개별 또는 그룹에 대한 재정의는 다음을 사용하여 지정할 수 있습니다.

<module>[,<module>...]=<level>

구문. 사양 예 ( --logging-level, 환경 변수 및 core.yaml 설정 모두에 유효 ) :

info                                       - Set default to INFO
warning:main,db=debug:chaincode=info       - Default WARNING; Override for main,db,chaincode
chaincode=info:main=debug:db=debug:warning - Same as above

Go chaincodes

체인 코드 애플리케이션 내에서 로그하는 표준 메커니즘은 피어를 통해 각 체인 코드 인스턴스에 노출된 로깅 전송과 통합하는 것입니다. chaincode shim 패키지는 체인 코드가 로그를 형식화하고 shim 로그와 일관되게 인터리브되는 로깅 객체를 생성하고 관리할 수 있게 해주는 API를 제공합니다.

독자적으로 실행되는 프로그램처럼, 사용자 제공 체인 코드는 기술적으로 stdout/stderr에 출력을 생성할 수도 있습니다. 자연적으로 "devmode"에 유용하지만 일반적으로 프로덕션 네트워크에서는 이러한 채널이 손상되어 악성 코드의 악용을 방지합니다. 그러나 CORE_VM_DOCKER_ATTACHSTDOUT = true 구성 옵션을 통해 피어가 관리하는 컨테이너 (예 : "netmode")의 경우에도 이 출력을 피어 단위로 활성화 할 수 있습니다.

일단 활성화되면, 각 체인 코드는 해당 컨테이너 ID에 의해 자체 로깅 채널을 수신하게됩니다. stdout 또는 stderr에 기록된 출력은 각 행별로 피어의 로그와 통합됩니다. 프로덕션 환경에서 이를 활성화하는 것은 권장되지 않습니다.

API

NewLogger(name string) *ChaincodeLogger - 체인 코드에서 사용할 로깅 개체 만들기 (c *ChaincodeLogger) SetLevel(level LoggingLevel) - 로거의 로깅 수준 설정

(c *ChaincodeLogger) IsEnabledFor(level LoggingLevel) bool - 지정된 레벨에서 로그가 생성되면 true를 반환합니다.

LogLevel(levelString string) (LoggingLevel, error) - 문자열을 LoggingLevel로 변환하십시오.

LoggingLevel은 열거 형의 멤버입니다.

LogDebug, LogInfo, LogNotice, LogWarning, LogError, LogCritical

대/소문자를 구별하지 않는 버전의 문자열을 전달하여 직접 사용할 수 있습니다.

DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL

LogLevel API.

다양한 심각도 수준의 형식화 된 로깅은 함수에 의해 제공됩니다.

(c *ChaincodeLogger) Debug(args ...interface{})
(c *ChaincodeLogger) Info(args ...interface{})
(c *ChaincodeLogger) Notice(args ...interface{})
(c *ChaincodeLogger) Warning(args ...interface{})
(c *ChaincodeLogger) Error(args ...interface{})
(c *ChaincodeLogger) Critical(args ...interface{})

(c *ChaincodeLogger) Debugf(format string, args ...interface{})
(c *ChaincodeLogger) Infof(format string, args ...interface{})
(c *ChaincodeLogger) Noticef(format string, args ...interface{})
(c *ChaincodeLogger) Warningf(format string, args ...interface{})
(c *ChaincodeLogger) Errorf(format string, args ...interface{})
(c *ChaincodeLogger) Criticalf(format string, args ...interface{})

f 형식의 로깅 API는 로그의 형식을 정확하게 제어합니다. 비 f 형식의 API는 현재 인수의 출력 표현 사이에 공백을 삽입하고 임의로 사용할 형식을 선택합니다.

현재 구현에서 shim 및 ChaincodeLogger에 의해 생성된 로그에는 타임 스탬프가 지정 되고 로거 이름 및 심각도 수준이 표시되며 stderr에 기록됩니다. 로깅 레벨 컨트롤은 현재 ChaincodeLogger가 생성 될 때 제공된 이름을 기반으로 합니다. 모호함을 피하기 위해 모든 ChaincodeLogger에는 "shim" 이외의 고유한 이름을 지정 해야합니다. 로거 이름 은 로거에 의해 작성된 모든 로그 메시지에 나타납니다. shim은 "심"으로 기록됩니다.

Go 언어 체인 코드는 SetLoggingLevel API를 통해 체인 코드 shim 인터페이스의 로깅 수준을 제어 할 수도 있습니다.

SetLoggingLevel(LoggingLevel level) - 심의 로깅 수준 제어

shim의 기본 로깅 수준은 LogDebug 입니다.

다음은 체인 코드가 LogInfo 레벨에서 로깅하는 개인 로깅 오브젝트를 작성하는 방법과 환경 변수를 기반으로 shim이 제공하는 로깅의 양을 제어 하는 간단한 예제입니다.

var logger = shim.NewLogger("myChaincode")

func main() {

    logger.SetLevel(shim.LogInfo)

    logLevel, _ := shim.LogLevel(os.Getenv("SHIM_LOGGING_LEVEL"))
    shim.SetLoggingLevel(logLevel)
    ...
}


출처 : http://hyperledger-fabric.readthedocs.io/en/release-1.1/logging-control.html

 Error handling

General Overview

Hyperledger 패브릭 코드는 Go에서 제공하는 표준 오류 유형 대신 판매된 패키지 github.com/pkg/errors 를 사용해야합니다. 이 패키지는 오류 메시지가 있는 스택 추적을 쉽게 생성하고 표시 할 수 있습니다.

Usage Instructions

fmt.Errorf() 또는 errors.New()에 대한 모든 호출 대신 github.com/pkg/errors를 사용해야합니다. 이 패키지를 사용하면 오류 메시지에 추가될 호출 스택이 생성됩니다.

이 패키지를 사용하는 것은 간단하며 코드를 쉽게 조정할 수 있습니다.

먼저 github.com/pkg/errors를 가져와야 합니다.

그런 다음 오류 생성 함수 (errors.New (), errors.Errorf (), errors.WithMessage (), errors.Wrap (), errors.Wrapf () 중 하나를 사용하도록 코드에서 생성된 모든 오류를 업데이트하십시오.

Note! 사용 가능한 오류 생성 기능에 대한 자세한 내용은 https://godoc.org/github.com/pkg/errors를 참조 하십시오. 또한 패브릭 코드에 패키지를 사용하기 위한 구체적인 지침은 아래의 일반 지침 섹션을 참조하십시오.

마지막으로, 로거 또는 fmt.Printf() 호출에 대한 형식 지시자를 %s에서 %+v로 변경하여 호출 스택을 오류 메시지와 함께 출력하십시오.

General guidelines for error handling in Hyperledger Fabric

  • 사용자 요청을 처리하는 중이라면 오류를 기록한 다음 반환해야합니다.
  • Go 라이브러리 나 판매자 패키지와 같은 외부 소스에서 오류가 발생하면 errors.Wrap()을 사용하여 오류를 래핑하여 오류에 대한 호출 스택을 생성하십시오.
  • 다른 패브릭 함수에서 오류가 발생하면 호출 스택을 영향을받지 않고 errors.WithMessage()를 사용하여 오류 메시지에 추가 컨텍스트를 추가하십시오.
  • 패닉이 다른 패키지로 퍼지면 안됩니다.

Example program

다음 예제 프로그램은 패키지 사용에 대한 명확한 데모를 제공합니다.

package main import ( "fmt" "github.com/pkg/errors" ) func wrapWithStack() error { err := createError() // do this when error comes from external source (go lib or vendor) return errors.Wrap(err, "wrapping an error with stack") } func wrapWithoutStack() error { err := createError() // do this when error comes from internal Fabric since it already has stack trace return errors.WithMessage(err, "wrapping an error without stack") } func createError() error { return errors.New("original error") } func main() { err := createError() fmt.Printf("print error without stack: %s\n\n", err) fmt.Printf("print error with stack: %+v\n\n", err) err = wrapWithoutStack() fmt.Printf("%+v\n\n", err) err = wrapWithStack() fmt.Printf("%+v\n\n", err) }


출처 : http://hyperledger-fabric.readthedocs.io/en/release-1.1/error-handling.html

Endorsement Policy내용

https://stackoverflow.com/questions/48108709/what-are-members-and-admins-in-endorsement-policy-of-hyperledger-fabric

Endorsement policies

Endorsement Policy은 트랜잭션이 적절하게 보증되는지 여부를 결정하는 방법을 피어에게 지시하는 데 사용됩니다. 피어가 트랜잭션을 수신하면 트랜잭션 유효성 검증 플로우의 일부로 트랜잭션의 체인 코드와 연관된 VSCC (유효성 검증 시스템 체인 코드)를 호출하여 트랜잭션의 유효성을 판별합니다. 보증(endorsing)이 많은 피어로부터 하나 이상의 보증(endorsement)을 포함한다는 것을 상기하십시오. VSCC는 다음 결정을 내려야합니다 :

  • 모든 보증은 유효합니다 (즉, 예상 메시지에 대한 유효한 인증서의 유효한 서명입니다)
  • 적절한 수의 보증이 있다.
  • 보증은 예상된 소스에서 나온 것입니다.

Endorsement Policy은 두 번째 및 세 번째 점을 지정하는 방법입니다.

Endorsement policy syntax in the CLI

CLI에서는 간단한 언어를 사용하여 원칙에 대한 부울 표현에 대한 정책을 표현합니다.

principal은 서명자의 신원을 확인하고 서명자가 해당 MSP 내에서 갖는 역할을 확인하는 임무를 맡은 MSP의 관점에서 설명합니다. 구성원(member) , 관리자(admin) , 클라이언트(client) 및 피어(peer)의 네 가지 역할이 지원됩니다 . principal은 MSPROLE로 설명됩니다. 여기서 MSP는 필수 MSP의 ID이며, ROLEmemberadminclient및 peer의 네 개의 문자열 중 하나입니다. 유효한 주체의 예로는 'Org0.admin'Org0 MSP의 모든 관리자 ) 또는 'Org1.member'Org1 MSP의 모든 구성원), 'Org1.client'Org1 MSP 클라이언트 ) 및 'Org1.peer'Org1 MSP의 피어 )입니다.

언어 구문은 다음과 같습니다. :

EXPR(E[, E...])

여기에서 EXPR은 두 개의 부울 표현식을 나타내는 AND 또는 OR이고 E는 principal(위에 설명 된 구문을 사용하는) 이거나 EXPR에 대한 다른 중첩 호출입니다.

예 :
  • AND('Org1.member', 'Org2.member', 'Org3.member')는 3 명의 주체(principal) 각자에게서 1 개의 서명을 요구한다.
  • OR('Org1.member', 'Org2.member')은 두 명의 주체(principal) 중 한 명에게 1 개의 서명을 요구한다.
  • OR('Org1.member', AND('Org2.member', 'Org3.member'))Org1 MSP의 멤버로부터 하나의 서명 또는, Org2 MSP의 멤버로부터 하나의 서명을, 그리고 Org3 MSP의 멤버로부터 하나의 서명을 요청합니다.

Specifying endorsement policies for a chaincode

체인 코드 배포자는 이 언어를 사용하여 지정된 정책에 대해 체인 코드의 인증을 확인하도록 요청할 수 있습니다.

Note! 인스턴스 생성시 지정되지 않은 경우 Endorsement Policy은 기본적으로 "채널에 있는 조직의 모든(any) 구성원"으로 지정됩니다. 예를 들어 'Org1' 및 'Org2'가 포함된 채널의 기본 Endorsement Policy은 'OR ('Org1.member ','Org2.member ')입니다.

-P 스위치를 사용하여 인스턴스를 생성 할 때 정책을 지정할 수 있으며 그 뒤에 정책이 옵니다.

 :

peer chaincode instantiate -C <channelid> -n mycc -P "AND('Org1.member', 'Org2.member')"

이 명령은 Org1 및 Org2 구성원이 트랜잭션에 서명해야하는 AND('Org1.member', 'Org2.member') 정책으로 chaincode mycc를 배포 합니다.

ID 분류가 활성화된 경우(Membership Service Providers (MSP) 참조) PEER 역할을 사용하여 peers에게만 보증을 제한할 수 있습니다.

 :

peer chaincode instantiate -C <channelid> -n mycc -P "AND('Org1.peer', 'Org2.peer')"

Note! 인스턴스 생성 후 채널에 추가된 새 조직은 체인 코드를 쿼리할 수 ​​있지만 (쿼리에 채널 정책 및 체인 코드에 의해 적용되는 모든 응용 프로그램 수준 검사가 정의한 적절한 권한을 가지고 있음에도 불구하고 체인 코드로 승인된 트랜잭션을 커밋 할 수는 없습니다). 새로운 조직의 보증을 통해 트랜잭션을 커밋 할 수 있도록 Endorsement Policy을 수정해야합니다(Upgrade and Invoke Chaincode 참조).


출처 : http://hyperledger-fabric.readthedocs.io/en/release-1.1/endorsement-policies.html

+ Recent posts