Skip to content

Commit

Permalink
[FAB-12363] grpc server logging interceptors
Browse files Browse the repository at this point in the history
Change-Id: I868f1e13189168b7c91ff96238a9bdb1ffe7b6ba
Signed-off-by: Matthew Sykes <sykesmat@us.ibm.com>
  • Loading branch information
sykesm committed Oct 29, 2018
1 parent 179eb83 commit a5ff8e9
Show file tree
Hide file tree
Showing 23 changed files with 1,666 additions and 15 deletions.
1 change: 1 addition & 0 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 12 additions & 12 deletions Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
# SPDX-License-Identifier: Apache-2.0

required = [
"golang.org/x/lint/golint",
"golang.org/x/tools/cmd/goimports",
"github.com/golang/protobuf/protoc-gen-go",
"golang.org/x/lint/golint",
"golang.org/x/tools/cmd/goimports"
]

ignored = [
Expand Down Expand Up @@ -101,6 +101,10 @@ noverify = [
branch = "master"
name = "golang.org/x/crypto"

[[constraint]]
name = "golang.org/x/lint"
revision = "c67002cb31c3a748b7688c27f20d8358b4193582"

[[constraint]]
branch = "master"
name = "golang.org/x/net"
Expand All @@ -109,6 +113,10 @@ noverify = [
branch = "master"
name = "golang.org/x/sync"

[[constraint]]
name = "golang.org/x/tools"
revision = "f60e5f99f0816fc2d9ecb338008ea420248d2943"

[[constraint]]
name = "google.golang.org/grpc"
version = "=1.15.0"
Expand Down Expand Up @@ -154,12 +162,8 @@ noverify = [
version = "1.1.8"

[[constraint]]
name = "golang.org/x/lint"
revision = "c67002cb31c3a748b7688c27f20d8358b4193582"

[[constraint]]
name = "golang.org/x/tools"
revision = "f60e5f99f0816fc2d9ecb338008ea420248d2943"
name = "github.com/go-kit/kit"
version = "0.7.0"

[prune]
go-tests = true
Expand All @@ -177,7 +181,3 @@ noverify = [
[[prune.project]]
name = "github.com/coreos/etcd"
non-go = false

[[constraint]]
name = "github.com/go-kit/kit"
version = "0.7.0"
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ K := $(foreach exec,$(EXECUTABLES),\
$(if $(shell which $(exec)),some string,$(error "No $(exec) in PATH: Check dependencies")))

GOSHIM_DEPS = $(shell ./scripts/goListFiles.sh $(PKGNAME)/core/chaincode/shim)
PROTOS = $(shell git ls-files *.proto | grep -v vendor)
PROTOS = $(shell git ls-files *.proto | grep -Ev 'vendor/|testdata/')
# No sense rebuilding when non production code is changed
PROJECT_FILES = $(shell git ls-files | grep -v ^test | grep -v ^unit-test | \
grep -v ^.git | grep -v ^examples | grep -v ^devenv | grep -v .png$ | \
Expand Down
41 changes: 41 additions & 0 deletions common/grpclogging/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package grpclogging

import (
"context"

"go.uber.org/zap/zapcore"
)

type fieldKeyType struct{}

var fieldKey = &fieldKeyType{}

func ZapFields(ctx context.Context) []zapcore.Field {
fields, ok := ctx.Value(fieldKey).([]zapcore.Field)
if ok {
return fields
}
return nil
}

func Fields(ctx context.Context) []interface{} {
fields, ok := ctx.Value(fieldKey).([]zapcore.Field)
if !ok {
return nil
}
genericFields := make([]interface{}, len(fields))
for i := range fields {
genericFields[i] = fields[i]
}
return genericFields
}

func WithFields(ctx context.Context, fields []zapcore.Field) context.Context {
return context.WithValue(ctx, fieldKey, fields)
}
70 changes: 70 additions & 0 deletions common/grpclogging/context_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package grpclogging_test

import (
"context"
"time"

"github.com/hyperledger/fabric/common/grpclogging"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)

var _ = Describe("Context", func() {
var inputFields []zapcore.Field

BeforeEach(func() {
inputFields = []zapcore.Field{
zap.String("string-key", "string-value"),
zap.Duration("duration-key", time.Second),
zap.Int("int-key", 42),
}
})

It("decorates a context with fields", func() {
ctx := grpclogging.WithFields(context.Background(), inputFields)
Expect(ctx).NotTo(Equal(context.Background()))

fields := grpclogging.Fields(ctx)
Expect(fields).NotTo(BeEmpty())
})

It("extracts fields from a decorated context as a slice of zapcore.Field", func() {
ctx := grpclogging.WithFields(context.Background(), inputFields)

fields := grpclogging.Fields(ctx)
Expect(fields).To(ConsistOf(inputFields))
})

It("extracts fields from a decorated context as a slice of interface{}", func() {
ctx := grpclogging.WithFields(context.Background(), inputFields)

zapFields := grpclogging.ZapFields(ctx)
Expect(zapFields).To(Equal(inputFields))
})

It("returns the same fields regardless of type", func() {
ctx := grpclogging.WithFields(context.Background(), inputFields)

fields := grpclogging.Fields(ctx)
zapFields := grpclogging.ZapFields(ctx)
Expect(zapFields).To(ConsistOf(fields))
})

Context("when the context isn't decorated", func() {
It("returns no fields", func() {
fields := grpclogging.Fields(context.Background())
Expect(fields).To(BeNil())

zapFields := grpclogging.ZapFields(context.Background())
Expect(zapFields).To(BeNil())
})
})
})
165 changes: 165 additions & 0 deletions common/grpclogging/fakes/echo_service.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 34 additions & 0 deletions common/grpclogging/fields.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package grpclogging

import (
"github.com/gogo/protobuf/proto"
"github.com/golang/protobuf/jsonpb"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)

type protoMarshaler struct {
jsonpb.Marshaler
message proto.Message
}

func (m *protoMarshaler) MarshalJSON() ([]byte, error) {
out, err := m.Marshaler.MarshalToString(m.message)
if err != nil {
return nil, err
}
return []byte(out), nil
}

func ProtoMessage(key string, val interface{}) zapcore.Field {
if pm, ok := val.(proto.Message); ok {
return zap.Reflect(key, &protoMarshaler{message: pm})
}
return zap.Any(key, val)
}
Loading

0 comments on commit a5ff8e9

Please sign in to comment.