Skip to content

Commit e503a08

Browse files
author
Jason Yellick
committed
[FAB-5732] Improve policy logging
The policy ogs can be quite cryptic to the uninitiated. In particular, because one policy may invoke others, and a subset of the 'others' may fail benignly, the logs can look full of errors, even when there is nothing wrong. This CR tries to address this in two ways, first, by adding a message to the implicit meta policy evaluation warning that the errors may be benign. Secondly, by adding a policy logger wrapper around policies, which indicate the fully qualified path of the policy being evaluated. And finally, the implicit meta policies are enhanced to say which policies were evaluated when there are not enough sub-policies which evaluate successfully. Change-Id: I032ef0d8e0a0d85f574ab313f0137cb4c6556d4a Signed-off-by: Jason Yellick <jyellick@us.ibm.com>
1 parent f3600cc commit e503a08

File tree

2 files changed

+58
-19
lines changed

2 files changed

+58
-19
lines changed

common/policies/implicitmeta.go

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,28 @@
11
/*
2-
Copyright IBM Corp. 2016 All Rights Reserved.
2+
Copyright IBM Corp. All Rights Reserved.
33
4-
Licensed under the Apache License, Version 2.0 (the "License");
5-
you may not use this file except in compliance with the License.
6-
You may obtain a copy of the License at
7-
8-
http://www.apache.org/licenses/LICENSE-2.0
9-
10-
Unless required by applicable law or agreed to in writing, software
11-
distributed under the License is distributed on an "AS IS" BASIS,
12-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
See the License for the specific language governing permissions and
14-
limitations under the License.
4+
SPDX-License-Identifier: Apache-2.0
155
*/
166

177
package policies
188

199
import (
10+
"bytes"
2011
"fmt"
2112

2213
cb "github.com/hyperledger/fabric/protos/common"
2314

2415
"github.com/golang/protobuf/proto"
16+
"github.com/op/go-logging"
2517
)
2618

2719
type implicitMetaPolicy struct {
2820
threshold int
2921
subPolicies []Policy
22+
23+
// Only used for logging
24+
managers map[string]*ManagerImpl
25+
subPolicyName string
3026
}
3127

3228
// NewPolicy creates a new policy based on the policy bytes
@@ -61,14 +57,36 @@ func newImplicitMetaPolicy(data []byte, managers map[string]*ManagerImpl) (*impl
6157
}
6258

6359
return &implicitMetaPolicy{
64-
subPolicies: subPolicies,
65-
threshold: threshold,
60+
subPolicies: subPolicies,
61+
threshold: threshold,
62+
managers: managers,
63+
subPolicyName: definition.SubPolicy,
6664
}, nil
6765
}
6866

6967
// Evaluate takes a set of SignedData and evaluates whether this set of signatures satisfies the policy
7068
func (imp *implicitMetaPolicy) Evaluate(signatureSet []*cb.SignedData) error {
69+
logger.Debugf("This is an implicit meta policy, it will trigger other policy evaluations, whose failures may be benign")
7170
remaining := imp.threshold
71+
72+
defer func() {
73+
if remaining != 0 {
74+
// This log message may be large and expensive to construct, so worth checking the log level
75+
if logger.IsEnabledFor(logging.DEBUG) {
76+
var b bytes.Buffer
77+
b.WriteString(fmt.Sprintf("Evaluation Failed: Only %d policies were satisfied, but needed %d of [ ", remaining, imp.threshold))
78+
for m := range imp.managers {
79+
b.WriteString(m)
80+
b.WriteString(".")
81+
b.WriteString(imp.subPolicyName)
82+
b.WriteString(" ")
83+
}
84+
b.WriteString("]")
85+
logger.Debugf(b.String())
86+
}
87+
}
88+
}()
89+
7290
for _, policy := range imp.subPolicies {
7391
if policy.Evaluate(signatureSet) == nil {
7492
remaining--

common/policies/policy.go

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ func NewManagerImpl(path string, providers map[int32]Provider, root *cb.ConfigGr
155155
type rejectPolicy string
156156

157157
func (rp rejectPolicy) Evaluate(signedData []*cb.SignedData) error {
158-
return fmt.Errorf("No such policy type: %s", rp)
158+
return fmt.Errorf("No such policy: '%s'", rp)
159159
}
160160

161161
// Manager returns the sub-policy manager for a given path and whether it exists
@@ -176,6 +176,26 @@ func (pm *ManagerImpl) Manager(path []string) (Manager, bool) {
176176
return m.Manager(path[1:])
177177
}
178178

179+
type policyLogger struct {
180+
policy Policy
181+
policyName string
182+
}
183+
184+
func (pl *policyLogger) Evaluate(signatureSet []*cb.SignedData) error {
185+
if logger.IsEnabledFor(logging.DEBUG) {
186+
logger.Debugf("== Evaluating %T Policy %s ==", pl.policy, pl.policyName)
187+
defer logger.Debugf("== Done Evaluating %T Policy %s", pl.policy, pl.policyName)
188+
}
189+
190+
err := pl.policy.Evaluate(signatureSet)
191+
if err != nil {
192+
logger.Debugf("Signature set did not satisfy policy %s", pl.policyName)
193+
} else {
194+
logger.Debugf("Signature set satisfies policy %s", pl.policyName)
195+
}
196+
return err
197+
}
198+
179199
// GetPolicy returns a policy and true if it was the policy requested, or false if it is the default reject policy
180200
func (pm *ManagerImpl) GetPolicy(id string) (Policy, bool) {
181201
if id == "" {
@@ -204,8 +224,9 @@ func (pm *ManagerImpl) GetPolicy(id string) (Policy, bool) {
204224
}
205225
return rejectPolicy(relpath), false
206226
}
207-
if logger.IsEnabledFor(logging.DEBUG) {
208-
logger.Debugf("Returning policy %s from manager %s for evaluation", relpath, pm.path)
209-
}
210-
return policy, true
227+
228+
return &policyLogger{
229+
policy: policy,
230+
policyName: PathSeparator + pm.path + PathSeparator + relpath,
231+
}, true
211232
}

0 commit comments

Comments
 (0)