Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-pages.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Vosmaer <jacob@gitlab.com>2018-04-12 16:42:12 +0300
committerJacob Vosmaer <jacob@gitlab.com>2018-04-12 16:42:12 +0300
commit2195e6ca9544764cf0b64daafd11d591de1ae4ea (patch)
treebee50cc9d62936930584e81e74a2c20d007ae083 /vendor/github.com/grpc-ecosystem/go-grpc-middleware
parent1429da85cb13d6d2105b475dac600832d756affb (diff)
Add more gRPC dependencies
Diffstat (limited to 'vendor/github.com/grpc-ecosystem/go-grpc-middleware')
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/DOC.md166
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/Gopkg.lock123
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/Gopkg.toml35
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/LICENSE201
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/README.md86
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/DOC.md148
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/README.md148
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/auth.go67
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/doc.go20
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/metadata.go38
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/chain.go183
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/doc.go69
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/DOC.md91
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/README.md91
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/common.go35
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/doc.go35
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/DOC.md391
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/README.md391
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/client_interceptors.go65
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/context.go19
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus/DOC.md93
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus/README.md58
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus/context.go65
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus/doc.go14
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus/noop.go16
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/doc.go67
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/grpclogger.go15
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/options.go185
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/payload_interceptors.go144
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/server_interceptors.go129
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/makefile19
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/DOC.md107
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/README.md107
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/doc.go15
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/interceptors.go48
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/options.go32
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/DOC.md188
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/README.md188
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/context.go78
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/doc.go22
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/fieldextractor.go85
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/interceptors.go83
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus/context.go25
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/options.go44
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/DOC.md114
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/README.md114
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/doc.go19
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/nicemd.go126
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/single_key.go22
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/wrappers.go29
50 files changed, 4653 insertions, 0 deletions
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/DOC.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/DOC.md
new file mode 100644
index 00000000..511d953a
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/DOC.md
@@ -0,0 +1,166 @@
+# grpc_middleware
+`import "github.com/grpc-ecosystem/go-grpc-middleware"`
+
+* [Overview](#pkg-overview)
+* [Imported Packages](#pkg-imports)
+* [Index](#pkg-index)
+
+## <a name="pkg-overview">Overview</a>
+`grpc_middleware` is a collection of gRPC middleware packages: interceptors, helpers and tools.
+
+### Middleware
+gRPC is a fantastic RPC middleware, which sees a lot of adoption in the Golang world. However, the
+upstream gRPC codebase is relatively bare bones.
+
+This package, and most of its child packages provides commonly needed middleware for gRPC:
+client-side interceptors for retires, server-side interceptors for input validation and auth,
+functions for chaining said interceptors, metadata convenience methods and more.
+
+### Chaining
+By default, gRPC doesn't allow one to have more than one interceptor either on the client nor on
+the server side. `grpc_middleware` provides convenient chaining methods
+
+Simple way of turning a multiple interceptors into a single interceptor. Here's an example for
+server chaining:
+
+ myServer := grpc.NewServer(
+ grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(loggingStream, monitoringStream, authStream)),
+ grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(loggingUnary, monitoringUnary, authUnary),
+ )
+
+These interceptors will be executed from left to right: logging, monitoring and auth.
+
+Here's an example for client side chaining:
+
+ clientConn, err = grpc.Dial(
+ address,
+ grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(monitoringClientUnary, retryUnary)),
+ grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(monitoringClientStream, retryStream)),
+ )
+ client = pb_testproto.NewTestServiceClient(clientConn)
+ resp, err := client.PingEmpty(s.ctx, &myservice.Request{Msg: "hello"})
+
+These interceptors will be executed from left to right: monitoring and then retry logic.
+
+The retry interceptor will call every interceptor that follows it whenever when a retry happens.
+
+### Writing Your Own
+Implementing your own interceptor is pretty trivial: there are interfaces for that. But the interesting
+bit exposing common data to handlers (and other middleware), similarly to HTTP Middleware design.
+For example, you may want to pass the identity of the caller from the auth interceptor all the way
+to the handling function.
+
+For example, a client side interceptor example for auth looks like:
+
+ func FakeAuthUnaryInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
+ newCtx := context.WithValue(ctx, "user_id", "john@example.com")
+ return handler(newCtx, req)
+ }
+
+Unfortunately, it's not as easy for streaming RPCs. These have the `context.Context` embedded within
+the `grpc.ServerStream` object. To pass values through context, a wrapper (`WrappedServerStream`) is
+needed. For example:
+
+ func FakeAuthStreamingInterceptor(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
+ newStream := grpc_middleware.WrapServerStream(stream)
+ newStream.WrappedContext = context.WithValue(ctx, "user_id", "john@example.com")
+ return handler(srv, stream)
+ }
+
+## <a name="pkg-imports">Imported Packages</a>
+
+- [golang.org/x/net/context](https://godoc.org/golang.org/x/net/context)
+- [google.golang.org/grpc](https://godoc.org/google.golang.org/grpc)
+
+## <a name="pkg-index">Index</a>
+* [func ChainStreamClient(interceptors ...grpc.StreamClientInterceptor) grpc.StreamClientInterceptor](#ChainStreamClient)
+* [func ChainStreamServer(interceptors ...grpc.StreamServerInterceptor) grpc.StreamServerInterceptor](#ChainStreamServer)
+* [func ChainUnaryClient(interceptors ...grpc.UnaryClientInterceptor) grpc.UnaryClientInterceptor](#ChainUnaryClient)
+* [func ChainUnaryServer(interceptors ...grpc.UnaryServerInterceptor) grpc.UnaryServerInterceptor](#ChainUnaryServer)
+* [func WithStreamServerChain(interceptors ...grpc.StreamServerInterceptor) grpc.ServerOption](#WithStreamServerChain)
+* [func WithUnaryServerChain(interceptors ...grpc.UnaryServerInterceptor) grpc.ServerOption](#WithUnaryServerChain)
+* [type WrappedServerStream](#WrappedServerStream)
+ * [func WrapServerStream(stream grpc.ServerStream) \*WrappedServerStream](#WrapServerStream)
+ * [func (w \*WrappedServerStream) Context() context.Context](#WrappedServerStream.Context)
+
+#### <a name="pkg-files">Package files</a>
+[chain.go](./chain.go) [doc.go](./doc.go) [wrappers.go](./wrappers.go)
+
+## <a name="ChainStreamClient">func</a> [ChainStreamClient](./chain.go#L136)
+``` go
+func ChainStreamClient(interceptors ...grpc.StreamClientInterceptor) grpc.StreamClientInterceptor
+```
+ChainStreamClient creates a single interceptor out of a chain of many interceptors.
+
+Execution is done in left-to-right order, including passing of context.
+For example ChainStreamClient(one, two, three) will execute one before two before three.
+
+## <a name="ChainStreamServer">func</a> [ChainStreamServer](./chain.go#L58)
+``` go
+func ChainStreamServer(interceptors ...grpc.StreamServerInterceptor) grpc.StreamServerInterceptor
+```
+ChainStreamServer creates a single interceptor out of a chain of many interceptors.
+
+Execution is done in left-to-right order, including passing of context.
+For example ChainUnaryServer(one, two, three) will execute one before two before three.
+If you want to pass context between interceptors, use WrapServerStream.
+
+## <a name="ChainUnaryClient">func</a> [ChainUnaryClient](./chain.go#L97)
+``` go
+func ChainUnaryClient(interceptors ...grpc.UnaryClientInterceptor) grpc.UnaryClientInterceptor
+```
+ChainUnaryClient creates a single interceptor out of a chain of many interceptors.
+
+Execution is done in left-to-right order, including passing of context.
+For example ChainUnaryClient(one, two, three) will execute one before two before three.
+
+## <a name="ChainUnaryServer">func</a> [ChainUnaryServer](./chain.go#L18)
+``` go
+func ChainUnaryServer(interceptors ...grpc.UnaryServerInterceptor) grpc.UnaryServerInterceptor
+```
+ChainUnaryServer creates a single interceptor out of a chain of many interceptors.
+
+Execution is done in left-to-right order, including passing of context.
+For example ChainUnaryServer(one, two, three) will execute one before two before three, and three
+will see context changes of one and two.
+
+## <a name="WithStreamServerChain">func</a> [WithStreamServerChain](./chain.go#L181)
+``` go
+func WithStreamServerChain(interceptors ...grpc.StreamServerInterceptor) grpc.ServerOption
+```
+WithStreamServerChain is a grpc.Server config option that accepts multiple stream interceptors.
+Basically syntactic sugar.
+
+## <a name="WithUnaryServerChain">func</a> [WithUnaryServerChain](./chain.go#L175)
+``` go
+func WithUnaryServerChain(interceptors ...grpc.UnaryServerInterceptor) grpc.ServerOption
+```
+Chain creates a single interceptor out of a chain of many interceptors.
+
+WithUnaryServerChain is a grpc.Server config option that accepts multiple unary interceptors.
+Basically syntactic sugar.
+
+## <a name="WrappedServerStream">type</a> [WrappedServerStream](./wrappers.go#L12-L16)
+``` go
+type WrappedServerStream struct {
+ grpc.ServerStream
+ // WrappedContext is the wrapper's own Context. You can assign it.
+ WrappedContext context.Context
+}
+```
+WrappedServerStream is a thin wrapper around grpc.ServerStream that allows modifying context.
+
+### <a name="WrapServerStream">func</a> [WrapServerStream](./wrappers.go#L24)
+``` go
+func WrapServerStream(stream grpc.ServerStream) *WrappedServerStream
+```
+WrapServerStream returns a ServerStream that has the ability to overwrite context.
+
+### <a name="WrappedServerStream.Context">func</a> (\*WrappedServerStream) [Context](./wrappers.go#L19)
+``` go
+func (w *WrappedServerStream) Context() context.Context
+```
+Context returns the wrapper's WrappedContext, overwriting the nested grpc.ServerStream.Context()
+
+- - -
+Generated by [godoc2ghmd](https://github.com/GandalfUK/godoc2ghmd) \ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/Gopkg.lock b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/Gopkg.lock
new file mode 100644
index 00000000..ebdcb75a
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/Gopkg.lock
@@ -0,0 +1,123 @@
+# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
+
+
+[[projects]]
+ name = "cloud.google.com/go"
+ packages = ["compute/metadata"]
+ revision = "2d3a6656c17a60b0815b7e06ab0be04eacb6e613"
+ version = "v0.16.0"
+
+[[projects]]
+ name = "github.com/davecgh/go-spew"
+ packages = ["spew"]
+ revision = "346938d642f2ec3594ed81d874461961cd0faa76"
+ version = "v1.1.0"
+
+[[projects]]
+ name = "github.com/gogo/protobuf"
+ packages = ["gogoproto","proto","protoc-gen-gogo/descriptor"]
+ revision = "342cbe0a04158f6dcb03ca0079991a51a4248c02"
+ version = "v0.5"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/golang/protobuf"
+ packages = ["jsonpb","proto","ptypes","ptypes/any","ptypes/duration","ptypes/struct","ptypes/timestamp"]
+ revision = "1e59b77b52bf8e4b449a57e6f79f21226d571845"
+
+[[projects]]
+ name = "github.com/opentracing/opentracing-go"
+ packages = [".","ext","log","mocktracer"]
+ revision = "1949ddbfd147afd4d964a9f00b24eb291e0e7c38"
+ version = "v1.0.2"
+
+[[projects]]
+ name = "github.com/pmezard/go-difflib"
+ packages = ["difflib"]
+ revision = "792786c7400a136282c1664665ae0a8db921c6c2"
+ version = "v1.0.0"
+
+[[projects]]
+ name = "github.com/sirupsen/logrus"
+ packages = ["."]
+ revision = "f006c2ac4710855cf0f916dd6b77acf6b048dc6e"
+ version = "v1.0.3"
+
+[[projects]]
+ name = "github.com/stretchr/testify"
+ packages = ["assert","require","suite"]
+ revision = "69483b4bd14f5845b5a1e55bca19e954e827f1d0"
+ version = "v1.1.4"
+
+[[projects]]
+ name = "go.uber.org/atomic"
+ packages = ["."]
+ revision = "8474b86a5a6f79c443ce4b2992817ff32cf208b8"
+ version = "v1.3.1"
+
+[[projects]]
+ name = "go.uber.org/multierr"
+ packages = ["."]
+ revision = "3c4937480c32f4c13a875a1829af76c98ca3d40a"
+ version = "v1.1.0"
+
+[[projects]]
+ name = "go.uber.org/zap"
+ packages = [".","buffer","internal/bufferpool","internal/color","internal/exit","zapcore"]
+ revision = "35aad584952c3e7020db7b839f6b102de6271f89"
+ version = "v1.7.1"
+
+[[projects]]
+ branch = "master"
+ name = "golang.org/x/crypto"
+ packages = ["ssh/terminal"]
+ revision = "94eea52f7b742c7cbe0b03b22f0c4c8631ece122"
+
+[[projects]]
+ branch = "master"
+ name = "golang.org/x/net"
+ packages = ["context","context/ctxhttp","http2","http2/hpack","idna","internal/timeseries","lex/httplex","trace"]
+ revision = "a8b9294777976932365dabb6640cf1468d95c70f"
+
+[[projects]]
+ branch = "master"
+ name = "golang.org/x/oauth2"
+ packages = [".","google","internal","jws","jwt"]
+ revision = "f95fa95eaa936d9d87489b15d1d18b97c1ba9c28"
+
+[[projects]]
+ branch = "master"
+ name = "golang.org/x/sys"
+ packages = ["unix","windows"]
+ revision = "13fcbd661c8ececa8807a29b48407d674b1d8ed8"
+
+[[projects]]
+ branch = "master"
+ name = "golang.org/x/text"
+ packages = ["collate","collate/build","internal/colltab","internal/gen","internal/tag","internal/triegen","internal/ucd","language","secure/bidirule","transform","unicode/bidi","unicode/cldr","unicode/norm","unicode/rangetable"]
+ revision = "75cc3cad82b5f47d3fb229ddda8c5167da14f294"
+
+[[projects]]
+ name = "google.golang.org/appengine"
+ packages = [".","internal","internal/app_identity","internal/base","internal/datastore","internal/log","internal/modules","internal/remote_api","internal/urlfetch","urlfetch"]
+ revision = "150dc57a1b433e64154302bdc40b6bb8aefa313a"
+ version = "v1.0.0"
+
+[[projects]]
+ branch = "master"
+ name = "google.golang.org/genproto"
+ packages = ["googleapis/rpc/status"]
+ revision = "7f0da29060c682909f650ad8ed4e515bd74fa12a"
+
+[[projects]]
+ name = "google.golang.org/grpc"
+ packages = [".","balancer","balancer/roundrobin","codes","connectivity","credentials","credentials/oauth","encoding","grpclb/grpc_lb_v1/messages","grpclog","internal","keepalive","metadata","naming","peer","resolver","resolver/dns","resolver/passthrough","stats","status","tap","transport"]
+ revision = "5a9f7b402fe85096d2e1d0383435ee1876e863d0"
+ version = "v1.8.0"
+
+[solve-meta]
+ analyzer-name = "dep"
+ analyzer-version = 1
+ inputs-digest = "b24c6670412eb0bc44ed1db77fecc52333f8725f3e3272bdc568f5683a63031f"
+ solver-name = "gps-cdcl"
+ solver-version = 1
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/Gopkg.toml b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/Gopkg.toml
new file mode 100644
index 00000000..0a7d4c1c
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/Gopkg.toml
@@ -0,0 +1,35 @@
+[[constraint]]
+ name = "github.com/gogo/protobuf"
+ version = "0.5.0"
+
+[[constraint]]
+ branch = "master"
+ name = "github.com/golang/protobuf"
+
+[[constraint]]
+ name = "github.com/opentracing/opentracing-go"
+ version = "1.0.2"
+
+[[constraint]]
+ name = "github.com/sirupsen/logrus"
+ version = "1.0.3"
+
+[[constraint]]
+ name = "github.com/stretchr/testify"
+ version = "1.1.4"
+
+[[constraint]]
+ name = "go.uber.org/zap"
+ version = "1.7.1"
+
+[[constraint]]
+ branch = "master"
+ name = "golang.org/x/net"
+
+[[constraint]]
+ branch = "master"
+ name = "golang.org/x/oauth2"
+
+[[constraint]]
+ name = "google.golang.org/grpc"
+ version = "1.8.0"
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/LICENSE b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/LICENSE
new file mode 100644
index 00000000..b2b06503
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License. \ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/README.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/README.md
new file mode 100644
index 00000000..4fe246f2
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/README.md
@@ -0,0 +1,86 @@
+# Go gRPC Middleware
+
+[![Travis Build](https://travis-ci.org/grpc-ecosystem/go-grpc-middleware.svg?branch=master)](https://travis-ci.org/grpc-ecosystem/go-grpc-middleware)
+[![Go Report Card](https://goreportcard.com/badge/github.com/grpc-ecosystem/go-grpc-middleware)](https://goreportcard.com/report/github.com/grpc-ecosystem/go-grpc-middleware)
+[![GoDoc](http://img.shields.io/badge/GoDoc-Reference-blue.svg)](https://godoc.org/github.com/grpc-ecosystem/go-grpc-middleware)
+[![SourceGraph](https://sourcegraph.com/github.com/grpc-ecosystem/go-grpc-middleware/-/badge.svg)](https://sourcegraph.com/github.com/grpc-ecosystem/go-grpc-middleware/?badge)
+[![codecov](https://codecov.io/gh/grpc-ecosystem/go-grpc-middleware/branch/master/graph/badge.svg)](https://codecov.io/gh/grpc-ecosystem/go-grpc-middleware)
+[![Apache 2.0 License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)
+[![quality: production](https://img.shields.io/badge/quality-production-orange.svg)](#status)
+
+
+[gRPC Go](https://github.com/grpc/grpc-go) Middleware: interceptors, helpers, utilities.
+
+**Important** The repo recently moved to `github.com/grpc-ecosystem/go-grpc-middleware`, please update your import paths.
+
+## Middleware
+
+[gRPC Go](https://github.com/grpc/grpc-go) recently acquired support for
+Interceptors, i.e. [middleware](https://medium.com/@matryer/writing-middleware-in-golang-and-how-go-makes-it-so-much-fun-4375c1246e81#.gv7tdlghs)
+that is executed either on the gRPC Server before the request is passed onto the user's application logic, or on the gRPC client either around the user call. It is a perfect way to implement
+common patterns: auth, logging, message, validation, retries or monitoring.
+
+These are generic building blocks that make it easy to build multiple microservices easily.
+The purpose of this repository is to act as a go-to point for such reusable functionality. It contains
+some of them itself, but also will link to useful external repos.
+
+`grpc_middleware` itself provides support for chaining interceptors. See [Documentation](DOC.md), but here's an example:
+
+```go
+import "github.com/grpc-ecosystem/go-grpc-middleware"
+
+myServer := grpc.NewServer(
+ grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(
+ grpc_ctxtags.StreamServerInterceptor(),
+ grpc_opentracing.StreamServerInterceptor(),
+ grpc_prometheus.StreamServerInterceptor,
+ grpc_zap.StreamServerInterceptor(zapLogger),
+ grpc_auth.StreamServerInterceptor(myAuthFunction),
+ grpc_recovery.StreamServerInterceptor(),
+ )),
+ grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(
+ grpc_ctxtags.UnaryServerInterceptor(),
+ grpc_opentracing.UnaryServerInterceptor(),
+ grpc_prometheus.UnaryServerInterceptor,
+ grpc_zap.UnaryServerInterceptor(zapLogger),
+ grpc_auth.UnaryServerInterceptor(myAuthFunction),
+ grpc_recovery.UnaryServerInterceptor(),
+ )),
+)
+```
+
+## Interceptors
+
+*Please send a PR to add new interceptors or middleware to this list*
+
+#### Auth
+ * [`grpc_auth`](auth) - a customizable (via `AuthFunc`) piece of auth middleware
+
+#### Logging
+ * [`grpc_ctxtags`](tags/) - a library that adds a `Tag` map to context, with data populated from request body
+ * [`grpc_zap`](logging/zap/) - integration of [zap](https://github.com/uber-go/zap) logging library into gRPC handlers.
+ * [`grpc_logrus`](logging/logrus/) - integration of [logrus](https://github.com/sirupsen/logrus) logging library into gRPC handlers.
+
+
+#### Monitoring
+ * [`grpc_prometheus`âš¡](https://github.com/grpc-ecosystem/go-grpc-prometheus) - Prometheus client-side and server-side monitoring middleware
+ * [`otgrpc`âš¡](https://github.com/grpc-ecosystem/grpc-opentracing/tree/master/go/otgrpc) - [OpenTracing](http://opentracing.io/) client-side and server-side interceptors
+ * [`grpc_opentracing`](tracing/opentracing) - [OpenTracing](http://opentracing.io/) client-side and server-side interceptors with support for streaming and handler-returned tags
+
+#### Client
+ * [`grpc_retry`](retry/) - a generic gRPC response code retry mechanism, client-side middleware
+
+#### Server
+ * [`grpc_validator`](validator/) - codegen inbound message validation from `.proto` options
+ * [`grpc_recovery`](recovery/) - turn panics into gRPC errors
+
+
+## Status
+
+This code has been running in *production* since May 2016 as the basis of the gRPC micro services stack at [Improbable](https://improbable.io).
+
+Additional tooling will be added, and contributions are welcome.
+
+## License
+
+`go-grpc-middleware` is released under the Apache 2.0 license. See the [LICENSE](LICENSE) file for details.
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/DOC.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/DOC.md
new file mode 100644
index 00000000..5834112b
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/DOC.md
@@ -0,0 +1,148 @@
+# grpc_auth
+`import "github.com/grpc-ecosystem/go-grpc-middleware/auth"`
+
+* [Overview](#pkg-overview)
+* [Imported Packages](#pkg-imports)
+* [Index](#pkg-index)
+* [Examples](#pkg-examples)
+
+## <a name="pkg-overview">Overview</a>
+`grpc_auth` a generic server-side auth middleware for gRPC.
+
+### Server Side Auth Middleware
+It allows for easy assertion of `:authorization` headers in gRPC calls, be it HTTP Basic auth, or
+OAuth2 Bearer tokens.
+
+The middleware takes a user-customizable `AuthFunc`, which can be customized to verify and extract
+auth information from the request. The extracted information can be put in the `context.Context` of
+handlers downstream for retrieval.
+
+It also allows for per-service implementation overrides of `AuthFunc`. See `ServiceAuthFuncOverride`.
+
+Please see examples for simple examples of use.
+
+#### Example:
+
+<details>
+<summary>Click to expand code.</summary>
+
+```go
+package grpc_auth_test
+
+import (
+ "github.com/grpc-ecosystem/go-grpc-middleware/auth"
+ "github.com/grpc-ecosystem/go-grpc-middleware/tags"
+ "golang.org/x/net/context"
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/codes"
+)
+
+var (
+ cc *grpc.ClientConn
+)
+
+func parseToken(token string) (struct{}, error) {
+ return struct{}{}, nil
+}
+
+func userClaimFromToken(struct{}) string {
+ return "foobar"
+}
+
+// Simple example of server initialization code.
+func Example_serverConfig() {
+ exampleAuthFunc := func(ctx context.Context) (context.Context, error) {
+ token, err := grpc_auth.AuthFromMD(ctx, "bearer")
+ if err != nil {
+ return nil, err
+ }
+ tokenInfo, err := parseToken(token)
+ if err != nil {
+ return nil, grpc.Errorf(codes.Unauthenticated, "invalid auth token: %v", err)
+ }
+ grpc_ctxtags.Extract(ctx).Set("auth.sub", userClaimFromToken(tokenInfo))
+ newCtx := context.WithValue(ctx, "tokenInfo", tokenInfo)
+ return newCtx, nil
+ }
+
+ _ = grpc.NewServer(
+ grpc.StreamInterceptor(grpc_auth.StreamServerInterceptor(exampleAuthFunc)),
+ grpc.UnaryInterceptor(grpc_auth.UnaryServerInterceptor(exampleAuthFunc)),
+ )
+}
+```
+
+</details>
+
+## <a name="pkg-imports">Imported Packages</a>
+
+- [github.com/grpc-ecosystem/go-grpc-middleware](./..)
+- [github.com/grpc-ecosystem/go-grpc-middleware/util/metautils](./../util/metautils)
+- [golang.org/x/net/context](https://godoc.org/golang.org/x/net/context)
+- [google.golang.org/grpc](https://godoc.org/google.golang.org/grpc)
+- [google.golang.org/grpc/codes](https://godoc.org/google.golang.org/grpc/codes)
+
+## <a name="pkg-index">Index</a>
+* [func AuthFromMD(ctx context.Context, expectedScheme string) (string, error)](#AuthFromMD)
+* [func StreamServerInterceptor(authFunc AuthFunc) grpc.StreamServerInterceptor](#StreamServerInterceptor)
+* [func UnaryServerInterceptor(authFunc AuthFunc) grpc.UnaryServerInterceptor](#UnaryServerInterceptor)
+* [type AuthFunc](#AuthFunc)
+* [type ServiceAuthFuncOverride](#ServiceAuthFuncOverride)
+
+#### <a name="pkg-examples">Examples</a>
+* [Package (ServerConfig)](#example__serverConfig)
+
+#### <a name="pkg-files">Package files</a>
+[auth.go](./auth.go) [doc.go](./doc.go) [metadata.go](./metadata.go)
+
+## <a name="AuthFromMD">func</a> [AuthFromMD](./metadata.go#L24)
+``` go
+func AuthFromMD(ctx context.Context, expectedScheme string) (string, error)
+```
+AuthFromMD is a helper function for extracting the :authorization header from the gRPC metadata of the request.
+
+It expects the `:authorization` header to be of a certain scheme (e.g. `basic`, `bearer`), in a
+case-insensitive format (see rfc2617, sec 1.2). If no such authorization is found, or the token
+is of wrong scheme, an error with gRPC status `Unauthenticated` is returned.
+
+## <a name="StreamServerInterceptor">func</a> [StreamServerInterceptor](./auth.go#L51)
+``` go
+func StreamServerInterceptor(authFunc AuthFunc) grpc.StreamServerInterceptor
+```
+StreamServerInterceptor returns a new unary server interceptors that performs per-request auth.
+
+## <a name="UnaryServerInterceptor">func</a> [UnaryServerInterceptor](./auth.go#L34)
+``` go
+func UnaryServerInterceptor(authFunc AuthFunc) grpc.UnaryServerInterceptor
+```
+UnaryServerInterceptor returns a new unary server interceptors that performs per-request auth.
+
+## <a name="AuthFunc">type</a> [AuthFunc](./auth.go#L23)
+``` go
+type AuthFunc func(ctx context.Context) (context.Context, error)
+```
+AuthFunc is the pluggable function that performs authentication.
+
+The passed in `Context` will contain the gRPC metadata.MD object (for header-based authentication) and
+the peer.Peer information that can contain transport-based credentials (e.g. `credentials.AuthInfo`).
+
+The returned context will be propagated to handlers, allowing user changes to `Context`. However,
+please make sure that the `Context` returned is a child `Context` of the one passed in.
+
+If error is returned, its `grpc.Code()` will be returned to the user as well as the verbatim message.
+Please make sure you use `codes.Unauthenticated` (lacking auth) and `codes.PermissionDenied`
+(authed, but lacking perms) appropriately.
+
+## <a name="ServiceAuthFuncOverride">type</a> [ServiceAuthFuncOverride](./auth.go#L29-L31)
+``` go
+type ServiceAuthFuncOverride interface {
+ AuthFuncOverride(ctx context.Context, fullMethodName string) (context.Context, error)
+}
+```
+ServiceAuthFuncOverride allows a given gRPC service implementation to override the global `AuthFunc`.
+
+If a service implements the AuthFuncOverride method, it takes precedence over the `AuthFunc` method,
+and will be called instead of AuthFunc for all method invocations within that service.
+
+- - -
+Generated by [godoc2ghmd](https://github.com/GandalfUK/godoc2ghmd) \ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/README.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/README.md
new file mode 100644
index 00000000..5834112b
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/README.md
@@ -0,0 +1,148 @@
+# grpc_auth
+`import "github.com/grpc-ecosystem/go-grpc-middleware/auth"`
+
+* [Overview](#pkg-overview)
+* [Imported Packages](#pkg-imports)
+* [Index](#pkg-index)
+* [Examples](#pkg-examples)
+
+## <a name="pkg-overview">Overview</a>
+`grpc_auth` a generic server-side auth middleware for gRPC.
+
+### Server Side Auth Middleware
+It allows for easy assertion of `:authorization` headers in gRPC calls, be it HTTP Basic auth, or
+OAuth2 Bearer tokens.
+
+The middleware takes a user-customizable `AuthFunc`, which can be customized to verify and extract
+auth information from the request. The extracted information can be put in the `context.Context` of
+handlers downstream for retrieval.
+
+It also allows for per-service implementation overrides of `AuthFunc`. See `ServiceAuthFuncOverride`.
+
+Please see examples for simple examples of use.
+
+#### Example:
+
+<details>
+<summary>Click to expand code.</summary>
+
+```go
+package grpc_auth_test
+
+import (
+ "github.com/grpc-ecosystem/go-grpc-middleware/auth"
+ "github.com/grpc-ecosystem/go-grpc-middleware/tags"
+ "golang.org/x/net/context"
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/codes"
+)
+
+var (
+ cc *grpc.ClientConn
+)
+
+func parseToken(token string) (struct{}, error) {
+ return struct{}{}, nil
+}
+
+func userClaimFromToken(struct{}) string {
+ return "foobar"
+}
+
+// Simple example of server initialization code.
+func Example_serverConfig() {
+ exampleAuthFunc := func(ctx context.Context) (context.Context, error) {
+ token, err := grpc_auth.AuthFromMD(ctx, "bearer")
+ if err != nil {
+ return nil, err
+ }
+ tokenInfo, err := parseToken(token)
+ if err != nil {
+ return nil, grpc.Errorf(codes.Unauthenticated, "invalid auth token: %v", err)
+ }
+ grpc_ctxtags.Extract(ctx).Set("auth.sub", userClaimFromToken(tokenInfo))
+ newCtx := context.WithValue(ctx, "tokenInfo", tokenInfo)
+ return newCtx, nil
+ }
+
+ _ = grpc.NewServer(
+ grpc.StreamInterceptor(grpc_auth.StreamServerInterceptor(exampleAuthFunc)),
+ grpc.UnaryInterceptor(grpc_auth.UnaryServerInterceptor(exampleAuthFunc)),
+ )
+}
+```
+
+</details>
+
+## <a name="pkg-imports">Imported Packages</a>
+
+- [github.com/grpc-ecosystem/go-grpc-middleware](./..)
+- [github.com/grpc-ecosystem/go-grpc-middleware/util/metautils](./../util/metautils)
+- [golang.org/x/net/context](https://godoc.org/golang.org/x/net/context)
+- [google.golang.org/grpc](https://godoc.org/google.golang.org/grpc)
+- [google.golang.org/grpc/codes](https://godoc.org/google.golang.org/grpc/codes)
+
+## <a name="pkg-index">Index</a>
+* [func AuthFromMD(ctx context.Context, expectedScheme string) (string, error)](#AuthFromMD)
+* [func StreamServerInterceptor(authFunc AuthFunc) grpc.StreamServerInterceptor](#StreamServerInterceptor)
+* [func UnaryServerInterceptor(authFunc AuthFunc) grpc.UnaryServerInterceptor](#UnaryServerInterceptor)
+* [type AuthFunc](#AuthFunc)
+* [type ServiceAuthFuncOverride](#ServiceAuthFuncOverride)
+
+#### <a name="pkg-examples">Examples</a>
+* [Package (ServerConfig)](#example__serverConfig)
+
+#### <a name="pkg-files">Package files</a>
+[auth.go](./auth.go) [doc.go](./doc.go) [metadata.go](./metadata.go)
+
+## <a name="AuthFromMD">func</a> [AuthFromMD](./metadata.go#L24)
+``` go
+func AuthFromMD(ctx context.Context, expectedScheme string) (string, error)
+```
+AuthFromMD is a helper function for extracting the :authorization header from the gRPC metadata of the request.
+
+It expects the `:authorization` header to be of a certain scheme (e.g. `basic`, `bearer`), in a
+case-insensitive format (see rfc2617, sec 1.2). If no such authorization is found, or the token
+is of wrong scheme, an error with gRPC status `Unauthenticated` is returned.
+
+## <a name="StreamServerInterceptor">func</a> [StreamServerInterceptor](./auth.go#L51)
+``` go
+func StreamServerInterceptor(authFunc AuthFunc) grpc.StreamServerInterceptor
+```
+StreamServerInterceptor returns a new unary server interceptors that performs per-request auth.
+
+## <a name="UnaryServerInterceptor">func</a> [UnaryServerInterceptor](./auth.go#L34)
+``` go
+func UnaryServerInterceptor(authFunc AuthFunc) grpc.UnaryServerInterceptor
+```
+UnaryServerInterceptor returns a new unary server interceptors that performs per-request auth.
+
+## <a name="AuthFunc">type</a> [AuthFunc](./auth.go#L23)
+``` go
+type AuthFunc func(ctx context.Context) (context.Context, error)
+```
+AuthFunc is the pluggable function that performs authentication.
+
+The passed in `Context` will contain the gRPC metadata.MD object (for header-based authentication) and
+the peer.Peer information that can contain transport-based credentials (e.g. `credentials.AuthInfo`).
+
+The returned context will be propagated to handlers, allowing user changes to `Context`. However,
+please make sure that the `Context` returned is a child `Context` of the one passed in.
+
+If error is returned, its `grpc.Code()` will be returned to the user as well as the verbatim message.
+Please make sure you use `codes.Unauthenticated` (lacking auth) and `codes.PermissionDenied`
+(authed, but lacking perms) appropriately.
+
+## <a name="ServiceAuthFuncOverride">type</a> [ServiceAuthFuncOverride](./auth.go#L29-L31)
+``` go
+type ServiceAuthFuncOverride interface {
+ AuthFuncOverride(ctx context.Context, fullMethodName string) (context.Context, error)
+}
+```
+ServiceAuthFuncOverride allows a given gRPC service implementation to override the global `AuthFunc`.
+
+If a service implements the AuthFuncOverride method, it takes precedence over the `AuthFunc` method,
+and will be called instead of AuthFunc for all method invocations within that service.
+
+- - -
+Generated by [godoc2ghmd](https://github.com/GandalfUK/godoc2ghmd) \ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/auth.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/auth.go
new file mode 100644
index 00000000..a35c95fa
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/auth.go
@@ -0,0 +1,67 @@
+// Copyright 2016 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+package grpc_auth
+
+import (
+ "github.com/grpc-ecosystem/go-grpc-middleware"
+ "golang.org/x/net/context"
+ "google.golang.org/grpc"
+)
+
+// AuthFunc is the pluggable function that performs authentication.
+//
+// The passed in `Context` will contain the gRPC metadata.MD object (for header-based authentication) and
+// the peer.Peer information that can contain transport-based credentials (e.g. `credentials.AuthInfo`).
+//
+// The returned context will be propagated to handlers, allowing user changes to `Context`. However,
+// please make sure that the `Context` returned is a child `Context` of the one passed in.
+//
+// If error is returned, its `grpc.Code()` will be returned to the user as well as the verbatim message.
+// Please make sure you use `codes.Unauthenticated` (lacking auth) and `codes.PermissionDenied`
+// (authed, but lacking perms) appropriately.
+type AuthFunc func(ctx context.Context) (context.Context, error)
+
+// ServiceAuthFuncOverride allows a given gRPC service implementation to override the global `AuthFunc`.
+//
+// If a service implements the AuthFuncOverride method, it takes precedence over the `AuthFunc` method,
+// and will be called instead of AuthFunc for all method invocations within that service.
+type ServiceAuthFuncOverride interface {
+ AuthFuncOverride(ctx context.Context, fullMethodName string) (context.Context, error)
+}
+
+// UnaryServerInterceptor returns a new unary server interceptors that performs per-request auth.
+func UnaryServerInterceptor(authFunc AuthFunc) grpc.UnaryServerInterceptor {
+ return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
+ var newCtx context.Context
+ var err error
+ if overrideSrv, ok := info.Server.(ServiceAuthFuncOverride); ok {
+ newCtx, err = overrideSrv.AuthFuncOverride(ctx, info.FullMethod)
+ } else {
+ newCtx, err = authFunc(ctx)
+ }
+ if err != nil {
+ return nil, err
+ }
+ return handler(newCtx, req)
+ }
+}
+
+// StreamServerInterceptor returns a new unary server interceptors that performs per-request auth.
+func StreamServerInterceptor(authFunc AuthFunc) grpc.StreamServerInterceptor {
+ return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
+ var newCtx context.Context
+ var err error
+ if overrideSrv, ok := srv.(ServiceAuthFuncOverride); ok {
+ newCtx, err = overrideSrv.AuthFuncOverride(stream.Context(), info.FullMethod)
+ } else {
+ newCtx, err = authFunc(stream.Context())
+ }
+ if err != nil {
+ return err
+ }
+ wrapped := grpc_middleware.WrapServerStream(stream)
+ wrapped.WrappedContext = newCtx
+ return handler(srv, wrapped)
+ }
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/doc.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/doc.go
new file mode 100644
index 00000000..0550f023
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/doc.go
@@ -0,0 +1,20 @@
+// Copyright 2016 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+/*
+`grpc_auth` a generic server-side auth middleware for gRPC.
+
+Server Side Auth Middleware
+
+It allows for easy assertion of `:authorization` headers in gRPC calls, be it HTTP Basic auth, or
+OAuth2 Bearer tokens.
+
+The middleware takes a user-customizable `AuthFunc`, which can be customized to verify and extract
+auth information from the request. The extracted information can be put in the `context.Context` of
+handlers downstream for retrieval.
+
+It also allows for per-service implementation overrides of `AuthFunc`. See `ServiceAuthFuncOverride`.
+
+Please see examples for simple examples of use.
+*/
+package grpc_auth
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/metadata.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/metadata.go
new file mode 100644
index 00000000..50020653
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/metadata.go
@@ -0,0 +1,38 @@
+// Copyright 2016 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+package grpc_auth
+
+import (
+ "strings"
+
+ "github.com/grpc-ecosystem/go-grpc-middleware/util/metautils"
+ "golang.org/x/net/context"
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/codes"
+)
+
+var (
+ headerAuthorize = "authorization"
+)
+
+// AuthFromMD is a helper function for extracting the :authorization header from the gRPC metadata of the request.
+//
+// It expects the `:authorization` header to be of a certain scheme (e.g. `basic`, `bearer`), in a
+// case-insensitive format (see rfc2617, sec 1.2). If no such authorization is found, or the token
+// is of wrong scheme, an error with gRPC status `Unauthenticated` is returned.
+func AuthFromMD(ctx context.Context, expectedScheme string) (string, error) {
+ val := metautils.ExtractIncoming(ctx).Get(headerAuthorize)
+ if val == "" {
+ return "", grpc.Errorf(codes.Unauthenticated, "Request unauthenticated with "+expectedScheme)
+
+ }
+ splits := strings.SplitN(val, " ", 2)
+ if len(splits) < 2 {
+ return "", grpc.Errorf(codes.Unauthenticated, "Bad authorization string")
+ }
+ if strings.ToLower(splits[0]) != strings.ToLower(expectedScheme) {
+ return "", grpc.Errorf(codes.Unauthenticated, "Request unauthenticated with "+expectedScheme)
+ }
+ return splits[1], nil
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/chain.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/chain.go
new file mode 100644
index 00000000..45a2f5f4
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/chain.go
@@ -0,0 +1,183 @@
+// Copyright 2016 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+// gRPC Server Interceptor chaining middleware.
+
+package grpc_middleware
+
+import (
+ "golang.org/x/net/context"
+ "google.golang.org/grpc"
+)
+
+// ChainUnaryServer creates a single interceptor out of a chain of many interceptors.
+//
+// Execution is done in left-to-right order, including passing of context.
+// For example ChainUnaryServer(one, two, three) will execute one before two before three, and three
+// will see context changes of one and two.
+func ChainUnaryServer(interceptors ...grpc.UnaryServerInterceptor) grpc.UnaryServerInterceptor {
+ n := len(interceptors)
+
+ if n > 1 {
+ lastI := n - 1
+ return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
+ var (
+ chainHandler grpc.UnaryHandler
+ curI int
+ )
+
+ chainHandler = func(currentCtx context.Context, currentReq interface{}) (interface{}, error) {
+ if curI == lastI {
+ return handler(currentCtx, currentReq)
+ }
+ curI++
+ resp, err := interceptors[curI](currentCtx, currentReq, info, chainHandler)
+ curI--
+ return resp, err
+ }
+
+ return interceptors[0](ctx, req, info, chainHandler)
+ }
+ }
+
+ if n == 1 {
+ return interceptors[0]
+ }
+
+ // n == 0; Dummy interceptor maintained for backward compatibility to avoid returning nil.
+ return func(ctx context.Context, req interface{}, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
+ return handler(ctx, req)
+ }
+}
+
+// ChainStreamServer creates a single interceptor out of a chain of many interceptors.
+//
+// Execution is done in left-to-right order, including passing of context.
+// For example ChainUnaryServer(one, two, three) will execute one before two before three.
+// If you want to pass context between interceptors, use WrapServerStream.
+func ChainStreamServer(interceptors ...grpc.StreamServerInterceptor) grpc.StreamServerInterceptor {
+ n := len(interceptors)
+
+ if n > 1 {
+ lastI := n - 1
+ return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
+ var (
+ chainHandler grpc.StreamHandler
+ curI int
+ )
+
+ chainHandler = func(currentSrv interface{}, currentStream grpc.ServerStream) error {
+ if curI == lastI {
+ return handler(currentSrv, currentStream)
+ }
+ curI++
+ err := interceptors[curI](currentSrv, currentStream, info, chainHandler)
+ curI--
+ return err
+ }
+
+ return interceptors[0](srv, stream, info, chainHandler)
+ }
+ }
+
+ if n == 1 {
+ return interceptors[0]
+ }
+
+ // n == 0; Dummy interceptor maintained for backward compatibility to avoid returning nil.
+ return func(srv interface{}, stream grpc.ServerStream, _ *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
+ return handler(srv, stream)
+ }
+}
+
+// ChainUnaryClient creates a single interceptor out of a chain of many interceptors.
+//
+// Execution is done in left-to-right order, including passing of context.
+// For example ChainUnaryClient(one, two, three) will execute one before two before three.
+func ChainUnaryClient(interceptors ...grpc.UnaryClientInterceptor) grpc.UnaryClientInterceptor {
+ n := len(interceptors)
+
+ if n > 1 {
+ lastI := n - 1
+ return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
+ var (
+ chainHandler grpc.UnaryInvoker
+ curI int
+ )
+
+ chainHandler = func(currentCtx context.Context, currentMethod string, currentReq, currentRepl interface{}, currentConn *grpc.ClientConn, currentOpts ...grpc.CallOption) error {
+ if curI == lastI {
+ return invoker(currentCtx, currentMethod, currentReq, currentRepl, currentConn, currentOpts...)
+ }
+ curI++
+ err := interceptors[curI](currentCtx, currentMethod, currentReq, currentRepl, currentConn, chainHandler, currentOpts...)
+ curI--
+ return err
+ }
+
+ return interceptors[0](ctx, method, req, reply, cc, chainHandler, opts...)
+ }
+ }
+
+ if n == 1 {
+ return interceptors[0]
+ }
+
+ // n == 0; Dummy interceptor maintained for backward compatibility to avoid returning nil.
+ return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
+ return invoker(ctx, method, req, reply, cc, opts...)
+ }
+}
+
+// ChainStreamClient creates a single interceptor out of a chain of many interceptors.
+//
+// Execution is done in left-to-right order, including passing of context.
+// For example ChainStreamClient(one, two, three) will execute one before two before three.
+func ChainStreamClient(interceptors ...grpc.StreamClientInterceptor) grpc.StreamClientInterceptor {
+ n := len(interceptors)
+
+ if n > 1 {
+ lastI := n - 1
+ return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
+ var (
+ chainHandler grpc.Streamer
+ curI int
+ )
+
+ chainHandler = func(currentCtx context.Context, currentDesc *grpc.StreamDesc, currentConn *grpc.ClientConn, currentMethod string, currentOpts ...grpc.CallOption) (grpc.ClientStream, error) {
+ if curI == lastI {
+ return streamer(currentCtx, currentDesc, currentConn, currentMethod, currentOpts...)
+ }
+ curI++
+ stream, err := interceptors[curI](currentCtx, currentDesc, currentConn, currentMethod, chainHandler, currentOpts...)
+ curI--
+ return stream, err
+ }
+
+ return interceptors[0](ctx, desc, cc, method, chainHandler, opts...)
+ }
+ }
+
+ if n == 1 {
+ return interceptors[0]
+ }
+
+ // n == 0; Dummy interceptor maintained for backward compatibility to avoid returning nil.
+ return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
+ return streamer(ctx, desc, cc, method, opts...)
+ }
+}
+
+// Chain creates a single interceptor out of a chain of many interceptors.
+//
+// WithUnaryServerChain is a grpc.Server config option that accepts multiple unary interceptors.
+// Basically syntactic sugar.
+func WithUnaryServerChain(interceptors ...grpc.UnaryServerInterceptor) grpc.ServerOption {
+ return grpc.UnaryInterceptor(ChainUnaryServer(interceptors...))
+}
+
+// WithStreamServerChain is a grpc.Server config option that accepts multiple stream interceptors.
+// Basically syntactic sugar.
+func WithStreamServerChain(interceptors ...grpc.StreamServerInterceptor) grpc.ServerOption {
+ return grpc.StreamInterceptor(ChainStreamServer(interceptors...))
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/doc.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/doc.go
new file mode 100644
index 00000000..71689503
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/doc.go
@@ -0,0 +1,69 @@
+// Copyright 2016 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+/*
+`grpc_middleware` is a collection of gRPC middleware packages: interceptors, helpers and tools.
+
+Middleware
+
+gRPC is a fantastic RPC middleware, which sees a lot of adoption in the Golang world. However, the
+upstream gRPC codebase is relatively bare bones.
+
+This package, and most of its child packages provides commonly needed middleware for gRPC:
+client-side interceptors for retires, server-side interceptors for input validation and auth,
+functions for chaining said interceptors, metadata convenience methods and more.
+
+Chaining
+
+By default, gRPC doesn't allow one to have more than one interceptor either on the client nor on
+the server side. `grpc_middleware` provides convenient chaining methods
+
+Simple way of turning a multiple interceptors into a single interceptor. Here's an example for
+server chaining:
+
+ myServer := grpc.NewServer(
+ grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(loggingStream, monitoringStream, authStream)),
+ grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(loggingUnary, monitoringUnary, authUnary),
+ )
+
+These interceptors will be executed from left to right: logging, monitoring and auth.
+
+Here's an example for client side chaining:
+
+ clientConn, err = grpc.Dial(
+ address,
+ grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(monitoringClientUnary, retryUnary)),
+ grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(monitoringClientStream, retryStream)),
+ )
+ client = pb_testproto.NewTestServiceClient(clientConn)
+ resp, err := client.PingEmpty(s.ctx, &myservice.Request{Msg: "hello"})
+
+These interceptors will be executed from left to right: monitoring and then retry logic.
+
+The retry interceptor will call every interceptor that follows it whenever when a retry happens.
+
+Writing Your Own
+
+Implementing your own interceptor is pretty trivial: there are interfaces for that. But the interesting
+bit exposing common data to handlers (and other middleware), similarly to HTTP Middleware design.
+For example, you may want to pass the identity of the caller from the auth interceptor all the way
+to the handling function.
+
+For example, a client side interceptor example for auth looks like:
+
+ func FakeAuthUnaryInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
+ newCtx := context.WithValue(ctx, "user_id", "john@example.com")
+ return handler(newCtx, req)
+ }
+
+Unfortunately, it's not as easy for streaming RPCs. These have the `context.Context` embedded within
+the `grpc.ServerStream` object. To pass values through context, a wrapper (`WrappedServerStream`) is
+needed. For example:
+
+ func FakeAuthStreamingInterceptor(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
+ newStream := grpc_middleware.WrapServerStream(stream)
+ newStream.WrappedContext = context.WithValue(ctx, "user_id", "john@example.com")
+ return handler(srv, stream)
+ }
+*/
+package grpc_middleware
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/DOC.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/DOC.md
new file mode 100644
index 00000000..9deb4722
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/DOC.md
@@ -0,0 +1,91 @@
+# grpc_logging
+`import "github.com/grpc-ecosystem/go-grpc-middleware/logging"`
+
+* [Overview](#pkg-overview)
+* [Imported Packages](#pkg-imports)
+* [Index](#pkg-index)
+
+## <a name="pkg-overview">Overview</a>
+grpc_logging is a "parent" package for gRPC logging middlewares.
+
+### General functionality of all middleware
+The gRPC logging middleware populates request-scoped data to `grpc_ctxtags.Tags` that relate to the current gRPC call
+(e.g. service and method names).
+
+Once the gRPC logging middleware has added the gRPC specific Tags to the ctx they will then be written with the logs
+that are made using the `ctx_logrus` or `ctx_zap` loggers.
+
+All logging middleware will emit a final log statement. It is based on the error returned by the handler function,
+the gRPC status code, an error (if any) and it will emit at a level controlled via `WithLevels`.
+
+### This parent package
+This particular package is intended for use by other middleware, logging or otherwise. It contains interfaces that other
+logging middlewares *could* share . This allows code to be shared between different implementations.
+
+### Field names
+All field names of loggers follow the OpenTracing semantics definitions, with `grpc.` prefix if needed:
+<a href="https://github.com/opentracing/specification/blob/master/semantic_conventions.md">https://github.com/opentracing/specification/blob/master/semantic_conventions.md</a>
+
+### Implementations
+There are two implementations at the moment: logrus and zap
+
+See relevant packages below.
+
+## <a name="pkg-imports">Imported Packages</a>
+
+- [golang.org/x/net/context](https://godoc.org/golang.org/x/net/context)
+- [google.golang.org/grpc](https://godoc.org/google.golang.org/grpc)
+- [google.golang.org/grpc/codes](https://godoc.org/google.golang.org/grpc/codes)
+
+## <a name="pkg-index">Index</a>
+* [func DefaultDeciderMethod(fullMethodName string, err error) bool](#DefaultDeciderMethod)
+* [func DefaultErrorToCode(err error) codes.Code](#DefaultErrorToCode)
+* [type ClientPayloadLoggingDecider](#ClientPayloadLoggingDecider)
+* [type Decider](#Decider)
+* [type ErrorToCode](#ErrorToCode)
+* [type ServerPayloadLoggingDecider](#ServerPayloadLoggingDecider)
+
+#### <a name="pkg-files">Package files</a>
+[common.go](./common.go) [doc.go](./doc.go)
+
+## <a name="DefaultDeciderMethod">func</a> [DefaultDeciderMethod](./common.go#L25)
+``` go
+func DefaultDeciderMethod(fullMethodName string, err error) bool
+```
+DefaultDeciderMethod is the default implementation of decider to see if you should log the call
+by default this if always true so all calls are logged
+
+## <a name="DefaultErrorToCode">func</a> [DefaultErrorToCode](./common.go#L16)
+``` go
+func DefaultErrorToCode(err error) codes.Code
+```
+
+## <a name="ClientPayloadLoggingDecider">type</a> [ClientPayloadLoggingDecider](./common.go#L35)
+``` go
+type ClientPayloadLoggingDecider func(ctx context.Context, fullMethodName string) bool
+```
+ClientPayloadLoggingDecider is a user-provided function for deciding whether to log the client-side
+request/response payloads
+
+## <a name="Decider">type</a> [Decider](./common.go#L21)
+``` go
+type Decider func(fullMethodName string, err error) bool
+```
+Decider function defines rules for suppressing any interceptor logs
+
+## <a name="ErrorToCode">type</a> [ErrorToCode](./common.go#L14)
+``` go
+type ErrorToCode func(err error) codes.Code
+```
+ErrorToCode function determines the error code of an error
+This makes using custom errors with grpc middleware easier
+
+## <a name="ServerPayloadLoggingDecider">type</a> [ServerPayloadLoggingDecider](./common.go#L31)
+``` go
+type ServerPayloadLoggingDecider func(ctx context.Context, fullMethodName string, servingObject interface{}) bool
+```
+ServerPayloadLoggingDecider is a user-provided function for deciding whether to log the server-side
+request/response payloads
+
+- - -
+Generated by [godoc2ghmd](https://github.com/GandalfUK/godoc2ghmd) \ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/README.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/README.md
new file mode 100644
index 00000000..9deb4722
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/README.md
@@ -0,0 +1,91 @@
+# grpc_logging
+`import "github.com/grpc-ecosystem/go-grpc-middleware/logging"`
+
+* [Overview](#pkg-overview)
+* [Imported Packages](#pkg-imports)
+* [Index](#pkg-index)
+
+## <a name="pkg-overview">Overview</a>
+grpc_logging is a "parent" package for gRPC logging middlewares.
+
+### General functionality of all middleware
+The gRPC logging middleware populates request-scoped data to `grpc_ctxtags.Tags` that relate to the current gRPC call
+(e.g. service and method names).
+
+Once the gRPC logging middleware has added the gRPC specific Tags to the ctx they will then be written with the logs
+that are made using the `ctx_logrus` or `ctx_zap` loggers.
+
+All logging middleware will emit a final log statement. It is based on the error returned by the handler function,
+the gRPC status code, an error (if any) and it will emit at a level controlled via `WithLevels`.
+
+### This parent package
+This particular package is intended for use by other middleware, logging or otherwise. It contains interfaces that other
+logging middlewares *could* share . This allows code to be shared between different implementations.
+
+### Field names
+All field names of loggers follow the OpenTracing semantics definitions, with `grpc.` prefix if needed:
+<a href="https://github.com/opentracing/specification/blob/master/semantic_conventions.md">https://github.com/opentracing/specification/blob/master/semantic_conventions.md</a>
+
+### Implementations
+There are two implementations at the moment: logrus and zap
+
+See relevant packages below.
+
+## <a name="pkg-imports">Imported Packages</a>
+
+- [golang.org/x/net/context](https://godoc.org/golang.org/x/net/context)
+- [google.golang.org/grpc](https://godoc.org/google.golang.org/grpc)
+- [google.golang.org/grpc/codes](https://godoc.org/google.golang.org/grpc/codes)
+
+## <a name="pkg-index">Index</a>
+* [func DefaultDeciderMethod(fullMethodName string, err error) bool](#DefaultDeciderMethod)
+* [func DefaultErrorToCode(err error) codes.Code](#DefaultErrorToCode)
+* [type ClientPayloadLoggingDecider](#ClientPayloadLoggingDecider)
+* [type Decider](#Decider)
+* [type ErrorToCode](#ErrorToCode)
+* [type ServerPayloadLoggingDecider](#ServerPayloadLoggingDecider)
+
+#### <a name="pkg-files">Package files</a>
+[common.go](./common.go) [doc.go](./doc.go)
+
+## <a name="DefaultDeciderMethod">func</a> [DefaultDeciderMethod](./common.go#L25)
+``` go
+func DefaultDeciderMethod(fullMethodName string, err error) bool
+```
+DefaultDeciderMethod is the default implementation of decider to see if you should log the call
+by default this if always true so all calls are logged
+
+## <a name="DefaultErrorToCode">func</a> [DefaultErrorToCode](./common.go#L16)
+``` go
+func DefaultErrorToCode(err error) codes.Code
+```
+
+## <a name="ClientPayloadLoggingDecider">type</a> [ClientPayloadLoggingDecider](./common.go#L35)
+``` go
+type ClientPayloadLoggingDecider func(ctx context.Context, fullMethodName string) bool
+```
+ClientPayloadLoggingDecider is a user-provided function for deciding whether to log the client-side
+request/response payloads
+
+## <a name="Decider">type</a> [Decider](./common.go#L21)
+``` go
+type Decider func(fullMethodName string, err error) bool
+```
+Decider function defines rules for suppressing any interceptor logs
+
+## <a name="ErrorToCode">type</a> [ErrorToCode](./common.go#L14)
+``` go
+type ErrorToCode func(err error) codes.Code
+```
+ErrorToCode function determines the error code of an error
+This makes using custom errors with grpc middleware easier
+
+## <a name="ServerPayloadLoggingDecider">type</a> [ServerPayloadLoggingDecider](./common.go#L31)
+``` go
+type ServerPayloadLoggingDecider func(ctx context.Context, fullMethodName string, servingObject interface{}) bool
+```
+ServerPayloadLoggingDecider is a user-provided function for deciding whether to log the server-side
+request/response payloads
+
+- - -
+Generated by [godoc2ghmd](https://github.com/GandalfUK/godoc2ghmd) \ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/common.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/common.go
new file mode 100644
index 00000000..f725d038
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/common.go
@@ -0,0 +1,35 @@
+// Copyright 2017 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+package grpc_logging
+
+import (
+ "golang.org/x/net/context"
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/codes"
+)
+
+// ErrorToCode function determines the error code of an error
+// This makes using custom errors with grpc middleware easier
+type ErrorToCode func(err error) codes.Code
+
+func DefaultErrorToCode(err error) codes.Code {
+ return grpc.Code(err)
+}
+
+// Decider function defines rules for suppressing any interceptor logs
+type Decider func(fullMethodName string, err error) bool
+
+// DefaultDeciderMethod is the default implementation of decider to see if you should log the call
+// by default this if always true so all calls are logged
+func DefaultDeciderMethod(fullMethodName string, err error) bool {
+ return true
+}
+
+// ServerPayloadLoggingDecider is a user-provided function for deciding whether to log the server-side
+// request/response payloads
+type ServerPayloadLoggingDecider func(ctx context.Context, fullMethodName string, servingObject interface{}) bool
+
+// ClientPayloadLoggingDecider is a user-provided function for deciding whether to log the client-side
+// request/response payloads
+type ClientPayloadLoggingDecider func(ctx context.Context, fullMethodName string) bool
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/doc.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/doc.go
new file mode 100644
index 00000000..ce8bb298
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/doc.go
@@ -0,0 +1,35 @@
+// Copyright 2017 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+//
+/*
+grpc_logging is a "parent" package for gRPC logging middlewares.
+
+General functionality of all middleware
+
+The gRPC logging middleware populates request-scoped data to `grpc_ctxtags.Tags` that relate to the current gRPC call
+(e.g. service and method names).
+
+Once the gRPC logging middleware has added the gRPC specific Tags to the ctx they will then be written with the logs
+that are made using the `ctx_logrus` or `ctx_zap` loggers.
+
+All logging middleware will emit a final log statement. It is based on the error returned by the handler function,
+the gRPC status code, an error (if any) and it will emit at a level controlled via `WithLevels`.
+
+This parent package
+
+This particular package is intended for use by other middleware, logging or otherwise. It contains interfaces that other
+logging middlewares *could* share . This allows code to be shared between different implementations.
+
+Field names
+
+All field names of loggers follow the OpenTracing semantics definitions, with `grpc.` prefix if needed:
+https://github.com/opentracing/specification/blob/master/semantic_conventions.md
+
+Implementations
+
+There are two implementations at the moment: logrus and zap
+
+See relevant packages below.
+*/
+package grpc_logging
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/DOC.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/DOC.md
new file mode 100644
index 00000000..77ebb64c
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/DOC.md
@@ -0,0 +1,391 @@
+# grpc_logrus
+`import "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus"`
+
+* [Overview](#pkg-overview)
+* [Imported Packages](#pkg-imports)
+* [Index](#pkg-index)
+* [Examples](#pkg-examples)
+
+## <a name="pkg-overview">Overview</a>
+`grpc_logrus` is a gRPC logging middleware backed by Logrus loggers
+
+It accepts a user-configured `logrus.Entry` that will be used for logging completed gRPC calls. The same
+`logrus.Entry` will be used for logging completed gRPC calls, and be populated into the `context.Context` passed into gRPC handler code.
+
+On calling `StreamServerInterceptor` or `UnaryServerInterceptor` this logging middleware will add gRPC call information
+to the ctx so that it will be present on subsequent use of the `ctxlogrus` logger.
+
+This package also implements request and response *payload* logging, both for server-side and client-side. These will be
+logged as structured `jsonpb` fields for every message received/sent (both unary and streaming). For that please use
+`Payload*Interceptor` functions for that. Please note that the user-provided function that determines whetether to log
+the full request/response payload needs to be written with care, this can significantly slow down gRPC.
+
+If a deadline is present on the gRPC request the grpc.request.deadline tag is populated when the request begins. grpc.request.deadline
+is a string representing the time (RFC3339) when the current call will expire.
+
+Logrus can also be made as a backend for gRPC library internals. For that use `ReplaceGrpcLogger`.
+
+*Server Interceptor*
+Below is a JSON formatted example of a log that would be logged by the server interceptor:
+
+ {
+ "level": "info", // string logrus log levels
+ "msg": "finished unary call", // string log message
+ "grpc.code": "OK", // string grpc status code
+ "grpc.method": "Ping", // string method name
+ "grpc.service": "mwitkow.testproto.TestService", // string full name of the called service
+ "grpc.start_time": "2006-01-02T15:04:05Z07:00", // string RFC3339 representation of the start time
+ "grpc.request.deadline": "2006-01-02T15:04:05Z07:00", // string RFC3339 deadline of the current request if supplied
+ "grpc.request.value": "something", // string value on the request
+ "grpc.time_ms": 1.234, // float32 run time of the call in ms
+ "peer.address": {
+ "IP": "127.0.0.1", // string IP address of calling party
+ "Port": 60216, // int port call is coming in on
+ "Zone": "" // string peer zone for caller
+ },
+ "span.kind": "server", // string client | server
+ "system": "grpc" // string
+
+ "custom_field": "custom_value", // string user defined field
+ "custom_tags.int": 1337, // int user defined tag on the ctx
+ "custom_tags.string": "something", // string user defined tag on the ctx
+ }
+
+*Payload Interceptor*
+Below is a JSON formatted example of a log that would be logged by the payload interceptor:
+
+ {
+ "level": "info", // string logrus log levels
+ "msg": "client request payload logged as grpc.request.content", // string log message
+
+ "grpc.request.content": { // object content of RPC request
+ "value": "something", // string defined by caller
+ "sleepTimeMs": 9999 // int defined by caller
+ },
+ "grpc.method": "Ping", // string method being called
+ "grpc.service": "mwitkow.testproto.TestService", // string service being called
+ "span.kind": "client", // string client | server
+ "system": "grpc" // string
+ }
+
+Note - due to implementation ZAP differs from Logrus in the "grpc.request.content" object by having an inner "msg" object.
+
+Please see examples and tests for examples of use.
+
+#### Example:
+
+<details>
+<summary>Click to expand code.</summary>
+
+```go
+// Logrus entry is used, allowing pre-definition of certain fields by the user.
+logrusEntry := logrus.NewEntry(logrusLogger)
+// Shared options for the logger, with a custom gRPC code to log level function.
+opts := []grpc_logrus.Option{
+ grpc_logrus.WithLevels(customFunc),
+}
+// Make sure that log statements internal to gRPC library are logged using the logrus Logger as well.
+grpc_logrus.ReplaceGrpcLogger(logrusEntry)
+// Create a server, make sure we put the grpc_ctxtags context before everything else.
+_ = grpc.NewServer(
+ grpc_middleware.WithUnaryServerChain(
+ grpc_ctxtags.UnaryServerInterceptor(grpc_ctxtags.WithFieldExtractor(grpc_ctxtags.CodeGenRequestFieldExtractor)),
+ grpc_logrus.UnaryServerInterceptor(logrusEntry, opts...),
+ ),
+ grpc_middleware.WithStreamServerChain(
+ grpc_ctxtags.StreamServerInterceptor(grpc_ctxtags.WithFieldExtractor(grpc_ctxtags.CodeGenRequestFieldExtractor)),
+ grpc_logrus.StreamServerInterceptor(logrusEntry, opts...),
+ ),
+)
+```
+
+</details>
+
+#### Example:
+
+<details>
+<summary>Click to expand code.</summary>
+
+```go
+// Logrus entry is used, allowing pre-definition of certain fields by the user.
+logrusEntry := logrus.NewEntry(logrusLogger)
+// Shared options for the logger, with a custom duration to log field function.
+opts := []grpc_logrus.Option{
+ grpc_logrus.WithDurationField(func(duration time.Duration) (key string, value interface{}) {
+ return "grpc.time_ns", duration.Nanoseconds()
+ }),
+}
+_ = grpc.NewServer(
+ grpc_middleware.WithUnaryServerChain(
+ grpc_ctxtags.UnaryServerInterceptor(),
+ grpc_logrus.UnaryServerInterceptor(logrusEntry, opts...),
+ ),
+ grpc_middleware.WithStreamServerChain(
+ grpc_ctxtags.StreamServerInterceptor(),
+ grpc_logrus.StreamServerInterceptor(logrusEntry, opts...),
+ ),
+)
+```
+
+</details>
+
+## <a name="pkg-imports">Imported Packages</a>
+
+- [github.com/golang/protobuf/jsonpb](https://godoc.org/github.com/golang/protobuf/jsonpb)
+- [github.com/golang/protobuf/proto](https://godoc.org/github.com/golang/protobuf/proto)
+- [github.com/grpc-ecosystem/go-grpc-middleware](./../..)
+- [github.com/grpc-ecosystem/go-grpc-middleware/logging](./..)
+- [github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus](./ctxlogrus)
+- [github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus](./../../tags/logrus)
+- [github.com/sirupsen/logrus](https://godoc.org/github.com/sirupsen/logrus)
+- [golang.org/x/net/context](https://godoc.org/golang.org/x/net/context)
+- [google.golang.org/grpc](https://godoc.org/google.golang.org/grpc)
+- [google.golang.org/grpc/codes](https://godoc.org/google.golang.org/grpc/codes)
+- [google.golang.org/grpc/grpclog](https://godoc.org/google.golang.org/grpc/grpclog)
+
+## <a name="pkg-index">Index</a>
+* [Variables](#pkg-variables)
+* [func AddFields(ctx context.Context, fields logrus.Fields)](#AddFields)
+* [func DefaultClientCodeToLevel(code codes.Code) logrus.Level](#DefaultClientCodeToLevel)
+* [func DefaultCodeToLevel(code codes.Code) logrus.Level](#DefaultCodeToLevel)
+* [func DurationToDurationField(duration time.Duration) (key string, value interface{})](#DurationToDurationField)
+* [func DurationToTimeMillisField(duration time.Duration) (key string, value interface{})](#DurationToTimeMillisField)
+* [func Extract(ctx context.Context) \*logrus.Entry](#Extract)
+* [func PayloadStreamClientInterceptor(entry \*logrus.Entry, decider grpc\_logging.ClientPayloadLoggingDecider) grpc.StreamClientInterceptor](#PayloadStreamClientInterceptor)
+* [func PayloadStreamServerInterceptor(entry \*logrus.Entry, decider grpc\_logging.ServerPayloadLoggingDecider) grpc.StreamServerInterceptor](#PayloadStreamServerInterceptor)
+* [func PayloadUnaryClientInterceptor(entry \*logrus.Entry, decider grpc\_logging.ClientPayloadLoggingDecider) grpc.UnaryClientInterceptor](#PayloadUnaryClientInterceptor)
+* [func PayloadUnaryServerInterceptor(entry \*logrus.Entry, decider grpc\_logging.ServerPayloadLoggingDecider) grpc.UnaryServerInterceptor](#PayloadUnaryServerInterceptor)
+* [func ReplaceGrpcLogger(logger \*logrus.Entry)](#ReplaceGrpcLogger)
+* [func StreamClientInterceptor(entry \*logrus.Entry, opts ...Option) grpc.StreamClientInterceptor](#StreamClientInterceptor)
+* [func StreamServerInterceptor(entry \*logrus.Entry, opts ...Option) grpc.StreamServerInterceptor](#StreamServerInterceptor)
+* [func UnaryClientInterceptor(entry \*logrus.Entry, opts ...Option) grpc.UnaryClientInterceptor](#UnaryClientInterceptor)
+* [func UnaryServerInterceptor(entry \*logrus.Entry, opts ...Option) grpc.UnaryServerInterceptor](#UnaryServerInterceptor)
+* [type CodeToLevel](#CodeToLevel)
+* [type DurationToField](#DurationToField)
+* [type Option](#Option)
+ * [func WithCodes(f grpc\_logging.ErrorToCode) Option](#WithCodes)
+ * [func WithDecider(f grpc\_logging.Decider) Option](#WithDecider)
+ * [func WithDurationField(f DurationToField) Option](#WithDurationField)
+ * [func WithLevels(f CodeToLevel) Option](#WithLevels)
+
+#### <a name="pkg-examples">Examples</a>
+* [Extract (Unary)](#example_Extract_unary)
+* [WithDecider](#example_WithDecider)
+* [Package (Initialization)](#example__initialization)
+* [Package (InitializationWithDurationFieldOverride)](#example__initializationWithDurationFieldOverride)
+
+#### <a name="pkg-files">Package files</a>
+[client_interceptors.go](./client_interceptors.go) [context.go](./context.go) [doc.go](./doc.go) [grpclogger.go](./grpclogger.go) [options.go](./options.go) [payload_interceptors.go](./payload_interceptors.go) [server_interceptors.go](./server_interceptors.go)
+
+## <a name="pkg-variables">Variables</a>
+``` go
+var (
+ // SystemField is used in every log statement made through grpc_logrus. Can be overwritten before any initialization code.
+ SystemField = "system"
+
+ // KindField describes the log gield used to incicate whether this is a server or a client log statment.
+ KindField = "span.kind"
+)
+```
+``` go
+var DefaultDurationToField = DurationToTimeMillisField
+```
+DefaultDurationToField is the default implementation of converting request duration to a log field (key and value).
+
+``` go
+var (
+ // JsonPBMarshaller is the marshaller used for serializing protobuf messages.
+ JsonPbMarshaller = &jsonpb.Marshaler{}
+)
+```
+
+## <a name="AddFields">func</a> [AddFields](./context.go#L11)
+``` go
+func AddFields(ctx context.Context, fields logrus.Fields)
+```
+AddFields adds logrus fields to the logger.
+Deprecated: should use the ctxlogrus.Extract instead
+
+## <a name="DefaultClientCodeToLevel">func</a> [DefaultClientCodeToLevel](./options.go#L129)
+``` go
+func DefaultClientCodeToLevel(code codes.Code) logrus.Level
+```
+DefaultClientCodeToLevel is the default implementation of gRPC return codes to log levels for client side.
+
+## <a name="DefaultCodeToLevel">func</a> [DefaultCodeToLevel](./options.go#L87)
+``` go
+func DefaultCodeToLevel(code codes.Code) logrus.Level
+```
+DefaultCodeToLevel is the default implementation of gRPC return codes to log levels for server side.
+
+## <a name="DurationToDurationField">func</a> [DurationToDurationField](./options.go#L179)
+``` go
+func DurationToDurationField(duration time.Duration) (key string, value interface{})
+```
+DurationToDurationField uses the duration value to log the request duration.
+
+## <a name="DurationToTimeMillisField">func</a> [DurationToTimeMillisField](./options.go#L174)
+``` go
+func DurationToTimeMillisField(duration time.Duration) (key string, value interface{})
+```
+DurationToTimeMillisField converts the duration to milliseconds and uses the key `grpc.time_ms`.
+
+## <a name="Extract">func</a> [Extract](./context.go#L17)
+``` go
+func Extract(ctx context.Context) *logrus.Entry
+```
+Extract takes the call-scoped logrus.Entry from grpc_logrus middleware.
+Deprecated: should use the ctxlogrus.Extract instead
+
+#### Example:
+
+<details>
+<summary>Click to expand code.</summary>
+
+```go
+_ = func(ctx context.Context, ping *pb_testproto.PingRequest) (*pb_testproto.PingResponse, error) {
+ // Add fields the ctxtags of the request which will be added to all extracted loggers.
+ grpc_ctxtags.Extract(ctx).Set("custom_tags.string", "something").Set("custom_tags.int", 1337)
+ // Extract a single request-scoped logrus.Logger and log messages.
+ l := ctx_logrus.Extract(ctx)
+ l.Info("some ping")
+ l.Info("another ping")
+ return &pb_testproto.PingResponse{Value: ping.Value}, nil
+}
+```
+
+</details>
+
+## <a name="PayloadStreamClientInterceptor">func</a> [PayloadStreamClientInterceptor](./payload_interceptors.go#L74)
+``` go
+func PayloadStreamClientInterceptor(entry *logrus.Entry, decider grpc_logging.ClientPayloadLoggingDecider) grpc.StreamClientInterceptor
+```
+PayloadStreamServerInterceptor returns a new streaming client interceptor that logs the paylods of requests and responses.
+
+## <a name="PayloadStreamServerInterceptor">func</a> [PayloadStreamServerInterceptor](./payload_interceptors.go#L45)
+``` go
+func PayloadStreamServerInterceptor(entry *logrus.Entry, decider grpc_logging.ServerPayloadLoggingDecider) grpc.StreamServerInterceptor
+```
+PayloadUnaryServerInterceptor returns a new server server interceptors that logs the payloads of requests.
+
+This *only* works when placed *after* the `grpc_logrus.StreamServerInterceptor`. However, the logging can be done to a
+separate instance of the logger.
+
+## <a name="PayloadUnaryClientInterceptor">func</a> [PayloadUnaryClientInterceptor](./payload_interceptors.go#L58)
+``` go
+func PayloadUnaryClientInterceptor(entry *logrus.Entry, decider grpc_logging.ClientPayloadLoggingDecider) grpc.UnaryClientInterceptor
+```
+PayloadUnaryClientInterceptor returns a new unary client interceptor that logs the paylods of requests and responses.
+
+## <a name="PayloadUnaryServerInterceptor">func</a> [PayloadUnaryServerInterceptor](./payload_interceptors.go#L25)
+``` go
+func PayloadUnaryServerInterceptor(entry *logrus.Entry, decider grpc_logging.ServerPayloadLoggingDecider) grpc.UnaryServerInterceptor
+```
+PayloadUnaryServerInterceptor returns a new unary server interceptors that logs the payloads of requests.
+
+This *only* works when placed *after* the `grpc_logrus.UnaryServerInterceptor`. However, the logging can be done to a
+separate instance of the logger.
+
+## <a name="ReplaceGrpcLogger">func</a> [ReplaceGrpcLogger](./grpclogger.go#L13)
+``` go
+func ReplaceGrpcLogger(logger *logrus.Entry)
+```
+ReplaceGrpcLogger sets the given logrus.Logger as a gRPC-level logger.
+This should be called *before* any other initialization, preferably from init() functions.
+
+## <a name="StreamClientInterceptor">func</a> [StreamClientInterceptor](./client_interceptors.go#L28)
+``` go
+func StreamClientInterceptor(entry *logrus.Entry, opts ...Option) grpc.StreamClientInterceptor
+```
+StreamServerInterceptor returns a new streaming client interceptor that optionally logs the execution of external gRPC calls.
+
+## <a name="StreamServerInterceptor">func</a> [StreamServerInterceptor](./server_interceptors.go#L58)
+``` go
+func StreamServerInterceptor(entry *logrus.Entry, opts ...Option) grpc.StreamServerInterceptor
+```
+StreamServerInterceptor returns a new streaming server interceptor that adds logrus.Entry to the context.
+
+## <a name="UnaryClientInterceptor">func</a> [UnaryClientInterceptor](./client_interceptors.go#L16)
+``` go
+func UnaryClientInterceptor(entry *logrus.Entry, opts ...Option) grpc.UnaryClientInterceptor
+```
+UnaryClientInterceptor returns a new unary client interceptor that optionally logs the execution of external gRPC calls.
+
+## <a name="UnaryServerInterceptor">func</a> [UnaryServerInterceptor](./server_interceptors.go#L26)
+``` go
+func UnaryServerInterceptor(entry *logrus.Entry, opts ...Option) grpc.UnaryServerInterceptor
+```
+PayloadUnaryServerInterceptor returns a new unary server interceptors that adds logrus.Entry to the context.
+
+## <a name="CodeToLevel">type</a> [CodeToLevel](./options.go#L53)
+``` go
+type CodeToLevel func(code codes.Code) logrus.Level
+```
+CodeToLevel function defines the mapping between gRPC return codes and interceptor log level.
+
+## <a name="DurationToField">type</a> [DurationToField](./options.go#L56)
+``` go
+type DurationToField func(duration time.Duration) (key string, value interface{})
+```
+DurationToField function defines how to produce duration fields for logging
+
+## <a name="Option">type</a> [Option](./options.go#L50)
+``` go
+type Option func(*options)
+```
+
+### <a name="WithCodes">func</a> [WithCodes](./options.go#L73)
+``` go
+func WithCodes(f grpc_logging.ErrorToCode) Option
+```
+WithCodes customizes the function for mapping errors to error codes.
+
+### <a name="WithDecider">func</a> [WithDecider](./options.go#L59)
+``` go
+func WithDecider(f grpc_logging.Decider) Option
+```
+WithDecider customizes the function for deciding if the gRPC interceptor logs should log.
+
+#### Example:
+
+<details>
+<summary>Click to expand code.</summary>
+
+```go
+opts := []grpc_logrus.Option{
+ grpc_logrus.WithDecider(func(methodFullName string, err error) bool {
+ // will not log gRPC calls if it was a call to healthcheck and no error was raised
+ if err == nil && methodFullName == "blah.foo.healthcheck" {
+ return false
+ }
+
+ // by default you will log all calls
+ return true
+ }),
+}
+
+_ = []grpc.ServerOption{
+ grpc_middleware.WithStreamServerChain(
+ grpc_ctxtags.StreamServerInterceptor(),
+ grpc_logrus.StreamServerInterceptor(logrus.NewEntry(logrus.New()), opts...)),
+ grpc_middleware.WithUnaryServerChain(
+ grpc_ctxtags.UnaryServerInterceptor(),
+ grpc_logrus.UnaryServerInterceptor(logrus.NewEntry(logrus.New()), opts...)),
+}
+```
+
+</details>
+### <a name="WithDurationField">func</a> [WithDurationField](./options.go#L80)
+``` go
+func WithDurationField(f DurationToField) Option
+```
+WithDurationField customizes the function for mapping request durations to log fields.
+
+### <a name="WithLevels">func</a> [WithLevels](./options.go#L66)
+``` go
+func WithLevels(f CodeToLevel) Option
+```
+WithLevels customizes the function for mapping gRPC return codes and interceptor log level statements.
+
+- - -
+Generated by [godoc2ghmd](https://github.com/GandalfUK/godoc2ghmd) \ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/README.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/README.md
new file mode 100644
index 00000000..77ebb64c
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/README.md
@@ -0,0 +1,391 @@
+# grpc_logrus
+`import "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus"`
+
+* [Overview](#pkg-overview)
+* [Imported Packages](#pkg-imports)
+* [Index](#pkg-index)
+* [Examples](#pkg-examples)
+
+## <a name="pkg-overview">Overview</a>
+`grpc_logrus` is a gRPC logging middleware backed by Logrus loggers
+
+It accepts a user-configured `logrus.Entry` that will be used for logging completed gRPC calls. The same
+`logrus.Entry` will be used for logging completed gRPC calls, and be populated into the `context.Context` passed into gRPC handler code.
+
+On calling `StreamServerInterceptor` or `UnaryServerInterceptor` this logging middleware will add gRPC call information
+to the ctx so that it will be present on subsequent use of the `ctxlogrus` logger.
+
+This package also implements request and response *payload* logging, both for server-side and client-side. These will be
+logged as structured `jsonpb` fields for every message received/sent (both unary and streaming). For that please use
+`Payload*Interceptor` functions for that. Please note that the user-provided function that determines whetether to log
+the full request/response payload needs to be written with care, this can significantly slow down gRPC.
+
+If a deadline is present on the gRPC request the grpc.request.deadline tag is populated when the request begins. grpc.request.deadline
+is a string representing the time (RFC3339) when the current call will expire.
+
+Logrus can also be made as a backend for gRPC library internals. For that use `ReplaceGrpcLogger`.
+
+*Server Interceptor*
+Below is a JSON formatted example of a log that would be logged by the server interceptor:
+
+ {
+ "level": "info", // string logrus log levels
+ "msg": "finished unary call", // string log message
+ "grpc.code": "OK", // string grpc status code
+ "grpc.method": "Ping", // string method name
+ "grpc.service": "mwitkow.testproto.TestService", // string full name of the called service
+ "grpc.start_time": "2006-01-02T15:04:05Z07:00", // string RFC3339 representation of the start time
+ "grpc.request.deadline": "2006-01-02T15:04:05Z07:00", // string RFC3339 deadline of the current request if supplied
+ "grpc.request.value": "something", // string value on the request
+ "grpc.time_ms": 1.234, // float32 run time of the call in ms
+ "peer.address": {
+ "IP": "127.0.0.1", // string IP address of calling party
+ "Port": 60216, // int port call is coming in on
+ "Zone": "" // string peer zone for caller
+ },
+ "span.kind": "server", // string client | server
+ "system": "grpc" // string
+
+ "custom_field": "custom_value", // string user defined field
+ "custom_tags.int": 1337, // int user defined tag on the ctx
+ "custom_tags.string": "something", // string user defined tag on the ctx
+ }
+
+*Payload Interceptor*
+Below is a JSON formatted example of a log that would be logged by the payload interceptor:
+
+ {
+ "level": "info", // string logrus log levels
+ "msg": "client request payload logged as grpc.request.content", // string log message
+
+ "grpc.request.content": { // object content of RPC request
+ "value": "something", // string defined by caller
+ "sleepTimeMs": 9999 // int defined by caller
+ },
+ "grpc.method": "Ping", // string method being called
+ "grpc.service": "mwitkow.testproto.TestService", // string service being called
+ "span.kind": "client", // string client | server
+ "system": "grpc" // string
+ }
+
+Note - due to implementation ZAP differs from Logrus in the "grpc.request.content" object by having an inner "msg" object.
+
+Please see examples and tests for examples of use.
+
+#### Example:
+
+<details>
+<summary>Click to expand code.</summary>
+
+```go
+// Logrus entry is used, allowing pre-definition of certain fields by the user.
+logrusEntry := logrus.NewEntry(logrusLogger)
+// Shared options for the logger, with a custom gRPC code to log level function.
+opts := []grpc_logrus.Option{
+ grpc_logrus.WithLevels(customFunc),
+}
+// Make sure that log statements internal to gRPC library are logged using the logrus Logger as well.
+grpc_logrus.ReplaceGrpcLogger(logrusEntry)
+// Create a server, make sure we put the grpc_ctxtags context before everything else.
+_ = grpc.NewServer(
+ grpc_middleware.WithUnaryServerChain(
+ grpc_ctxtags.UnaryServerInterceptor(grpc_ctxtags.WithFieldExtractor(grpc_ctxtags.CodeGenRequestFieldExtractor)),
+ grpc_logrus.UnaryServerInterceptor(logrusEntry, opts...),
+ ),
+ grpc_middleware.WithStreamServerChain(
+ grpc_ctxtags.StreamServerInterceptor(grpc_ctxtags.WithFieldExtractor(grpc_ctxtags.CodeGenRequestFieldExtractor)),
+ grpc_logrus.StreamServerInterceptor(logrusEntry, opts...),
+ ),
+)
+```
+
+</details>
+
+#### Example:
+
+<details>
+<summary>Click to expand code.</summary>
+
+```go
+// Logrus entry is used, allowing pre-definition of certain fields by the user.
+logrusEntry := logrus.NewEntry(logrusLogger)
+// Shared options for the logger, with a custom duration to log field function.
+opts := []grpc_logrus.Option{
+ grpc_logrus.WithDurationField(func(duration time.Duration) (key string, value interface{}) {
+ return "grpc.time_ns", duration.Nanoseconds()
+ }),
+}
+_ = grpc.NewServer(
+ grpc_middleware.WithUnaryServerChain(
+ grpc_ctxtags.UnaryServerInterceptor(),
+ grpc_logrus.UnaryServerInterceptor(logrusEntry, opts...),
+ ),
+ grpc_middleware.WithStreamServerChain(
+ grpc_ctxtags.StreamServerInterceptor(),
+ grpc_logrus.StreamServerInterceptor(logrusEntry, opts...),
+ ),
+)
+```
+
+</details>
+
+## <a name="pkg-imports">Imported Packages</a>
+
+- [github.com/golang/protobuf/jsonpb](https://godoc.org/github.com/golang/protobuf/jsonpb)
+- [github.com/golang/protobuf/proto](https://godoc.org/github.com/golang/protobuf/proto)
+- [github.com/grpc-ecosystem/go-grpc-middleware](./../..)
+- [github.com/grpc-ecosystem/go-grpc-middleware/logging](./..)
+- [github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus](./ctxlogrus)
+- [github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus](./../../tags/logrus)
+- [github.com/sirupsen/logrus](https://godoc.org/github.com/sirupsen/logrus)
+- [golang.org/x/net/context](https://godoc.org/golang.org/x/net/context)
+- [google.golang.org/grpc](https://godoc.org/google.golang.org/grpc)
+- [google.golang.org/grpc/codes](https://godoc.org/google.golang.org/grpc/codes)
+- [google.golang.org/grpc/grpclog](https://godoc.org/google.golang.org/grpc/grpclog)
+
+## <a name="pkg-index">Index</a>
+* [Variables](#pkg-variables)
+* [func AddFields(ctx context.Context, fields logrus.Fields)](#AddFields)
+* [func DefaultClientCodeToLevel(code codes.Code) logrus.Level](#DefaultClientCodeToLevel)
+* [func DefaultCodeToLevel(code codes.Code) logrus.Level](#DefaultCodeToLevel)
+* [func DurationToDurationField(duration time.Duration) (key string, value interface{})](#DurationToDurationField)
+* [func DurationToTimeMillisField(duration time.Duration) (key string, value interface{})](#DurationToTimeMillisField)
+* [func Extract(ctx context.Context) \*logrus.Entry](#Extract)
+* [func PayloadStreamClientInterceptor(entry \*logrus.Entry, decider grpc\_logging.ClientPayloadLoggingDecider) grpc.StreamClientInterceptor](#PayloadStreamClientInterceptor)
+* [func PayloadStreamServerInterceptor(entry \*logrus.Entry, decider grpc\_logging.ServerPayloadLoggingDecider) grpc.StreamServerInterceptor](#PayloadStreamServerInterceptor)
+* [func PayloadUnaryClientInterceptor(entry \*logrus.Entry, decider grpc\_logging.ClientPayloadLoggingDecider) grpc.UnaryClientInterceptor](#PayloadUnaryClientInterceptor)
+* [func PayloadUnaryServerInterceptor(entry \*logrus.Entry, decider grpc\_logging.ServerPayloadLoggingDecider) grpc.UnaryServerInterceptor](#PayloadUnaryServerInterceptor)
+* [func ReplaceGrpcLogger(logger \*logrus.Entry)](#ReplaceGrpcLogger)
+* [func StreamClientInterceptor(entry \*logrus.Entry, opts ...Option) grpc.StreamClientInterceptor](#StreamClientInterceptor)
+* [func StreamServerInterceptor(entry \*logrus.Entry, opts ...Option) grpc.StreamServerInterceptor](#StreamServerInterceptor)
+* [func UnaryClientInterceptor(entry \*logrus.Entry, opts ...Option) grpc.UnaryClientInterceptor](#UnaryClientInterceptor)
+* [func UnaryServerInterceptor(entry \*logrus.Entry, opts ...Option) grpc.UnaryServerInterceptor](#UnaryServerInterceptor)
+* [type CodeToLevel](#CodeToLevel)
+* [type DurationToField](#DurationToField)
+* [type Option](#Option)
+ * [func WithCodes(f grpc\_logging.ErrorToCode) Option](#WithCodes)
+ * [func WithDecider(f grpc\_logging.Decider) Option](#WithDecider)
+ * [func WithDurationField(f DurationToField) Option](#WithDurationField)
+ * [func WithLevels(f CodeToLevel) Option](#WithLevels)
+
+#### <a name="pkg-examples">Examples</a>
+* [Extract (Unary)](#example_Extract_unary)
+* [WithDecider](#example_WithDecider)
+* [Package (Initialization)](#example__initialization)
+* [Package (InitializationWithDurationFieldOverride)](#example__initializationWithDurationFieldOverride)
+
+#### <a name="pkg-files">Package files</a>
+[client_interceptors.go](./client_interceptors.go) [context.go](./context.go) [doc.go](./doc.go) [grpclogger.go](./grpclogger.go) [options.go](./options.go) [payload_interceptors.go](./payload_interceptors.go) [server_interceptors.go](./server_interceptors.go)
+
+## <a name="pkg-variables">Variables</a>
+``` go
+var (
+ // SystemField is used in every log statement made through grpc_logrus. Can be overwritten before any initialization code.
+ SystemField = "system"
+
+ // KindField describes the log gield used to incicate whether this is a server or a client log statment.
+ KindField = "span.kind"
+)
+```
+``` go
+var DefaultDurationToField = DurationToTimeMillisField
+```
+DefaultDurationToField is the default implementation of converting request duration to a log field (key and value).
+
+``` go
+var (
+ // JsonPBMarshaller is the marshaller used for serializing protobuf messages.
+ JsonPbMarshaller = &jsonpb.Marshaler{}
+)
+```
+
+## <a name="AddFields">func</a> [AddFields](./context.go#L11)
+``` go
+func AddFields(ctx context.Context, fields logrus.Fields)
+```
+AddFields adds logrus fields to the logger.
+Deprecated: should use the ctxlogrus.Extract instead
+
+## <a name="DefaultClientCodeToLevel">func</a> [DefaultClientCodeToLevel](./options.go#L129)
+``` go
+func DefaultClientCodeToLevel(code codes.Code) logrus.Level
+```
+DefaultClientCodeToLevel is the default implementation of gRPC return codes to log levels for client side.
+
+## <a name="DefaultCodeToLevel">func</a> [DefaultCodeToLevel](./options.go#L87)
+``` go
+func DefaultCodeToLevel(code codes.Code) logrus.Level
+```
+DefaultCodeToLevel is the default implementation of gRPC return codes to log levels for server side.
+
+## <a name="DurationToDurationField">func</a> [DurationToDurationField](./options.go#L179)
+``` go
+func DurationToDurationField(duration time.Duration) (key string, value interface{})
+```
+DurationToDurationField uses the duration value to log the request duration.
+
+## <a name="DurationToTimeMillisField">func</a> [DurationToTimeMillisField](./options.go#L174)
+``` go
+func DurationToTimeMillisField(duration time.Duration) (key string, value interface{})
+```
+DurationToTimeMillisField converts the duration to milliseconds and uses the key `grpc.time_ms`.
+
+## <a name="Extract">func</a> [Extract](./context.go#L17)
+``` go
+func Extract(ctx context.Context) *logrus.Entry
+```
+Extract takes the call-scoped logrus.Entry from grpc_logrus middleware.
+Deprecated: should use the ctxlogrus.Extract instead
+
+#### Example:
+
+<details>
+<summary>Click to expand code.</summary>
+
+```go
+_ = func(ctx context.Context, ping *pb_testproto.PingRequest) (*pb_testproto.PingResponse, error) {
+ // Add fields the ctxtags of the request which will be added to all extracted loggers.
+ grpc_ctxtags.Extract(ctx).Set("custom_tags.string", "something").Set("custom_tags.int", 1337)
+ // Extract a single request-scoped logrus.Logger and log messages.
+ l := ctx_logrus.Extract(ctx)
+ l.Info("some ping")
+ l.Info("another ping")
+ return &pb_testproto.PingResponse{Value: ping.Value}, nil
+}
+```
+
+</details>
+
+## <a name="PayloadStreamClientInterceptor">func</a> [PayloadStreamClientInterceptor](./payload_interceptors.go#L74)
+``` go
+func PayloadStreamClientInterceptor(entry *logrus.Entry, decider grpc_logging.ClientPayloadLoggingDecider) grpc.StreamClientInterceptor
+```
+PayloadStreamServerInterceptor returns a new streaming client interceptor that logs the paylods of requests and responses.
+
+## <a name="PayloadStreamServerInterceptor">func</a> [PayloadStreamServerInterceptor](./payload_interceptors.go#L45)
+``` go
+func PayloadStreamServerInterceptor(entry *logrus.Entry, decider grpc_logging.ServerPayloadLoggingDecider) grpc.StreamServerInterceptor
+```
+PayloadUnaryServerInterceptor returns a new server server interceptors that logs the payloads of requests.
+
+This *only* works when placed *after* the `grpc_logrus.StreamServerInterceptor`. However, the logging can be done to a
+separate instance of the logger.
+
+## <a name="PayloadUnaryClientInterceptor">func</a> [PayloadUnaryClientInterceptor](./payload_interceptors.go#L58)
+``` go
+func PayloadUnaryClientInterceptor(entry *logrus.Entry, decider grpc_logging.ClientPayloadLoggingDecider) grpc.UnaryClientInterceptor
+```
+PayloadUnaryClientInterceptor returns a new unary client interceptor that logs the paylods of requests and responses.
+
+## <a name="PayloadUnaryServerInterceptor">func</a> [PayloadUnaryServerInterceptor](./payload_interceptors.go#L25)
+``` go
+func PayloadUnaryServerInterceptor(entry *logrus.Entry, decider grpc_logging.ServerPayloadLoggingDecider) grpc.UnaryServerInterceptor
+```
+PayloadUnaryServerInterceptor returns a new unary server interceptors that logs the payloads of requests.
+
+This *only* works when placed *after* the `grpc_logrus.UnaryServerInterceptor`. However, the logging can be done to a
+separate instance of the logger.
+
+## <a name="ReplaceGrpcLogger">func</a> [ReplaceGrpcLogger](./grpclogger.go#L13)
+``` go
+func ReplaceGrpcLogger(logger *logrus.Entry)
+```
+ReplaceGrpcLogger sets the given logrus.Logger as a gRPC-level logger.
+This should be called *before* any other initialization, preferably from init() functions.
+
+## <a name="StreamClientInterceptor">func</a> [StreamClientInterceptor](./client_interceptors.go#L28)
+``` go
+func StreamClientInterceptor(entry *logrus.Entry, opts ...Option) grpc.StreamClientInterceptor
+```
+StreamServerInterceptor returns a new streaming client interceptor that optionally logs the execution of external gRPC calls.
+
+## <a name="StreamServerInterceptor">func</a> [StreamServerInterceptor](./server_interceptors.go#L58)
+``` go
+func StreamServerInterceptor(entry *logrus.Entry, opts ...Option) grpc.StreamServerInterceptor
+```
+StreamServerInterceptor returns a new streaming server interceptor that adds logrus.Entry to the context.
+
+## <a name="UnaryClientInterceptor">func</a> [UnaryClientInterceptor](./client_interceptors.go#L16)
+``` go
+func UnaryClientInterceptor(entry *logrus.Entry, opts ...Option) grpc.UnaryClientInterceptor
+```
+UnaryClientInterceptor returns a new unary client interceptor that optionally logs the execution of external gRPC calls.
+
+## <a name="UnaryServerInterceptor">func</a> [UnaryServerInterceptor](./server_interceptors.go#L26)
+``` go
+func UnaryServerInterceptor(entry *logrus.Entry, opts ...Option) grpc.UnaryServerInterceptor
+```
+PayloadUnaryServerInterceptor returns a new unary server interceptors that adds logrus.Entry to the context.
+
+## <a name="CodeToLevel">type</a> [CodeToLevel](./options.go#L53)
+``` go
+type CodeToLevel func(code codes.Code) logrus.Level
+```
+CodeToLevel function defines the mapping between gRPC return codes and interceptor log level.
+
+## <a name="DurationToField">type</a> [DurationToField](./options.go#L56)
+``` go
+type DurationToField func(duration time.Duration) (key string, value interface{})
+```
+DurationToField function defines how to produce duration fields for logging
+
+## <a name="Option">type</a> [Option](./options.go#L50)
+``` go
+type Option func(*options)
+```
+
+### <a name="WithCodes">func</a> [WithCodes](./options.go#L73)
+``` go
+func WithCodes(f grpc_logging.ErrorToCode) Option
+```
+WithCodes customizes the function for mapping errors to error codes.
+
+### <a name="WithDecider">func</a> [WithDecider](./options.go#L59)
+``` go
+func WithDecider(f grpc_logging.Decider) Option
+```
+WithDecider customizes the function for deciding if the gRPC interceptor logs should log.
+
+#### Example:
+
+<details>
+<summary>Click to expand code.</summary>
+
+```go
+opts := []grpc_logrus.Option{
+ grpc_logrus.WithDecider(func(methodFullName string, err error) bool {
+ // will not log gRPC calls if it was a call to healthcheck and no error was raised
+ if err == nil && methodFullName == "blah.foo.healthcheck" {
+ return false
+ }
+
+ // by default you will log all calls
+ return true
+ }),
+}
+
+_ = []grpc.ServerOption{
+ grpc_middleware.WithStreamServerChain(
+ grpc_ctxtags.StreamServerInterceptor(),
+ grpc_logrus.StreamServerInterceptor(logrus.NewEntry(logrus.New()), opts...)),
+ grpc_middleware.WithUnaryServerChain(
+ grpc_ctxtags.UnaryServerInterceptor(),
+ grpc_logrus.UnaryServerInterceptor(logrus.NewEntry(logrus.New()), opts...)),
+}
+```
+
+</details>
+### <a name="WithDurationField">func</a> [WithDurationField](./options.go#L80)
+``` go
+func WithDurationField(f DurationToField) Option
+```
+WithDurationField customizes the function for mapping request durations to log fields.
+
+### <a name="WithLevels">func</a> [WithLevels](./options.go#L66)
+``` go
+func WithLevels(f CodeToLevel) Option
+```
+WithLevels customizes the function for mapping gRPC return codes and interceptor log level statements.
+
+- - -
+Generated by [godoc2ghmd](https://github.com/GandalfUK/godoc2ghmd) \ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/client_interceptors.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/client_interceptors.go
new file mode 100644
index 00000000..f7655ff6
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/client_interceptors.go
@@ -0,0 +1,65 @@
+// Copyright 2017 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+package grpc_logrus
+
+import (
+ "path"
+ "time"
+
+ "github.com/sirupsen/logrus"
+ "golang.org/x/net/context"
+ "google.golang.org/grpc"
+)
+
+// UnaryClientInterceptor returns a new unary client interceptor that optionally logs the execution of external gRPC calls.
+func UnaryClientInterceptor(entry *logrus.Entry, opts ...Option) grpc.UnaryClientInterceptor {
+ o := evaluateClientOpt(opts)
+ return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
+ fields := newClientLoggerFields(ctx, method)
+ startTime := time.Now()
+ err := invoker(ctx, method, req, reply, cc, opts...)
+ logFinalClientLine(o, entry.WithFields(fields), startTime, err, "finished client unary call")
+ return err
+ }
+}
+
+// StreamServerInterceptor returns a new streaming client interceptor that optionally logs the execution of external gRPC calls.
+func StreamClientInterceptor(entry *logrus.Entry, opts ...Option) grpc.StreamClientInterceptor {
+ o := evaluateClientOpt(opts)
+ return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
+ fields := newClientLoggerFields(ctx, method)
+ startTime := time.Now()
+ clientStream, err := streamer(ctx, desc, cc, method, opts...)
+ logFinalClientLine(o, entry.WithFields(fields), startTime, err, "finished client streaming call")
+ return clientStream, err
+ }
+}
+
+func logFinalClientLine(o *options, entry *logrus.Entry, startTime time.Time, err error, msg string) {
+ code := o.codeFunc(err)
+ level := o.levelFunc(code)
+ durField, durVal := o.durationFunc(time.Now().Sub(startTime))
+ fields := logrus.Fields{
+ "grpc.code": code.String(),
+ durField: durVal,
+ }
+ if err != nil {
+ fields[logrus.ErrorKey] = err
+ }
+ levelLogf(
+ entry.WithFields(fields),
+ level,
+ msg)
+}
+
+func newClientLoggerFields(ctx context.Context, fullMethodString string) logrus.Fields {
+ service := path.Dir(fullMethodString)[1:]
+ method := path.Base(fullMethodString)
+ return logrus.Fields{
+ SystemField: "grpc",
+ KindField: "client",
+ "grpc.service": service,
+ "grpc.method": method,
+ }
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/context.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/context.go
new file mode 100644
index 00000000..a39bb772
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/context.go
@@ -0,0 +1,19 @@
+package grpc_logrus
+
+import (
+ "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus"
+ "github.com/sirupsen/logrus"
+ "golang.org/x/net/context"
+)
+
+// AddFields adds logrus fields to the logger.
+// Deprecated: should use the ctxlogrus.Extract instead
+func AddFields(ctx context.Context, fields logrus.Fields) {
+ ctxlogrus.AddFields(ctx, fields)
+}
+
+// Extract takes the call-scoped logrus.Entry from grpc_logrus middleware.
+// Deprecated: should use the ctxlogrus.Extract instead
+func Extract(ctx context.Context) *logrus.Entry {
+ return ctxlogrus.Extract(ctx)
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus/DOC.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus/DOC.md
new file mode 100644
index 00000000..90918029
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus/DOC.md
@@ -0,0 +1,93 @@
+# ctxlogrus
+`import "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus"`
+
+* [Overview](#pkg-overview)
+* [Imported Packages](#pkg-imports)
+* [Index](#pkg-index)
+* [Examples](#pkg-examples)
+
+## <a name="pkg-overview">Overview</a>
+`ctxlogrus` is a ctxlogger that is backed by logrus
+
+It accepts a user-configured `logrus.Logger` that will be used for logging. The same `logrus.Logger` will
+be populated into the `context.Context` passed into gRPC handler code.
+
+You can use `ctx_logrus.Extract` to log into a request-scoped `logrus.Logger` instance in your handler code.
+
+As `ctx_logrus.Extract` will iterate all tags on from `grpc_ctxtags` it is therefore expensive so it is advised that you
+extract once at the start of the function from the context and reuse it for the remainder of the function (see examples).
+
+Please see examples and tests for examples of use.
+
+## <a name="pkg-imports">Imported Packages</a>
+
+- [github.com/grpc-ecosystem/go-grpc-middleware/tags](./../../../tags)
+- [github.com/sirupsen/logrus](https://godoc.org/github.com/sirupsen/logrus)
+- [golang.org/x/net/context](https://godoc.org/golang.org/x/net/context)
+
+## <a name="pkg-index">Index</a>
+* [func AddFields(ctx context.Context, fields logrus.Fields)](#AddFields)
+* [func Extract(ctx context.Context) \*logrus.Entry](#Extract)
+* [func ToContext(ctx context.Context, entry \*logrus.Entry) context.Context](#ToContext)
+
+#### <a name="pkg-examples">Examples</a>
+* [Extract (Unary)](#example_Extract_unary)
+
+#### <a name="pkg-files">Package files</a>
+[context.go](./context.go) [doc.go](./doc.go) [noop.go](./noop.go)
+
+## <a name="AddFields">func</a> [AddFields](./context.go#L21)
+``` go
+func AddFields(ctx context.Context, fields logrus.Fields)
+```
+AddFields adds logrus fields to the logger.
+
+## <a name="Extract">func</a> [Extract](./context.go#L35)
+``` go
+func Extract(ctx context.Context) *logrus.Entry
+```
+Extract takes the call-scoped logrus.Entry from ctx_logrus middleware.
+
+If the ctx_logrus middleware wasn't used, a no-op `logrus.Entry` is returned. This makes it safe to
+use regardless.
+
+#### Example:
+
+<details>
+<summary>Click to expand code.</summary>
+
+```go
+package ctxlogrus_test
+
+import (
+ "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus"
+ "github.com/grpc-ecosystem/go-grpc-middleware/tags"
+ "github.com/sirupsen/logrus"
+ "golang.org/x/net/context"
+)
+
+var logrusLogger *logrus.Logger
+
+// Simple unary handler that adds custom fields to the requests's context. These will be used for all log statements.
+func ExampleExtract_unary() {
+ ctx := context.Background()
+ // setting tags will be added to the logger as log fields
+ grpc_ctxtags.Extract(ctx).Set("custom_tags.string", "something").Set("custom_tags.int", 1337)
+ // Extract a single request-scoped logrus.Logger and log messages.
+ l := ctxlogrus.Extract(ctx)
+ l.Info("some ping")
+ l.Info("another ping")
+}
+```
+
+</details>
+
+## <a name="ToContext">func</a> [ToContext](./context.go#L59)
+``` go
+func ToContext(ctx context.Context, entry *logrus.Entry) context.Context
+```
+ToContext adds the logrus.Entry to the context for extraction later.
+Returning the new context that has been created.
+
+- - -
+Generated by [godoc2ghmd](https://github.com/GandalfUK/godoc2ghmd) \ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus/README.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus/README.md
new file mode 100644
index 00000000..fc1d0a92
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus/README.md
@@ -0,0 +1,58 @@
+# ctx_logrus
+`import "github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus"`
+
+* [Overview](#pkg-overview)
+* [Imported Packages](#pkg-imports)
+* [Index](#pkg-index)
+
+## <a name="pkg-overview">Overview</a>
+`ctx_logrus` is a ctxlogger that is backed by logrus
+
+It accepts a user-configured `logrus.Logger` that will be used for logging. The same `logrus.Logger` will
+be populated into the `context.Context` passed into gRPC handler code.
+
+You can use `ctx_logrus.Extract` to log into a request-scoped `logrus.Logger` instance in your handler code.
+
+As `ctx_logrus.Extract` will iterate all tags on from `grpc_ctxtags` it is therefore expensive so it is advised that you
+extract once at the start of the function from the context and reuse it for the remainder of the function (see examples).
+
+Please see examples and tests for examples of use.
+
+## <a name="pkg-imports">Imported Packages</a>
+
+- [github.com/grpc-ecosystem/go-grpc-middleware/tags](./..)
+- [github.com/sirupsen/logrus](https://godoc.org/github.com/sirupsen/logrus)
+- [golang.org/x/net/context](https://godoc.org/golang.org/x/net/context)
+
+## <a name="pkg-index">Index</a>
+* [func AddFields(ctx context.Context, fields logrus.Fields)](#AddFields)
+* [func Extract(ctx context.Context) \*logrus.Entry](#Extract)
+* [func ToContext(ctx context.Context, entry \*logrus.Entry) context.Context](#ToContext)
+
+#### <a name="pkg-files">Package files</a>
+[context.go](./context.go) [doc.go](./doc.go) [noop.go](./noop.go)
+
+## <a name="AddFields">func</a> [AddFields](./context.go#L21)
+``` go
+func AddFields(ctx context.Context, fields logrus.Fields)
+```
+AddFields adds logrus fields to the logger.
+
+## <a name="Extract">func</a> [Extract](./context.go#L35)
+``` go
+func Extract(ctx context.Context) *logrus.Entry
+```
+Extract takes the call-scoped logrus.Entry from ctx_logrus middleware.
+
+If the ctx_logrus middleware wasn't used, a no-op `logrus.Entry` is returned. This makes it safe to
+use regardless.
+
+## <a name="ToContext">func</a> [ToContext](./context.go#L59)
+``` go
+func ToContext(ctx context.Context, entry *logrus.Entry) context.Context
+```
+ToContext adds the logrus.Entry to the context for extraction later.
+Returning the new context that has been created.
+
+- - -
+Generated by [godoc2ghmd](https://github.com/GandalfUK/godoc2ghmd) \ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus/context.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus/context.go
new file mode 100644
index 00000000..ff3e3353
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus/context.go
@@ -0,0 +1,65 @@
+package ctxlogrus
+
+import (
+ "github.com/grpc-ecosystem/go-grpc-middleware/tags"
+ "github.com/sirupsen/logrus"
+ "golang.org/x/net/context"
+)
+
+type ctxLoggerMarker struct{}
+
+type ctxLogger struct {
+ logger *logrus.Entry
+ fields logrus.Fields
+}
+
+var (
+ ctxLoggerKey = &ctxLoggerMarker{}
+)
+
+// AddFields adds logrus fields to the logger.
+func AddFields(ctx context.Context, fields logrus.Fields) {
+ l, ok := ctx.Value(ctxLoggerKey).(*ctxLogger)
+ if !ok || l == nil {
+ return
+ }
+ for k, v := range fields {
+ l.fields[k] = v
+ }
+}
+
+// Extract takes the call-scoped logrus.Entry from ctx_logrus middleware.
+//
+// If the ctx_logrus middleware wasn't used, a no-op `logrus.Entry` is returned. This makes it safe to
+// use regardless.
+func Extract(ctx context.Context) *logrus.Entry {
+ l, ok := ctx.Value(ctxLoggerKey).(*ctxLogger)
+ if !ok || l == nil {
+ return logrus.NewEntry(nullLogger)
+ }
+
+ fields := logrus.Fields{}
+
+ // Add grpc_ctxtags tags metadata until now.
+ tags := grpc_ctxtags.Extract(ctx)
+ for k, v := range tags.Values() {
+ fields[k] = v
+ }
+
+ // Add logrus fields added until now.
+ for k, v := range l.fields {
+ fields[k] = v
+ }
+
+ return l.logger.WithFields(fields)
+}
+
+// ToContext adds the logrus.Entry to the context for extraction later.
+// Returning the new context that has been created.
+func ToContext(ctx context.Context, entry *logrus.Entry) context.Context {
+ l := &ctxLogger{
+ logger: entry,
+ fields: logrus.Fields{},
+ }
+ return context.WithValue(ctx, ctxLoggerKey, l)
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus/doc.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus/doc.go
new file mode 100644
index 00000000..95803fb6
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus/doc.go
@@ -0,0 +1,14 @@
+/*
+`ctxlogrus` is a ctxlogger that is backed by logrus
+
+It accepts a user-configured `logrus.Logger` that will be used for logging. The same `logrus.Logger` will
+be populated into the `context.Context` passed into gRPC handler code.
+
+You can use `ctx_logrus.Extract` to log into a request-scoped `logrus.Logger` instance in your handler code.
+
+As `ctx_logrus.Extract` will iterate all tags on from `grpc_ctxtags` it is therefore expensive so it is advised that you
+extract once at the start of the function from the context and reuse it for the remainder of the function (see examples).
+
+Please see examples and tests for examples of use.
+*/
+package ctxlogrus
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus/noop.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus/noop.go
new file mode 100644
index 00000000..7fcc0f64
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus/noop.go
@@ -0,0 +1,16 @@
+package ctxlogrus
+
+import (
+ "io/ioutil"
+
+ "github.com/sirupsen/logrus"
+)
+
+var (
+ nullLogger = &logrus.Logger{
+ Out: ioutil.Discard,
+ Formatter: new(logrus.TextFormatter),
+ Hooks: make(logrus.LevelHooks),
+ Level: logrus.PanicLevel,
+ }
+)
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/doc.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/doc.go
new file mode 100644
index 00000000..df8785f5
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/doc.go
@@ -0,0 +1,67 @@
+/*
+`grpc_logrus` is a gRPC logging middleware backed by Logrus loggers
+
+It accepts a user-configured `logrus.Entry` that will be used for logging completed gRPC calls. The same
+`logrus.Entry` will be used for logging completed gRPC calls, and be populated into the `context.Context` passed into gRPC handler code.
+
+On calling `StreamServerInterceptor` or `UnaryServerInterceptor` this logging middleware will add gRPC call information
+to the ctx so that it will be present on subsequent use of the `ctxlogrus` logger.
+
+This package also implements request and response *payload* logging, both for server-side and client-side. These will be
+logged as structured `jsonpb` fields for every message received/sent (both unary and streaming). For that please use
+`Payload*Interceptor` functions for that. Please note that the user-provided function that determines whetether to log
+the full request/response payload needs to be written with care, this can significantly slow down gRPC.
+
+If a deadline is present on the gRPC request the grpc.request.deadline tag is populated when the request begins. grpc.request.deadline
+is a string representing the time (RFC3339) when the current call will expire.
+
+Logrus can also be made as a backend for gRPC library internals. For that use `ReplaceGrpcLogger`.
+
+*Server Interceptor*
+Below is a JSON formatted example of a log that would be logged by the server interceptor:
+
+ {
+ "level": "info", // string logrus log levels
+ "msg": "finished unary call", // string log message
+ "grpc.code": "OK", // string grpc status code
+ "grpc.method": "Ping", // string method name
+ "grpc.service": "mwitkow.testproto.TestService", // string full name of the called service
+ "grpc.start_time": "2006-01-02T15:04:05Z07:00", // string RFC3339 representation of the start time
+ "grpc.request.deadline": "2006-01-02T15:04:05Z07:00", // string RFC3339 deadline of the current request if supplied
+ "grpc.request.value": "something", // string value on the request
+ "grpc.time_ms": 1.234, // float32 run time of the call in ms
+ "peer.address": {
+ "IP": "127.0.0.1", // string IP address of calling party
+ "Port": 60216, // int port call is coming in on
+ "Zone": "" // string peer zone for caller
+ },
+ "span.kind": "server", // string client | server
+ "system": "grpc" // string
+
+ "custom_field": "custom_value", // string user defined field
+ "custom_tags.int": 1337, // int user defined tag on the ctx
+ "custom_tags.string": "something", // string user defined tag on the ctx
+ }
+
+*Payload Interceptor*
+Below is a JSON formatted example of a log that would be logged by the payload interceptor:
+
+ {
+ "level": "info", // string logrus log levels
+ "msg": "client request payload logged as grpc.request.content", // string log message
+
+ "grpc.request.content": { // object content of RPC request
+ "value": "something", // string defined by caller
+ "sleepTimeMs": 9999 // int defined by caller
+ },
+ "grpc.method": "Ping", // string method being called
+ "grpc.service": "mwitkow.testproto.TestService", // string service being called
+ "span.kind": "client", // string client | server
+ "system": "grpc" // string
+ }
+
+Note - due to implementation ZAP differs from Logrus in the "grpc.request.content" object by having an inner "msg" object.
+
+Please see examples and tests for examples of use.
+*/
+package grpc_logrus
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/grpclogger.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/grpclogger.go
new file mode 100644
index 00000000..c0f6c5ab
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/grpclogger.go
@@ -0,0 +1,15 @@
+// Copyright 2017 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+package grpc_logrus
+
+import (
+ "github.com/sirupsen/logrus"
+ "google.golang.org/grpc/grpclog"
+)
+
+// ReplaceGrpcLogger sets the given logrus.Logger as a gRPC-level logger.
+// This should be called *before* any other initialization, preferably from init() functions.
+func ReplaceGrpcLogger(logger *logrus.Entry) {
+ grpclog.SetLogger(logger.WithField("system", SystemField))
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/options.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/options.go
new file mode 100644
index 00000000..b2b35189
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/options.go
@@ -0,0 +1,185 @@
+// Copyright 2017 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+package grpc_logrus
+
+import (
+ "time"
+
+ "github.com/grpc-ecosystem/go-grpc-middleware/logging"
+ "github.com/sirupsen/logrus"
+ "google.golang.org/grpc/codes"
+)
+
+var (
+ defaultOptions = &options{
+ levelFunc: nil,
+ shouldLog: grpc_logging.DefaultDeciderMethod,
+ codeFunc: grpc_logging.DefaultErrorToCode,
+ durationFunc: DefaultDurationToField,
+ }
+)
+
+type options struct {
+ levelFunc CodeToLevel
+ shouldLog grpc_logging.Decider
+ codeFunc grpc_logging.ErrorToCode
+ durationFunc DurationToField
+}
+
+func evaluateServerOpt(opts []Option) *options {
+ optCopy := &options{}
+ *optCopy = *defaultOptions
+ optCopy.levelFunc = DefaultCodeToLevel
+ for _, o := range opts {
+ o(optCopy)
+ }
+ return optCopy
+}
+
+func evaluateClientOpt(opts []Option) *options {
+ optCopy := &options{}
+ *optCopy = *defaultOptions
+ optCopy.levelFunc = DefaultClientCodeToLevel
+ for _, o := range opts {
+ o(optCopy)
+ }
+ return optCopy
+}
+
+type Option func(*options)
+
+// CodeToLevel function defines the mapping between gRPC return codes and interceptor log level.
+type CodeToLevel func(code codes.Code) logrus.Level
+
+// DurationToField function defines how to produce duration fields for logging
+type DurationToField func(duration time.Duration) (key string, value interface{})
+
+// WithDecider customizes the function for deciding if the gRPC interceptor logs should log.
+func WithDecider(f grpc_logging.Decider) Option {
+ return func(o *options) {
+ o.shouldLog = f
+ }
+}
+
+// WithLevels customizes the function for mapping gRPC return codes and interceptor log level statements.
+func WithLevels(f CodeToLevel) Option {
+ return func(o *options) {
+ o.levelFunc = f
+ }
+}
+
+// WithCodes customizes the function for mapping errors to error codes.
+func WithCodes(f grpc_logging.ErrorToCode) Option {
+ return func(o *options) {
+ o.codeFunc = f
+ }
+}
+
+// WithDurationField customizes the function for mapping request durations to log fields.
+func WithDurationField(f DurationToField) Option {
+ return func(o *options) {
+ o.durationFunc = f
+ }
+}
+
+// DefaultCodeToLevel is the default implementation of gRPC return codes to log levels for server side.
+func DefaultCodeToLevel(code codes.Code) logrus.Level {
+ switch code {
+ case codes.OK:
+ return logrus.InfoLevel
+ case codes.Canceled:
+ return logrus.InfoLevel
+ case codes.Unknown:
+ return logrus.ErrorLevel
+ case codes.InvalidArgument:
+ return logrus.InfoLevel
+ case codes.DeadlineExceeded:
+ return logrus.WarnLevel
+ case codes.NotFound:
+ return logrus.InfoLevel
+ case codes.AlreadyExists:
+ return logrus.InfoLevel
+ case codes.PermissionDenied:
+ return logrus.WarnLevel
+ case codes.Unauthenticated:
+ return logrus.InfoLevel // unauthenticated requests can happen
+ case codes.ResourceExhausted:
+ return logrus.WarnLevel
+ case codes.FailedPrecondition:
+ return logrus.WarnLevel
+ case codes.Aborted:
+ return logrus.WarnLevel
+ case codes.OutOfRange:
+ return logrus.WarnLevel
+ case codes.Unimplemented:
+ return logrus.ErrorLevel
+ case codes.Internal:
+ return logrus.ErrorLevel
+ case codes.Unavailable:
+ return logrus.WarnLevel
+ case codes.DataLoss:
+ return logrus.ErrorLevel
+ default:
+ return logrus.ErrorLevel
+ }
+}
+
+// DefaultClientCodeToLevel is the default implementation of gRPC return codes to log levels for client side.
+func DefaultClientCodeToLevel(code codes.Code) logrus.Level {
+ switch code {
+ case codes.OK:
+ return logrus.DebugLevel
+ case codes.Canceled:
+ return logrus.DebugLevel
+ case codes.Unknown:
+ return logrus.InfoLevel
+ case codes.InvalidArgument:
+ return logrus.DebugLevel
+ case codes.DeadlineExceeded:
+ return logrus.InfoLevel
+ case codes.NotFound:
+ return logrus.DebugLevel
+ case codes.AlreadyExists:
+ return logrus.DebugLevel
+ case codes.PermissionDenied:
+ return logrus.InfoLevel
+ case codes.Unauthenticated:
+ return logrus.InfoLevel // unauthenticated requests can happen
+ case codes.ResourceExhausted:
+ return logrus.DebugLevel
+ case codes.FailedPrecondition:
+ return logrus.DebugLevel
+ case codes.Aborted:
+ return logrus.DebugLevel
+ case codes.OutOfRange:
+ return logrus.DebugLevel
+ case codes.Unimplemented:
+ return logrus.WarnLevel
+ case codes.Internal:
+ return logrus.WarnLevel
+ case codes.Unavailable:
+ return logrus.WarnLevel
+ case codes.DataLoss:
+ return logrus.WarnLevel
+ default:
+ return logrus.InfoLevel
+ }
+}
+
+// DefaultDurationToField is the default implementation of converting request duration to a log field (key and value).
+var DefaultDurationToField = DurationToTimeMillisField
+
+// DurationToTimeMillisField converts the duration to milliseconds and uses the key `grpc.time_ms`.
+func DurationToTimeMillisField(duration time.Duration) (key string, value interface{}) {
+ return "grpc.time_ms", durationToMilliseconds(duration)
+}
+
+// DurationToDurationField uses the duration value to log the request duration.
+func DurationToDurationField(duration time.Duration) (key string, value interface{}) {
+ return "grpc.duration", duration
+}
+
+func durationToMilliseconds(duration time.Duration) float32 {
+ return float32(duration.Nanoseconds()/1000) / 1000
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/payload_interceptors.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/payload_interceptors.go
new file mode 100644
index 00000000..6ac4d04a
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/payload_interceptors.go
@@ -0,0 +1,144 @@
+package grpc_logrus
+
+import (
+ "bytes"
+ "fmt"
+
+ "github.com/golang/protobuf/jsonpb"
+ "github.com/golang/protobuf/proto"
+ "github.com/grpc-ecosystem/go-grpc-middleware/logging"
+ "github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus"
+ "github.com/sirupsen/logrus"
+ "golang.org/x/net/context"
+ "google.golang.org/grpc"
+)
+
+var (
+ // JsonPBMarshaller is the marshaller used for serializing protobuf messages.
+ JsonPbMarshaller = &jsonpb.Marshaler{}
+)
+
+// PayloadUnaryServerInterceptor returns a new unary server interceptors that logs the payloads of requests.
+//
+// This *only* works when placed *after* the `grpc_logrus.UnaryServerInterceptor`. However, the logging can be done to a
+// separate instance of the logger.
+func PayloadUnaryServerInterceptor(entry *logrus.Entry, decider grpc_logging.ServerPayloadLoggingDecider) grpc.UnaryServerInterceptor {
+ return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
+ if !decider(ctx, info.FullMethod, info.Server) {
+ return handler(ctx, req)
+ }
+ // Use the provided logrus.Entry for logging but use the fields from context.
+ logEntry := entry.WithFields(ctx_logrus.Extract(ctx).Data)
+ logProtoMessageAsJson(logEntry, req, "grpc.request.content", "server request payload logged as grpc.request.content field")
+ resp, err := handler(ctx, req)
+ if err == nil {
+ logProtoMessageAsJson(logEntry, resp, "grpc.response.content", "server response payload logged as grpc.request.content field")
+ }
+ return resp, err
+ }
+}
+
+// PayloadUnaryServerInterceptor returns a new server server interceptors that logs the payloads of requests.
+//
+// This *only* works when placed *after* the `grpc_logrus.StreamServerInterceptor`. However, the logging can be done to a
+// separate instance of the logger.
+func PayloadStreamServerInterceptor(entry *logrus.Entry, decider grpc_logging.ServerPayloadLoggingDecider) grpc.StreamServerInterceptor {
+ return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
+ if !decider(stream.Context(), info.FullMethod, srv) {
+ return handler(srv, stream)
+ }
+ // Use the provided logrus.Entry for logging but use the fields from context.
+ logEntry := entry.WithFields(Extract(stream.Context()).Data)
+ newStream := &loggingServerStream{ServerStream: stream, entry: logEntry}
+ return handler(srv, newStream)
+ }
+}
+
+// PayloadUnaryClientInterceptor returns a new unary client interceptor that logs the paylods of requests and responses.
+func PayloadUnaryClientInterceptor(entry *logrus.Entry, decider grpc_logging.ClientPayloadLoggingDecider) grpc.UnaryClientInterceptor {
+ return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
+ if !decider(ctx, method) {
+ return invoker(ctx, method, req, reply, cc, opts...)
+ }
+ logEntry := entry.WithFields(newClientLoggerFields(ctx, method))
+ logProtoMessageAsJson(logEntry, req, "grpc.request.content", "client request payload logged as grpc.request.content")
+ err := invoker(ctx, method, req, reply, cc, opts...)
+ if err == nil {
+ logProtoMessageAsJson(logEntry, reply, "grpc.response.content", "client response payload logged as grpc.response.content")
+ }
+ return err
+ }
+}
+
+// PayloadStreamServerInterceptor returns a new streaming client interceptor that logs the paylods of requests and responses.
+func PayloadStreamClientInterceptor(entry *logrus.Entry, decider grpc_logging.ClientPayloadLoggingDecider) grpc.StreamClientInterceptor {
+ return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
+ if !decider(ctx, method) {
+ return streamer(ctx, desc, cc, method, opts...)
+ }
+ logEntry := entry.WithFields(newClientLoggerFields(ctx, method))
+ clientStream, err := streamer(ctx, desc, cc, method, opts...)
+ newStream := &loggingClientStream{ClientStream: clientStream, entry: logEntry}
+ return newStream, err
+ }
+}
+
+type loggingClientStream struct {
+ grpc.ClientStream
+ entry *logrus.Entry
+}
+
+func (l *loggingClientStream) SendMsg(m interface{}) error {
+ err := l.ClientStream.SendMsg(m)
+ if err == nil {
+ logProtoMessageAsJson(l.entry, m, "grpc.request.content", "server request payload logged as grpc.request.content field")
+ }
+ return err
+}
+
+func (l *loggingClientStream) RecvMsg(m interface{}) error {
+ err := l.ClientStream.RecvMsg(m)
+ if err == nil {
+ logProtoMessageAsJson(l.entry, m, "grpc.response.content", "server response payload logged as grpc.response.content field")
+ }
+ return err
+}
+
+type loggingServerStream struct {
+ grpc.ServerStream
+ entry *logrus.Entry
+}
+
+func (l *loggingServerStream) SendMsg(m interface{}) error {
+ err := l.ServerStream.SendMsg(m)
+ if err == nil {
+ logProtoMessageAsJson(l.entry, m, "grpc.response.content", "server response payload logged as grpc.response.content field")
+ }
+ return err
+}
+
+func (l *loggingServerStream) RecvMsg(m interface{}) error {
+ err := l.ServerStream.RecvMsg(m)
+ if err == nil {
+ logProtoMessageAsJson(l.entry, m, "grpc.request.content", "server request payload logged as grpc.request.content field")
+ }
+ return err
+}
+
+func logProtoMessageAsJson(entry *logrus.Entry, pbMsg interface{}, key string, msg string) {
+ if p, ok := pbMsg.(proto.Message); ok {
+ entry.WithField(key, &jsonpbMarshalleble{p}).Info(msg)
+ }
+}
+
+type jsonpbMarshalleble struct {
+ proto.Message
+}
+
+func (j *jsonpbMarshalleble) MarshalJSON() ([]byte, error) {
+ b := &bytes.Buffer{}
+ if err := JsonPbMarshaller.Marshal(b, j.Message); err != nil {
+ return nil, fmt.Errorf("jsonpb serializer failed: %v", err)
+ }
+ return b.Bytes(), nil
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/server_interceptors.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/server_interceptors.go
new file mode 100644
index 00000000..0711d881
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/server_interceptors.go
@@ -0,0 +1,129 @@
+// Copyright (c) Improbable Worlds Ltd, All Rights Reserved
+
+package grpc_logrus
+
+import (
+ "path"
+ "time"
+
+ "github.com/grpc-ecosystem/go-grpc-middleware"
+ "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus"
+ "github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus"
+ "github.com/sirupsen/logrus"
+ "golang.org/x/net/context"
+ "google.golang.org/grpc"
+)
+
+var (
+ // SystemField is used in every log statement made through grpc_logrus. Can be overwritten before any initialization code.
+ SystemField = "system"
+
+ // KindField describes the log gield used to incicate whether this is a server or a client log statment.
+ KindField = "span.kind"
+)
+
+// PayloadUnaryServerInterceptor returns a new unary server interceptors that adds logrus.Entry to the context.
+func UnaryServerInterceptor(entry *logrus.Entry, opts ...Option) grpc.UnaryServerInterceptor {
+ o := evaluateServerOpt(opts)
+ return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
+ startTime := time.Now()
+ newCtx := newLoggerForCall(ctx, entry, info.FullMethod, startTime)
+
+ resp, err := handler(newCtx, req)
+
+ if !o.shouldLog(info.FullMethod, err) {
+ return resp, err
+ }
+ code := o.codeFunc(err)
+ level := o.levelFunc(code)
+ durField, durVal := o.durationFunc(time.Since(startTime))
+ fields := logrus.Fields{
+ "grpc.code": code.String(),
+ durField: durVal,
+ }
+ if err != nil {
+ fields[logrus.ErrorKey] = err
+ }
+
+ levelLogf(
+ ctx_logrus.Extract(newCtx).WithFields(fields), // re-extract logger from newCtx, as it may have extra fields that changed in the holder.
+ level,
+ "finished unary call with code "+code.String())
+
+ return resp, err
+ }
+}
+
+// StreamServerInterceptor returns a new streaming server interceptor that adds logrus.Entry to the context.
+func StreamServerInterceptor(entry *logrus.Entry, opts ...Option) grpc.StreamServerInterceptor {
+ o := evaluateServerOpt(opts)
+ return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
+ startTime := time.Now()
+ newCtx := newLoggerForCall(stream.Context(), entry, info.FullMethod, startTime)
+ wrapped := grpc_middleware.WrapServerStream(stream)
+ wrapped.WrappedContext = newCtx
+
+ err := handler(srv, wrapped)
+
+ if !o.shouldLog(info.FullMethod, err) {
+ return err
+ }
+ code := o.codeFunc(err)
+ level := o.levelFunc(code)
+ durField, durVal := o.durationFunc(time.Since(startTime))
+ fields := logrus.Fields{
+ "grpc.code": code.String(),
+ durField: durVal,
+ }
+ if err != nil {
+ fields[logrus.ErrorKey] = err
+ }
+
+ levelLogf(
+ ctx_logrus.Extract(newCtx).WithFields(fields), // re-extract logger from newCtx, as it may have extra fields that changed in the holder.
+ level,
+ "finished streaming call with code "+code.String())
+
+ return err
+ }
+}
+
+func levelLogf(entry *logrus.Entry, level logrus.Level, format string, args ...interface{}) {
+ switch level {
+ case logrus.DebugLevel:
+ entry.Debugf(format, args...)
+ case logrus.InfoLevel:
+ entry.Infof(format, args...)
+ case logrus.WarnLevel:
+ entry.Warningf(format, args...)
+ case logrus.ErrorLevel:
+ entry.Errorf(format, args...)
+ case logrus.FatalLevel:
+ entry.Fatalf(format, args...)
+ case logrus.PanicLevel:
+ entry.Panicf(format, args...)
+ }
+}
+
+func newLoggerForCall(ctx context.Context, entry *logrus.Entry, fullMethodString string, start time.Time) context.Context {
+ service := path.Dir(fullMethodString)[1:]
+ method := path.Base(fullMethodString)
+ callLog := entry.WithFields(
+ logrus.Fields{
+ SystemField: "grpc",
+ KindField: "server",
+ "grpc.service": service,
+ "grpc.method": method,
+ "grpc.start_time": start.Format(time.RFC3339),
+ })
+
+ if d, ok := ctx.Deadline(); ok {
+ callLog = callLog.WithFields(
+ logrus.Fields{
+ "grpc.request.deadline": d.Format(time.RFC3339),
+ })
+ }
+
+ callLog = callLog.WithFields(ctx_logrus.Extract(ctx).Data)
+ return ctxlogrus.ToContext(ctx, callLog)
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/makefile b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/makefile
new file mode 100644
index 00000000..4ad54c37
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/makefile
@@ -0,0 +1,19 @@
+SHELL="/bin/bash"
+
+GOFILES_NOVENDOR = $(shell go list ./... | grep -v /vendor/)
+
+all: vet fmt docs test
+
+docs:
+ ./scripts/fixup.sh
+
+fmt:
+ go fmt $(GOFILES_NOVENDOR)
+
+vet:
+ go vet $(GOFILES_NOVENDOR)
+
+test: vet
+ ./scripts/test_all.sh
+
+.PHONY: all docs validate test
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/DOC.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/DOC.md
new file mode 100644
index 00000000..d4ef78af
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/DOC.md
@@ -0,0 +1,107 @@
+# grpc_recovery
+`import "github.com/grpc-ecosystem/go-grpc-middleware/recovery"`
+
+* [Overview](#pkg-overview)
+* [Imported Packages](#pkg-imports)
+* [Index](#pkg-index)
+* [Examples](#pkg-examples)
+
+## <a name="pkg-overview">Overview</a>
+`grpc_recovery` are intereceptors that recover from gRPC handler panics.
+
+### Server Side Recovery Middleware
+By default a panic will be converted into a gRPC error with `code.Internal`.
+
+Handling can be customised by providing an alternate recovery function.
+
+Please see examples for simple examples of use.
+
+#### Example:
+
+<details>
+<summary>Click to expand code.</summary>
+
+```go
+package grpc_recovery_test
+
+import (
+ "github.com/grpc-ecosystem/go-grpc-middleware"
+ "github.com/grpc-ecosystem/go-grpc-middleware/recovery"
+ "google.golang.org/grpc"
+)
+
+var (
+ customFunc grpc_recovery.RecoveryHandlerFunc
+)
+
+// Initialization shows an initialization sequence with a custom recovery handler func.
+func Example_initialization() {
+ // Shared options for the logger, with a custom gRPC code to log level function.
+ opts := []grpc_recovery.Option{
+ grpc_recovery.WithRecoveryHandler(customFunc),
+ }
+ // Create a server. Recovery handlers should typically be last in the chain so that other middleware
+ // (e.g. logging) can operate on the recovered state instead of being directly affected by any panic
+ _ = grpc.NewServer(
+ grpc_middleware.WithUnaryServerChain(
+ grpc_recovery.UnaryServerInterceptor(opts...),
+ ),
+ grpc_middleware.WithStreamServerChain(
+ grpc_recovery.StreamServerInterceptor(opts...),
+ ),
+ )
+}
+```
+
+</details>
+
+## <a name="pkg-imports">Imported Packages</a>
+
+- [golang.org/x/net/context](https://godoc.org/golang.org/x/net/context)
+- [google.golang.org/grpc](https://godoc.org/google.golang.org/grpc)
+- [google.golang.org/grpc/codes](https://godoc.org/google.golang.org/grpc/codes)
+
+## <a name="pkg-index">Index</a>
+* [func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor](#StreamServerInterceptor)
+* [func UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor](#UnaryServerInterceptor)
+* [type Option](#Option)
+ * [func WithRecoveryHandler(f RecoveryHandlerFunc) Option](#WithRecoveryHandler)
+* [type RecoveryHandlerFunc](#RecoveryHandlerFunc)
+
+#### <a name="pkg-examples">Examples</a>
+* [Package (Initialization)](#example__initialization)
+
+#### <a name="pkg-files">Package files</a>
+[doc.go](./doc.go) [interceptors.go](./interceptors.go) [options.go](./options.go)
+
+## <a name="StreamServerInterceptor">func</a> [StreamServerInterceptor](./interceptors.go#L30)
+``` go
+func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor
+```
+StreamServerInterceptor returns a new streaming server interceptor for panic recovery.
+
+## <a name="UnaryServerInterceptor">func</a> [UnaryServerInterceptor](./interceptors.go#L16)
+``` go
+func UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor
+```
+UnaryServerInterceptor returns a new unary server interceptor for panic recovery.
+
+## <a name="Option">type</a> [Option](./options.go#L25)
+``` go
+type Option func(*options)
+```
+
+### <a name="WithRecoveryHandler">func</a> [WithRecoveryHandler](./options.go#L28)
+``` go
+func WithRecoveryHandler(f RecoveryHandlerFunc) Option
+```
+WithRecoveryHandler customizes the function for recovering from a panic.
+
+## <a name="RecoveryHandlerFunc">type</a> [RecoveryHandlerFunc](./interceptors.go#L13)
+``` go
+type RecoveryHandlerFunc func(p interface{}) (err error)
+```
+RecoveryHandlerFunc is a function that recovers from the panic `p` by returning an `error`.
+
+- - -
+Generated by [godoc2ghmd](https://github.com/GandalfUK/godoc2ghmd) \ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/README.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/README.md
new file mode 100644
index 00000000..d4ef78af
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/README.md
@@ -0,0 +1,107 @@
+# grpc_recovery
+`import "github.com/grpc-ecosystem/go-grpc-middleware/recovery"`
+
+* [Overview](#pkg-overview)
+* [Imported Packages](#pkg-imports)
+* [Index](#pkg-index)
+* [Examples](#pkg-examples)
+
+## <a name="pkg-overview">Overview</a>
+`grpc_recovery` are intereceptors that recover from gRPC handler panics.
+
+### Server Side Recovery Middleware
+By default a panic will be converted into a gRPC error with `code.Internal`.
+
+Handling can be customised by providing an alternate recovery function.
+
+Please see examples for simple examples of use.
+
+#### Example:
+
+<details>
+<summary>Click to expand code.</summary>
+
+```go
+package grpc_recovery_test
+
+import (
+ "github.com/grpc-ecosystem/go-grpc-middleware"
+ "github.com/grpc-ecosystem/go-grpc-middleware/recovery"
+ "google.golang.org/grpc"
+)
+
+var (
+ customFunc grpc_recovery.RecoveryHandlerFunc
+)
+
+// Initialization shows an initialization sequence with a custom recovery handler func.
+func Example_initialization() {
+ // Shared options for the logger, with a custom gRPC code to log level function.
+ opts := []grpc_recovery.Option{
+ grpc_recovery.WithRecoveryHandler(customFunc),
+ }
+ // Create a server. Recovery handlers should typically be last in the chain so that other middleware
+ // (e.g. logging) can operate on the recovered state instead of being directly affected by any panic
+ _ = grpc.NewServer(
+ grpc_middleware.WithUnaryServerChain(
+ grpc_recovery.UnaryServerInterceptor(opts...),
+ ),
+ grpc_middleware.WithStreamServerChain(
+ grpc_recovery.StreamServerInterceptor(opts...),
+ ),
+ )
+}
+```
+
+</details>
+
+## <a name="pkg-imports">Imported Packages</a>
+
+- [golang.org/x/net/context](https://godoc.org/golang.org/x/net/context)
+- [google.golang.org/grpc](https://godoc.org/google.golang.org/grpc)
+- [google.golang.org/grpc/codes](https://godoc.org/google.golang.org/grpc/codes)
+
+## <a name="pkg-index">Index</a>
+* [func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor](#StreamServerInterceptor)
+* [func UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor](#UnaryServerInterceptor)
+* [type Option](#Option)
+ * [func WithRecoveryHandler(f RecoveryHandlerFunc) Option](#WithRecoveryHandler)
+* [type RecoveryHandlerFunc](#RecoveryHandlerFunc)
+
+#### <a name="pkg-examples">Examples</a>
+* [Package (Initialization)](#example__initialization)
+
+#### <a name="pkg-files">Package files</a>
+[doc.go](./doc.go) [interceptors.go](./interceptors.go) [options.go](./options.go)
+
+## <a name="StreamServerInterceptor">func</a> [StreamServerInterceptor](./interceptors.go#L30)
+``` go
+func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor
+```
+StreamServerInterceptor returns a new streaming server interceptor for panic recovery.
+
+## <a name="UnaryServerInterceptor">func</a> [UnaryServerInterceptor](./interceptors.go#L16)
+``` go
+func UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor
+```
+UnaryServerInterceptor returns a new unary server interceptor for panic recovery.
+
+## <a name="Option">type</a> [Option](./options.go#L25)
+``` go
+type Option func(*options)
+```
+
+### <a name="WithRecoveryHandler">func</a> [WithRecoveryHandler](./options.go#L28)
+``` go
+func WithRecoveryHandler(f RecoveryHandlerFunc) Option
+```
+WithRecoveryHandler customizes the function for recovering from a panic.
+
+## <a name="RecoveryHandlerFunc">type</a> [RecoveryHandlerFunc](./interceptors.go#L13)
+``` go
+type RecoveryHandlerFunc func(p interface{}) (err error)
+```
+RecoveryHandlerFunc is a function that recovers from the panic `p` by returning an `error`.
+
+- - -
+Generated by [godoc2ghmd](https://github.com/GandalfUK/godoc2ghmd) \ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/doc.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/doc.go
new file mode 100644
index 00000000..da40190c
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/doc.go
@@ -0,0 +1,15 @@
+// Copyright 2017 David Ackroyd. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+/*
+`grpc_recovery` are intereceptors that recover from gRPC handler panics.
+
+Server Side Recovery Middleware
+
+By default a panic will be converted into a gRPC error with `code.Internal`.
+
+Handling can be customised by providing an alternate recovery function.
+
+Please see examples for simple examples of use.
+*/
+package grpc_recovery
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/interceptors.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/interceptors.go
new file mode 100644
index 00000000..c0fb5ac8
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/interceptors.go
@@ -0,0 +1,48 @@
+// Copyright 2017 David Ackroyd. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+package grpc_recovery
+
+import (
+ "golang.org/x/net/context"
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/codes"
+)
+
+// RecoveryHandlerFunc is a function that recovers from the panic `p` by returning an `error`.
+type RecoveryHandlerFunc func(p interface{}) (err error)
+
+// UnaryServerInterceptor returns a new unary server interceptor for panic recovery.
+func UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor {
+ o := evaluateOptions(opts)
+ return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (_ interface{}, err error) {
+ defer func() {
+ if r := recover(); r != nil {
+ err = recoverFrom(r, o.recoveryHandlerFunc)
+ }
+ }()
+
+ return handler(ctx, req)
+ }
+}
+
+// StreamServerInterceptor returns a new streaming server interceptor for panic recovery.
+func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor {
+ o := evaluateOptions(opts)
+ return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) (err error) {
+ defer func() {
+ if r := recover(); r != nil {
+ err = recoverFrom(r, o.recoveryHandlerFunc)
+ }
+ }()
+
+ return handler(srv, stream)
+ }
+}
+
+func recoverFrom(p interface{}, r RecoveryHandlerFunc) error {
+ if r == nil {
+ return grpc.Errorf(codes.Internal, "%s", p)
+ }
+ return r(p)
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/options.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/options.go
new file mode 100644
index 00000000..e482d7a5
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/options.go
@@ -0,0 +1,32 @@
+// Copyright 2017 David Ackroyd. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+package grpc_recovery
+
+var (
+ defaultOptions = &options{
+ recoveryHandlerFunc: nil,
+ }
+)
+
+type options struct {
+ recoveryHandlerFunc RecoveryHandlerFunc
+}
+
+func evaluateOptions(opts []Option) *options {
+ optCopy := &options{}
+ *optCopy = *defaultOptions
+ for _, o := range opts {
+ o(optCopy)
+ }
+ return optCopy
+}
+
+type Option func(*options)
+
+// WithRecoveryHandler customizes the function for recovering from a panic.
+func WithRecoveryHandler(f RecoveryHandlerFunc) Option {
+ return func(o *options) {
+ o.recoveryHandlerFunc = f
+ }
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/DOC.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/DOC.md
new file mode 100644
index 00000000..b954b1f9
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/DOC.md
@@ -0,0 +1,188 @@
+# grpc_ctxtags
+`import "github.com/grpc-ecosystem/go-grpc-middleware/tags"`
+
+* [Overview](#pkg-overview)
+* [Imported Packages](#pkg-imports)
+* [Index](#pkg-index)
+* [Examples](#pkg-examples)
+
+## <a name="pkg-overview">Overview</a>
+`grpc_ctxtags` adds a Tag object to the context that can be used by other middleware to add context about a request.
+
+### Request Context Tags
+Tags describe information about the request, and can be set and used by other middleware, or handlers. Tags are used
+for logging and tracing of requests. Tags are populated both upwards, *and* downwards in the interceptor-handler stack.
+
+You can automatically extract tags (in `grpc.request.<field_name>`) from request payloads.
+
+For unary and server-streaming methods, pass in the `WithFieldExtractor` option. For client-streams and bidirectional-streams, you can
+use `WithFieldExtractorForInitialReq` which will extract the tags from the first message passed from client to server.
+Note the tags will not be modified for subsequent requests, so this option only makes sense when the initial message
+establishes the meta-data for the stream.
+
+If a user doesn't use the interceptors that initialize the `Tags` object, all operations following from an `Extract(ctx)`
+will be no-ops. This is to ensure that code doesn't panic if the interceptors weren't used.
+
+Tags fields are typed, and shallow and should follow the OpenTracing semantics convention:
+<a href="https://github.com/opentracing/specification/blob/master/semantic_conventions.md">https://github.com/opentracing/specification/blob/master/semantic_conventions.md</a>
+
+#### Example:
+
+<details>
+<summary>Click to expand code.</summary>
+
+```go
+opts := []grpc_ctxtags.Option{
+ grpc_ctxtags.WithFieldExtractorForInitialReq(grpc_ctxtags.TagBasedRequestFieldExtractor("log_fields")),
+}
+_ = grpc.NewServer(
+ grpc.StreamInterceptor(grpc_ctxtags.StreamServerInterceptor(opts...)),
+ grpc.UnaryInterceptor(grpc_ctxtags.UnaryServerInterceptor(opts...)),
+)
+```
+
+</details>
+
+#### Example:
+
+<details>
+<summary>Click to expand code.</summary>
+
+```go
+opts := []grpc_ctxtags.Option{
+ grpc_ctxtags.WithFieldExtractor(grpc_ctxtags.TagBasedRequestFieldExtractor("log_fields")),
+}
+_ = grpc.NewServer(
+ grpc.StreamInterceptor(grpc_ctxtags.StreamServerInterceptor(opts...)),
+ grpc.UnaryInterceptor(grpc_ctxtags.UnaryServerInterceptor(opts...)),
+)
+```
+
+</details>
+
+## <a name="pkg-imports">Imported Packages</a>
+
+- [github.com/grpc-ecosystem/go-grpc-middleware](./..)
+- [golang.org/x/net/context](https://godoc.org/golang.org/x/net/context)
+- [google.golang.org/grpc](https://godoc.org/google.golang.org/grpc)
+- [google.golang.org/grpc/peer](https://godoc.org/google.golang.org/grpc/peer)
+
+## <a name="pkg-index">Index</a>
+* [func CodeGenRequestFieldExtractor(fullMethod string, req interface{}) map[string]interface{}](#CodeGenRequestFieldExtractor)
+* [func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor](#StreamServerInterceptor)
+* [func UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor](#UnaryServerInterceptor)
+* [type Option](#Option)
+ * [func WithFieldExtractor(f RequestFieldExtractorFunc) Option](#WithFieldExtractor)
+ * [func WithFieldExtractorForInitialReq(f RequestFieldExtractorFunc) Option](#WithFieldExtractorForInitialReq)
+* [type RequestFieldExtractorFunc](#RequestFieldExtractorFunc)
+ * [func TagBasedRequestFieldExtractor(tagName string) RequestFieldExtractorFunc](#TagBasedRequestFieldExtractor)
+* [type Tags](#Tags)
+ * [func Extract(ctx context.Context) \*Tags](#Extract)
+ * [func (t \*Tags) Has(key string) bool](#Tags.Has)
+ * [func (t \*Tags) Set(key string, value interface{}) \*Tags](#Tags.Set)
+ * [func (t \*Tags) Values() map[string]interface{}](#Tags.Values)
+
+#### <a name="pkg-examples">Examples</a>
+* [Package (InitialisationWithOptions)](#example__initialisationWithOptions)
+* [Package (Initialization)](#example__initialization)
+
+#### <a name="pkg-files">Package files</a>
+[context.go](./context.go) [doc.go](./doc.go) [fieldextractor.go](./fieldextractor.go) [interceptors.go](./interceptors.go) [options.go](./options.go)
+
+## <a name="CodeGenRequestFieldExtractor">func</a> [CodeGenRequestFieldExtractor](./fieldextractor.go#L23)
+``` go
+func CodeGenRequestFieldExtractor(fullMethod string, req interface{}) map[string]interface{}
+```
+CodeGenRequestFieldExtractor is a function that relies on code-generated functions that export log fields from requests.
+These are usually coming from a protoc-plugin that generates additional information based on custom field options.
+
+## <a name="StreamServerInterceptor">func</a> [StreamServerInterceptor](./interceptors.go#L26)
+``` go
+func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor
+```
+StreamServerInterceptor returns a new streaming server interceptor that sets the values for request tags.
+
+## <a name="UnaryServerInterceptor">func</a> [UnaryServerInterceptor](./interceptors.go#L14)
+``` go
+func UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor
+```
+UnaryServerInterceptor returns a new unary server interceptors that sets the values for request tags.
+
+## <a name="Option">type</a> [Option](./options.go#L26)
+``` go
+type Option func(*options)
+```
+
+### <a name="WithFieldExtractor">func</a> [WithFieldExtractor](./options.go#L30)
+``` go
+func WithFieldExtractor(f RequestFieldExtractorFunc) Option
+```
+WithFieldExtractor customizes the function for extracting log fields from protobuf messages, for
+unary and server-streamed methods only.
+
+### <a name="WithFieldExtractorForInitialReq">func</a> [WithFieldExtractorForInitialReq](./options.go#L39)
+``` go
+func WithFieldExtractorForInitialReq(f RequestFieldExtractorFunc) Option
+```
+WithFieldExtractorForInitialReq customizes the function for extracting log fields from protobuf messages,
+for all unary and streaming methods. For client-streams and bidirectional-streams, the tags will be
+extracted from the first message from the client.
+
+## <a name="RequestFieldExtractorFunc">type</a> [RequestFieldExtractorFunc](./fieldextractor.go#L13)
+``` go
+type RequestFieldExtractorFunc func(fullMethod string, req interface{}) map[string]interface{}
+```
+RequestFieldExtractorFunc is a user-provided function that extracts field information from a gRPC request.
+It is called from tags middleware on arrival of unary request or a server-stream request.
+Keys and values will be added to the context tags of the request. If there are no fields, you should return a nil.
+
+### <a name="TagBasedRequestFieldExtractor">func</a> [TagBasedRequestFieldExtractor](./fieldextractor.go#L43)
+``` go
+func TagBasedRequestFieldExtractor(tagName string) RequestFieldExtractorFunc
+```
+TagBasedRequestFieldExtractor is a function that relies on Go struct tags to export log fields from requests.
+These are usualy coming from a protoc-plugin, such as Gogo protobuf.
+
+ message Metadata {
+ repeated string tags = 1 [ (gogoproto.moretags) = "log_field:\"meta_tags\"" ];
+ }
+
+The tagName is configurable using the tagName variable. Here it would be "log_field".
+
+## <a name="Tags">type</a> [Tags](./context.go#L17-L19)
+``` go
+type Tags struct {
+ // contains filtered or unexported fields
+}
+```
+Tags is the struct used for storing request tags between Context calls.
+This object is *not* thread safe, and should be handled only in the context of the request.
+
+### <a name="Extract">func</a> [Extract](./context.go#L41)
+``` go
+func Extract(ctx context.Context) *Tags
+```
+Extracts returns a pre-existing Tags object in the Context.
+If the context wasn't set in a tag interceptor, a no-op Tag storage is returned that will *not* be propagated in context.
+
+### <a name="Tags.Has">func</a> (\*Tags) [Has](./context.go#L28)
+``` go
+func (t *Tags) Has(key string) bool
+```
+Has checks if the given key exists.
+
+### <a name="Tags.Set">func</a> (\*Tags) [Set](./context.go#L22)
+``` go
+func (t *Tags) Set(key string, value interface{}) *Tags
+```
+Set sets the given key in the metadata tags.
+
+### <a name="Tags.Values">func</a> (\*Tags) [Values](./context.go#L35)
+``` go
+func (t *Tags) Values() map[string]interface{}
+```
+Values returns a map of key to values.
+Do not modify the underlying map, please use Set instead.
+
+- - -
+Generated by [godoc2ghmd](https://github.com/GandalfUK/godoc2ghmd) \ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/README.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/README.md
new file mode 100644
index 00000000..b954b1f9
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/README.md
@@ -0,0 +1,188 @@
+# grpc_ctxtags
+`import "github.com/grpc-ecosystem/go-grpc-middleware/tags"`
+
+* [Overview](#pkg-overview)
+* [Imported Packages](#pkg-imports)
+* [Index](#pkg-index)
+* [Examples](#pkg-examples)
+
+## <a name="pkg-overview">Overview</a>
+`grpc_ctxtags` adds a Tag object to the context that can be used by other middleware to add context about a request.
+
+### Request Context Tags
+Tags describe information about the request, and can be set and used by other middleware, or handlers. Tags are used
+for logging and tracing of requests. Tags are populated both upwards, *and* downwards in the interceptor-handler stack.
+
+You can automatically extract tags (in `grpc.request.<field_name>`) from request payloads.
+
+For unary and server-streaming methods, pass in the `WithFieldExtractor` option. For client-streams and bidirectional-streams, you can
+use `WithFieldExtractorForInitialReq` which will extract the tags from the first message passed from client to server.
+Note the tags will not be modified for subsequent requests, so this option only makes sense when the initial message
+establishes the meta-data for the stream.
+
+If a user doesn't use the interceptors that initialize the `Tags` object, all operations following from an `Extract(ctx)`
+will be no-ops. This is to ensure that code doesn't panic if the interceptors weren't used.
+
+Tags fields are typed, and shallow and should follow the OpenTracing semantics convention:
+<a href="https://github.com/opentracing/specification/blob/master/semantic_conventions.md">https://github.com/opentracing/specification/blob/master/semantic_conventions.md</a>
+
+#### Example:
+
+<details>
+<summary>Click to expand code.</summary>
+
+```go
+opts := []grpc_ctxtags.Option{
+ grpc_ctxtags.WithFieldExtractorForInitialReq(grpc_ctxtags.TagBasedRequestFieldExtractor("log_fields")),
+}
+_ = grpc.NewServer(
+ grpc.StreamInterceptor(grpc_ctxtags.StreamServerInterceptor(opts...)),
+ grpc.UnaryInterceptor(grpc_ctxtags.UnaryServerInterceptor(opts...)),
+)
+```
+
+</details>
+
+#### Example:
+
+<details>
+<summary>Click to expand code.</summary>
+
+```go
+opts := []grpc_ctxtags.Option{
+ grpc_ctxtags.WithFieldExtractor(grpc_ctxtags.TagBasedRequestFieldExtractor("log_fields")),
+}
+_ = grpc.NewServer(
+ grpc.StreamInterceptor(grpc_ctxtags.StreamServerInterceptor(opts...)),
+ grpc.UnaryInterceptor(grpc_ctxtags.UnaryServerInterceptor(opts...)),
+)
+```
+
+</details>
+
+## <a name="pkg-imports">Imported Packages</a>
+
+- [github.com/grpc-ecosystem/go-grpc-middleware](./..)
+- [golang.org/x/net/context](https://godoc.org/golang.org/x/net/context)
+- [google.golang.org/grpc](https://godoc.org/google.golang.org/grpc)
+- [google.golang.org/grpc/peer](https://godoc.org/google.golang.org/grpc/peer)
+
+## <a name="pkg-index">Index</a>
+* [func CodeGenRequestFieldExtractor(fullMethod string, req interface{}) map[string]interface{}](#CodeGenRequestFieldExtractor)
+* [func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor](#StreamServerInterceptor)
+* [func UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor](#UnaryServerInterceptor)
+* [type Option](#Option)
+ * [func WithFieldExtractor(f RequestFieldExtractorFunc) Option](#WithFieldExtractor)
+ * [func WithFieldExtractorForInitialReq(f RequestFieldExtractorFunc) Option](#WithFieldExtractorForInitialReq)
+* [type RequestFieldExtractorFunc](#RequestFieldExtractorFunc)
+ * [func TagBasedRequestFieldExtractor(tagName string) RequestFieldExtractorFunc](#TagBasedRequestFieldExtractor)
+* [type Tags](#Tags)
+ * [func Extract(ctx context.Context) \*Tags](#Extract)
+ * [func (t \*Tags) Has(key string) bool](#Tags.Has)
+ * [func (t \*Tags) Set(key string, value interface{}) \*Tags](#Tags.Set)
+ * [func (t \*Tags) Values() map[string]interface{}](#Tags.Values)
+
+#### <a name="pkg-examples">Examples</a>
+* [Package (InitialisationWithOptions)](#example__initialisationWithOptions)
+* [Package (Initialization)](#example__initialization)
+
+#### <a name="pkg-files">Package files</a>
+[context.go](./context.go) [doc.go](./doc.go) [fieldextractor.go](./fieldextractor.go) [interceptors.go](./interceptors.go) [options.go](./options.go)
+
+## <a name="CodeGenRequestFieldExtractor">func</a> [CodeGenRequestFieldExtractor](./fieldextractor.go#L23)
+``` go
+func CodeGenRequestFieldExtractor(fullMethod string, req interface{}) map[string]interface{}
+```
+CodeGenRequestFieldExtractor is a function that relies on code-generated functions that export log fields from requests.
+These are usually coming from a protoc-plugin that generates additional information based on custom field options.
+
+## <a name="StreamServerInterceptor">func</a> [StreamServerInterceptor](./interceptors.go#L26)
+``` go
+func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor
+```
+StreamServerInterceptor returns a new streaming server interceptor that sets the values for request tags.
+
+## <a name="UnaryServerInterceptor">func</a> [UnaryServerInterceptor](./interceptors.go#L14)
+``` go
+func UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor
+```
+UnaryServerInterceptor returns a new unary server interceptors that sets the values for request tags.
+
+## <a name="Option">type</a> [Option](./options.go#L26)
+``` go
+type Option func(*options)
+```
+
+### <a name="WithFieldExtractor">func</a> [WithFieldExtractor](./options.go#L30)
+``` go
+func WithFieldExtractor(f RequestFieldExtractorFunc) Option
+```
+WithFieldExtractor customizes the function for extracting log fields from protobuf messages, for
+unary and server-streamed methods only.
+
+### <a name="WithFieldExtractorForInitialReq">func</a> [WithFieldExtractorForInitialReq](./options.go#L39)
+``` go
+func WithFieldExtractorForInitialReq(f RequestFieldExtractorFunc) Option
+```
+WithFieldExtractorForInitialReq customizes the function for extracting log fields from protobuf messages,
+for all unary and streaming methods. For client-streams and bidirectional-streams, the tags will be
+extracted from the first message from the client.
+
+## <a name="RequestFieldExtractorFunc">type</a> [RequestFieldExtractorFunc](./fieldextractor.go#L13)
+``` go
+type RequestFieldExtractorFunc func(fullMethod string, req interface{}) map[string]interface{}
+```
+RequestFieldExtractorFunc is a user-provided function that extracts field information from a gRPC request.
+It is called from tags middleware on arrival of unary request or a server-stream request.
+Keys and values will be added to the context tags of the request. If there are no fields, you should return a nil.
+
+### <a name="TagBasedRequestFieldExtractor">func</a> [TagBasedRequestFieldExtractor](./fieldextractor.go#L43)
+``` go
+func TagBasedRequestFieldExtractor(tagName string) RequestFieldExtractorFunc
+```
+TagBasedRequestFieldExtractor is a function that relies on Go struct tags to export log fields from requests.
+These are usualy coming from a protoc-plugin, such as Gogo protobuf.
+
+ message Metadata {
+ repeated string tags = 1 [ (gogoproto.moretags) = "log_field:\"meta_tags\"" ];
+ }
+
+The tagName is configurable using the tagName variable. Here it would be "log_field".
+
+## <a name="Tags">type</a> [Tags](./context.go#L17-L19)
+``` go
+type Tags struct {
+ // contains filtered or unexported fields
+}
+```
+Tags is the struct used for storing request tags between Context calls.
+This object is *not* thread safe, and should be handled only in the context of the request.
+
+### <a name="Extract">func</a> [Extract](./context.go#L41)
+``` go
+func Extract(ctx context.Context) *Tags
+```
+Extracts returns a pre-existing Tags object in the Context.
+If the context wasn't set in a tag interceptor, a no-op Tag storage is returned that will *not* be propagated in context.
+
+### <a name="Tags.Has">func</a> (\*Tags) [Has](./context.go#L28)
+``` go
+func (t *Tags) Has(key string) bool
+```
+Has checks if the given key exists.
+
+### <a name="Tags.Set">func</a> (\*Tags) [Set](./context.go#L22)
+``` go
+func (t *Tags) Set(key string, value interface{}) *Tags
+```
+Set sets the given key in the metadata tags.
+
+### <a name="Tags.Values">func</a> (\*Tags) [Values](./context.go#L35)
+``` go
+func (t *Tags) Values() map[string]interface{}
+```
+Values returns a map of key to values.
+Do not modify the underlying map, please use Set instead.
+
+- - -
+Generated by [godoc2ghmd](https://github.com/GandalfUK/godoc2ghmd) \ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/context.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/context.go
new file mode 100644
index 00000000..583025ce
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/context.go
@@ -0,0 +1,78 @@
+package grpc_ctxtags
+
+import (
+ "context"
+)
+
+type ctxMarker struct{}
+
+var (
+ // ctxMarkerKey is the Context value marker used by *all* logging middleware.
+ // The logging middleware object must interf
+ ctxMarkerKey = &ctxMarker{}
+ // NoopTags is a trivial, minimum overhead implementation of Tags for which all operations are no-ops.
+ NoopTags = &noopTags{}
+)
+
+// Tags is the interface used for storing request tags between Context calls.
+// The default implementation is *not* thread safe, and should be handled only in the context of the request.
+type Tags interface {
+ // Set sets the given key in the metadata tags.
+ Set(key string, value interface{}) Tags
+ // Has checks if the given key exists.
+ Has(key string) bool
+ // Values returns a map of key to values.
+ // Do not modify the underlying map, please use Set instead.
+ Values() map[string]interface{}
+}
+
+type mapTags struct {
+ values map[string]interface{}
+}
+
+func (t *mapTags) Set(key string, value interface{}) Tags {
+ t.values[key] = value
+ return t
+}
+
+func (t *mapTags) Has(key string) bool {
+ _, ok := t.values[key]
+ return ok
+}
+
+func (t *mapTags) Values() map[string]interface{} {
+ return t.values
+}
+
+type noopTags struct{}
+
+func (t *noopTags) Set(key string, value interface{}) Tags {
+ return t
+}
+
+func (t *noopTags) Has(key string) bool {
+ return false
+}
+
+func (t *noopTags) Values() map[string]interface{} {
+ return nil
+}
+
+// Extracts returns a pre-existing Tags object in the Context.
+// If the context wasn't set in a tag interceptor, a no-op Tag storage is returned that will *not* be propagated in context.
+func Extract(ctx context.Context) Tags {
+ t, ok := ctx.Value(ctxMarkerKey).(Tags)
+ if !ok {
+ return NoopTags
+ }
+
+ return t
+}
+
+func setInContext(ctx context.Context, tags Tags) context.Context {
+ return context.WithValue(ctx, ctxMarkerKey, tags)
+}
+
+func newTags() Tags {
+ return &mapTags{values: make(map[string]interface{})}
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/doc.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/doc.go
new file mode 100644
index 00000000..960638d0
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/doc.go
@@ -0,0 +1,22 @@
+/*
+`grpc_ctxtags` adds a Tag object to the context that can be used by other middleware to add context about a request.
+
+Request Context Tags
+
+Tags describe information about the request, and can be set and used by other middleware, or handlers. Tags are used
+for logging and tracing of requests. Tags are populated both upwards, *and* downwards in the interceptor-handler stack.
+
+You can automatically extract tags (in `grpc.request.<field_name>`) from request payloads.
+
+For unary and server-streaming methods, pass in the `WithFieldExtractor` option. For client-streams and bidirectional-streams, you can
+use `WithFieldExtractorForInitialReq` which will extract the tags from the first message passed from client to server.
+Note the tags will not be modified for subsequent requests, so this option only makes sense when the initial message
+establishes the meta-data for the stream.
+
+If a user doesn't use the interceptors that initialize the `Tags` object, all operations following from an `Extract(ctx)`
+will be no-ops. This is to ensure that code doesn't panic if the interceptors weren't used.
+
+Tags fields are typed, and shallow and should follow the OpenTracing semantics convention:
+https://github.com/opentracing/specification/blob/master/semantic_conventions.md
+*/
+package grpc_ctxtags
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/fieldextractor.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/fieldextractor.go
new file mode 100644
index 00000000..d87ee438
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/fieldextractor.go
@@ -0,0 +1,85 @@
+// Copyright 2017 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+package grpc_ctxtags
+
+import (
+ "reflect"
+)
+
+// RequestFieldExtractorFunc is a user-provided function that extracts field information from a gRPC request.
+// It is called from tags middleware on arrival of unary request or a server-stream request.
+// Keys and values will be added to the context tags of the request. If there are no fields, you should return a nil.
+type RequestFieldExtractorFunc func(fullMethod string, req interface{}) map[string]interface{}
+
+type requestFieldsExtractor interface {
+ // ExtractRequestFields is a method declared on a Protobuf message that extracts fields from the interface.
+ // The values from the extracted fields should be set in the appendToMap, in order to avoid allocations.
+ ExtractRequestFields(appendToMap map[string]interface{})
+}
+
+// CodeGenRequestFieldExtractor is a function that relies on code-generated functions that export log fields from requests.
+// These are usually coming from a protoc-plugin that generates additional information based on custom field options.
+func CodeGenRequestFieldExtractor(fullMethod string, req interface{}) map[string]interface{} {
+ if ext, ok := req.(requestFieldsExtractor); ok {
+ retMap := make(map[string]interface{})
+ ext.ExtractRequestFields(retMap)
+ if len(retMap) == 0 {
+ return nil
+ }
+ return retMap
+ }
+ return nil
+}
+
+// TagBasedRequestFieldExtractor is a function that relies on Go struct tags to export log fields from requests.
+// These are usualy coming from a protoc-plugin, such as Gogo protobuf.
+//
+// message Metadata {
+// repeated string tags = 1 [ (gogoproto.moretags) = "log_field:\"meta_tags\"" ];
+// }
+//
+// The tagName is configurable using the tagName variable. Here it would be "log_field".
+func TagBasedRequestFieldExtractor(tagName string) RequestFieldExtractorFunc {
+ return func(fullMethod string, req interface{}) map[string]interface{} {
+ retMap := make(map[string]interface{})
+ reflectMessageTags(req, retMap, tagName)
+ if len(retMap) == 0 {
+ return nil
+ }
+ return retMap
+ }
+}
+
+func reflectMessageTags(msg interface{}, existingMap map[string]interface{}, tagName string) {
+ v := reflect.ValueOf(msg)
+ // Only deal with pointers to structs.
+ if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct {
+ return
+ }
+ // Deref the pointer get to the struct.
+ v = v.Elem()
+ t := v.Type()
+ for i := 0; i < v.NumField(); i++ {
+ field := v.Field(i)
+ kind := field.Kind()
+ // Only recurse down direct pointers, which should only be to nested structs.
+ if kind == reflect.Ptr {
+ reflectMessageTags(field.Interface(), existingMap, tagName)
+ }
+ // In case of arrays/splices (repeated fields) go down to the concrete type.
+ if kind == reflect.Array || kind == reflect.Slice {
+ if field.Len() == 0 {
+ continue
+ }
+ kind = field.Index(0).Kind()
+ }
+ // Only be interested in
+ if (kind >= reflect.Bool && kind <= reflect.Float64) || kind == reflect.String {
+ if tag := t.Field(i).Tag.Get(tagName); tag != "" {
+ existingMap[tag] = field.Interface()
+ }
+ }
+ }
+ return
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/interceptors.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/interceptors.go
new file mode 100644
index 00000000..038afd26
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/interceptors.go
@@ -0,0 +1,83 @@
+// Copyright 2017 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+package grpc_ctxtags
+
+import (
+ "github.com/grpc-ecosystem/go-grpc-middleware"
+ "golang.org/x/net/context"
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/peer"
+)
+
+// UnaryServerInterceptor returns a new unary server interceptors that sets the values for request tags.
+func UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor {
+ o := evaluateOptions(opts)
+ return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
+ newCtx := newTagsForCtx(ctx)
+ if o.requestFieldsFunc != nil {
+ setRequestFieldTags(newCtx, o.requestFieldsFunc, info.FullMethod, req)
+ }
+ return handler(newCtx, req)
+ }
+}
+
+// StreamServerInterceptor returns a new streaming server interceptor that sets the values for request tags.
+func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor {
+ o := evaluateOptions(opts)
+ return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
+ newCtx := newTagsForCtx(stream.Context())
+ if o.requestFieldsFunc == nil {
+ // Short-circuit, don't do the expensive bit of allocating a wrappedStream.
+ wrappedStream := grpc_middleware.WrapServerStream(stream)
+ wrappedStream.WrappedContext = newCtx
+ return handler(srv, wrappedStream)
+ }
+ wrapped := &wrappedStream{stream, info, o, newCtx, true}
+ err := handler(srv, wrapped)
+ return err
+ }
+}
+
+// wrappedStream is a thin wrapper around grpc.ServerStream that allows modifying context and extracts log fields from the initial message.
+type wrappedStream struct {
+ grpc.ServerStream
+ info *grpc.StreamServerInfo
+ opts *options
+ // WrappedContext is the wrapper's own Context. You can assign it.
+ WrappedContext context.Context
+ initial bool
+}
+
+// Context returns the wrapper's WrappedContext, overwriting the nested grpc.ServerStream.Context()
+func (w *wrappedStream) Context() context.Context {
+ return w.WrappedContext
+}
+
+func (w *wrappedStream) RecvMsg(m interface{}) error {
+ err := w.ServerStream.RecvMsg(m)
+ // We only do log fields extraction on the single-request of a server-side stream.
+ if !w.info.IsClientStream || w.opts.requestFieldsFromInitial && w.initial {
+ w.initial = false
+
+ setRequestFieldTags(w.Context(), w.opts.requestFieldsFunc, w.info.FullMethod, m)
+ }
+ return err
+}
+
+func newTagsForCtx(ctx context.Context) context.Context {
+ t := newTags()
+ if peer, ok := peer.FromContext(ctx); ok {
+ t.Set("peer.address", peer.Addr.String())
+ }
+ return setInContext(ctx, t)
+}
+
+func setRequestFieldTags(ctx context.Context, f RequestFieldExtractorFunc, fullMethodName string, req interface{}) {
+ if valMap := f(fullMethodName, req); valMap != nil {
+ t := Extract(ctx)
+ for k, v := range valMap {
+ t.Set("grpc.request."+k, v)
+ }
+ }
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus/context.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus/context.go
new file mode 100644
index 00000000..2596be89
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus/context.go
@@ -0,0 +1,25 @@
+package ctx_logrus
+
+import (
+ "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus"
+ "github.com/sirupsen/logrus"
+ "golang.org/x/net/context"
+)
+
+// AddFields adds logrus fields to the logger.
+// Deprecated: should use the ctxlogrus.Extract instead
+func AddFields(ctx context.Context, fields logrus.Fields) {
+ ctxlogrus.AddFields(ctx, fields)
+}
+
+// Extract takes the call-scoped logrus.Entry from grpc_logrus middleware.
+// Deprecated: should use the ctxlogrus.Extract instead
+func Extract(ctx context.Context) *logrus.Entry {
+ return ctxlogrus.Extract(ctx)
+}
+
+// ToContext adds the logrus.Entry to the context for extraction later.
+// Depricated: should use ctxlogrus.ToContext instead
+func ToContext(ctx context.Context, entry *logrus.Entry) context.Context {
+ return ctxlogrus.ToContext(ctx, entry)
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/options.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/options.go
new file mode 100644
index 00000000..952775f8
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/options.go
@@ -0,0 +1,44 @@
+// Copyright 2017 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+package grpc_ctxtags
+
+var (
+ defaultOptions = &options{
+ requestFieldsFunc: nil,
+ }
+)
+
+type options struct {
+ requestFieldsFunc RequestFieldExtractorFunc
+ requestFieldsFromInitial bool
+}
+
+func evaluateOptions(opts []Option) *options {
+ optCopy := &options{}
+ *optCopy = *defaultOptions
+ for _, o := range opts {
+ o(optCopy)
+ }
+ return optCopy
+}
+
+type Option func(*options)
+
+// WithFieldExtractor customizes the function for extracting log fields from protobuf messages, for
+// unary and server-streamed methods only.
+func WithFieldExtractor(f RequestFieldExtractorFunc) Option {
+ return func(o *options) {
+ o.requestFieldsFunc = f
+ }
+}
+
+// WithFieldExtractorForInitialReq customizes the function for extracting log fields from protobuf messages,
+// for all unary and streaming methods. For client-streams and bidirectional-streams, the tags will be
+// extracted from the first message from the client.
+func WithFieldExtractorForInitialReq(f RequestFieldExtractorFunc) Option {
+ return func(o *options) {
+ o.requestFieldsFunc = f
+ o.requestFieldsFromInitial = true
+ }
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/DOC.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/DOC.md
new file mode 100644
index 00000000..a02cde31
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/DOC.md
@@ -0,0 +1,114 @@
+# metautils
+`import "github.com/grpc-ecosystem/go-grpc-middleware/util/metautils"`
+
+* [Overview](#pkg-overview)
+* [Imported Packages](#pkg-imports)
+* [Index](#pkg-index)
+
+## <a name="pkg-overview">Overview</a>
+
+## <a name="pkg-imports">Imported Packages</a>
+
+- [golang.org/x/net/context](https://godoc.org/golang.org/x/net/context)
+- [google.golang.org/grpc/metadata](https://godoc.org/google.golang.org/grpc/metadata)
+
+## <a name="pkg-index">Index</a>
+* [type NiceMD](#NiceMD)
+ * [func ExtractIncoming(ctx context.Context) NiceMD](#ExtractIncoming)
+ * [func ExtractOutgoing(ctx context.Context) NiceMD](#ExtractOutgoing)
+ * [func (m NiceMD) Add(key string, value string) NiceMD](#NiceMD.Add)
+ * [func (m NiceMD) Clone(copiedKeys ...string) NiceMD](#NiceMD.Clone)
+ * [func (m NiceMD) Del(key string) NiceMD](#NiceMD.Del)
+ * [func (m NiceMD) Get(key string) string](#NiceMD.Get)
+ * [func (m NiceMD) Set(key string, value string) NiceMD](#NiceMD.Set)
+ * [func (m NiceMD) ToIncoming(ctx context.Context) context.Context](#NiceMD.ToIncoming)
+ * [func (m NiceMD) ToOutgoing(ctx context.Context) context.Context](#NiceMD.ToOutgoing)
+
+#### <a name="pkg-files">Package files</a>
+[doc.go](./doc.go) [nicemd.go](./nicemd.go) [single_key.go](./single_key.go)
+
+## <a name="NiceMD">type</a> [NiceMD](./nicemd.go#L14)
+``` go
+type NiceMD metadata.MD
+```
+NiceMD is a convenience wrapper definiting extra functions on the metadata.
+
+### <a name="ExtractIncoming">func</a> [ExtractIncoming](./nicemd.go#L20)
+``` go
+func ExtractIncoming(ctx context.Context) NiceMD
+```
+ExtractIncoming extracts an inbound metadata from the server-side context.
+
+This function always returns a NiceMD wrapper of the metadata.MD, in case the context doesn't have metadata it returns
+a new empty NiceMD.
+
+### <a name="ExtractOutgoing">func</a> [ExtractOutgoing](./nicemd.go#L32)
+``` go
+func ExtractOutgoing(ctx context.Context) NiceMD
+```
+ExtractOutgoing extracts an outbound metadata from the client-side context.
+
+This function always returns a NiceMD wrapper of the metadata.MD, in case the context doesn't have metadata it returns
+a new empty NiceMD.
+
+### <a name="NiceMD.Add">func</a> (NiceMD) [Add](./nicemd.go#L122)
+``` go
+func (m NiceMD) Add(key string, value string) NiceMD
+```
+Add retrieves a single value from the metadata.
+
+It works analogously to http.Header.Add, as it appends to any existing values associated with key.
+
+The function is binary-key safe.
+
+### <a name="NiceMD.Clone">func</a> (NiceMD) [Clone](./nicemd.go#L44)
+``` go
+func (m NiceMD) Clone(copiedKeys ...string) NiceMD
+```
+Clone performs a *deep* copy of the metadata.MD.
+
+You can specify the lower-case copiedKeys to only copy certain whitelisted keys. If no keys are explicitly whitelisted
+all keys get copied.
+
+### <a name="NiceMD.Del">func</a> (NiceMD) [Del](./nicemd.go#L100)
+``` go
+func (m NiceMD) Del(key string) NiceMD
+```
+
+### <a name="NiceMD.Get">func</a> (NiceMD) [Get](./nicemd.go#L85)
+``` go
+func (m NiceMD) Get(key string) string
+```
+Get retrieves a single value from the metadata.
+
+It works analogously to http.Header.Get, returning the first value if there are many set. If the value is not set,
+an empty string is returned.
+
+The function is binary-key safe.
+
+### <a name="NiceMD.Set">func</a> (NiceMD) [Set](./nicemd.go#L111)
+``` go
+func (m NiceMD) Set(key string, value string) NiceMD
+```
+Set sets the given value in a metadata.
+
+It works analogously to http.Header.Set, overwriting all previous metadata values.
+
+The function is binary-key safe.
+
+### <a name="NiceMD.ToIncoming">func</a> (NiceMD) [ToIncoming](./nicemd.go#L75)
+``` go
+func (m NiceMD) ToIncoming(ctx context.Context) context.Context
+```
+ToIncoming sets the given NiceMD as a server-side context for dispatching.
+
+This is mostly useful in ServerInterceptors..
+
+### <a name="NiceMD.ToOutgoing">func</a> (NiceMD) [ToOutgoing](./nicemd.go#L68)
+``` go
+func (m NiceMD) ToOutgoing(ctx context.Context) context.Context
+```
+ToOutgoing sets the given NiceMD as a client-side context for dispatching.
+
+- - -
+Generated by [godoc2ghmd](https://github.com/GandalfUK/godoc2ghmd) \ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/README.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/README.md
new file mode 100644
index 00000000..a02cde31
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/README.md
@@ -0,0 +1,114 @@
+# metautils
+`import "github.com/grpc-ecosystem/go-grpc-middleware/util/metautils"`
+
+* [Overview](#pkg-overview)
+* [Imported Packages](#pkg-imports)
+* [Index](#pkg-index)
+
+## <a name="pkg-overview">Overview</a>
+
+## <a name="pkg-imports">Imported Packages</a>
+
+- [golang.org/x/net/context](https://godoc.org/golang.org/x/net/context)
+- [google.golang.org/grpc/metadata](https://godoc.org/google.golang.org/grpc/metadata)
+
+## <a name="pkg-index">Index</a>
+* [type NiceMD](#NiceMD)
+ * [func ExtractIncoming(ctx context.Context) NiceMD](#ExtractIncoming)
+ * [func ExtractOutgoing(ctx context.Context) NiceMD](#ExtractOutgoing)
+ * [func (m NiceMD) Add(key string, value string) NiceMD](#NiceMD.Add)
+ * [func (m NiceMD) Clone(copiedKeys ...string) NiceMD](#NiceMD.Clone)
+ * [func (m NiceMD) Del(key string) NiceMD](#NiceMD.Del)
+ * [func (m NiceMD) Get(key string) string](#NiceMD.Get)
+ * [func (m NiceMD) Set(key string, value string) NiceMD](#NiceMD.Set)
+ * [func (m NiceMD) ToIncoming(ctx context.Context) context.Context](#NiceMD.ToIncoming)
+ * [func (m NiceMD) ToOutgoing(ctx context.Context) context.Context](#NiceMD.ToOutgoing)
+
+#### <a name="pkg-files">Package files</a>
+[doc.go](./doc.go) [nicemd.go](./nicemd.go) [single_key.go](./single_key.go)
+
+## <a name="NiceMD">type</a> [NiceMD](./nicemd.go#L14)
+``` go
+type NiceMD metadata.MD
+```
+NiceMD is a convenience wrapper definiting extra functions on the metadata.
+
+### <a name="ExtractIncoming">func</a> [ExtractIncoming](./nicemd.go#L20)
+``` go
+func ExtractIncoming(ctx context.Context) NiceMD
+```
+ExtractIncoming extracts an inbound metadata from the server-side context.
+
+This function always returns a NiceMD wrapper of the metadata.MD, in case the context doesn't have metadata it returns
+a new empty NiceMD.
+
+### <a name="ExtractOutgoing">func</a> [ExtractOutgoing](./nicemd.go#L32)
+``` go
+func ExtractOutgoing(ctx context.Context) NiceMD
+```
+ExtractOutgoing extracts an outbound metadata from the client-side context.
+
+This function always returns a NiceMD wrapper of the metadata.MD, in case the context doesn't have metadata it returns
+a new empty NiceMD.
+
+### <a name="NiceMD.Add">func</a> (NiceMD) [Add](./nicemd.go#L122)
+``` go
+func (m NiceMD) Add(key string, value string) NiceMD
+```
+Add retrieves a single value from the metadata.
+
+It works analogously to http.Header.Add, as it appends to any existing values associated with key.
+
+The function is binary-key safe.
+
+### <a name="NiceMD.Clone">func</a> (NiceMD) [Clone](./nicemd.go#L44)
+``` go
+func (m NiceMD) Clone(copiedKeys ...string) NiceMD
+```
+Clone performs a *deep* copy of the metadata.MD.
+
+You can specify the lower-case copiedKeys to only copy certain whitelisted keys. If no keys are explicitly whitelisted
+all keys get copied.
+
+### <a name="NiceMD.Del">func</a> (NiceMD) [Del](./nicemd.go#L100)
+``` go
+func (m NiceMD) Del(key string) NiceMD
+```
+
+### <a name="NiceMD.Get">func</a> (NiceMD) [Get](./nicemd.go#L85)
+``` go
+func (m NiceMD) Get(key string) string
+```
+Get retrieves a single value from the metadata.
+
+It works analogously to http.Header.Get, returning the first value if there are many set. If the value is not set,
+an empty string is returned.
+
+The function is binary-key safe.
+
+### <a name="NiceMD.Set">func</a> (NiceMD) [Set](./nicemd.go#L111)
+``` go
+func (m NiceMD) Set(key string, value string) NiceMD
+```
+Set sets the given value in a metadata.
+
+It works analogously to http.Header.Set, overwriting all previous metadata values.
+
+The function is binary-key safe.
+
+### <a name="NiceMD.ToIncoming">func</a> (NiceMD) [ToIncoming](./nicemd.go#L75)
+``` go
+func (m NiceMD) ToIncoming(ctx context.Context) context.Context
+```
+ToIncoming sets the given NiceMD as a server-side context for dispatching.
+
+This is mostly useful in ServerInterceptors..
+
+### <a name="NiceMD.ToOutgoing">func</a> (NiceMD) [ToOutgoing](./nicemd.go#L68)
+``` go
+func (m NiceMD) ToOutgoing(ctx context.Context) context.Context
+```
+ToOutgoing sets the given NiceMD as a client-side context for dispatching.
+
+- - -
+Generated by [godoc2ghmd](https://github.com/GandalfUK/godoc2ghmd) \ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/doc.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/doc.go
new file mode 100644
index 00000000..1ed9bb49
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/doc.go
@@ -0,0 +1,19 @@
+// Copyright 2016 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+/*
+Package `metautils` provides convenience functions for dealing with gRPC metadata.MD objects inside
+Context handlers.
+
+While the upstream grpc-go package contains decent functionality (see https://github.com/grpc/grpc-go/blob/master/Documentation/grpc-metadata.md)
+they are hard to use.
+
+The majority of functions center around the NiceMD, which is a convenience wrapper around metadata.MD. For example
+the following code allows you to easily extract incoming metadata (server handler) and put it into a new client context
+metadata.
+
+ nmd := metautils.ExtractIncoming(serverCtx).Clone(":authorization", ":custom")
+ clientCtx := nmd.Set("x-client-header", "2").Set("x-another", "3").ToOutgoing(ctx)
+*/
+
+package metautils
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/nicemd.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/nicemd.go
new file mode 100644
index 00000000..a277bee3
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/nicemd.go
@@ -0,0 +1,126 @@
+// Copyright 2016 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+package metautils
+
+import (
+ "strings"
+
+ "golang.org/x/net/context"
+ "google.golang.org/grpc/metadata"
+)
+
+// NiceMD is a convenience wrapper definiting extra functions on the metadata.
+type NiceMD metadata.MD
+
+// ExtractIncoming extracts an inbound metadata from the server-side context.
+//
+// This function always returns a NiceMD wrapper of the metadata.MD, in case the context doesn't have metadata it returns
+// a new empty NiceMD.
+func ExtractIncoming(ctx context.Context) NiceMD {
+ md, ok := metadata.FromIncomingContext(ctx)
+ if !ok {
+ return NiceMD(metadata.Pairs())
+ }
+ return NiceMD(md)
+}
+
+// ExtractOutgoing extracts an outbound metadata from the client-side context.
+//
+// This function always returns a NiceMD wrapper of the metadata.MD, in case the context doesn't have metadata it returns
+// a new empty NiceMD.
+func ExtractOutgoing(ctx context.Context) NiceMD {
+ md, ok := metadata.FromOutgoingContext(ctx)
+ if !ok {
+ return NiceMD(metadata.Pairs())
+ }
+ return NiceMD(md)
+}
+
+// Clone performs a *deep* copy of the metadata.MD.
+//
+// You can specify the lower-case copiedKeys to only copy certain whitelisted keys. If no keys are explicitly whitelisted
+// all keys get copied.
+func (m NiceMD) Clone(copiedKeys ...string) NiceMD {
+ newMd := NiceMD(metadata.Pairs())
+ for k, vv := range m {
+ found := false
+ if len(copiedKeys) == 0 {
+ found = true
+ } else {
+ for _, allowedKey := range copiedKeys {
+ if strings.ToLower(allowedKey) == strings.ToLower(k) {
+ found = true
+ break
+ }
+ }
+ }
+ if !found {
+ continue
+ }
+ newMd[k] = make([]string, len(vv))
+ copy(newMd[k], vv)
+ }
+ return NiceMD(newMd)
+}
+
+// ToOutgoing sets the given NiceMD as a client-side context for dispatching.
+func (m NiceMD) ToOutgoing(ctx context.Context) context.Context {
+ return metadata.NewOutgoingContext(ctx, metadata.MD(m))
+}
+
+// ToIncoming sets the given NiceMD as a server-side context for dispatching.
+//
+// This is mostly useful in ServerInterceptors..
+func (m NiceMD) ToIncoming(ctx context.Context) context.Context {
+ return metadata.NewIncomingContext(ctx, metadata.MD(m))
+}
+
+// Get retrieves a single value from the metadata.
+//
+// It works analogously to http.Header.Get, returning the first value if there are many set. If the value is not set,
+// an empty string is returned.
+//
+// The function is binary-key safe.
+func (m NiceMD) Get(key string) string {
+ k, _ := encodeKeyValue(key, "")
+ vv, ok := m[k]
+ if !ok {
+ return ""
+ }
+ return vv[0]
+}
+
+// Del retrieves a single value from the metadata.
+//
+// It works analogously to http.Header.Del, deleting all values if they exist.
+//
+// The function is binary-key safe.
+
+func (m NiceMD) Del(key string) NiceMD {
+ k, _ := encodeKeyValue(key, "")
+ delete(m, k)
+ return m
+}
+
+// Set sets the given value in a metadata.
+//
+// It works analogously to http.Header.Set, overwriting all previous metadata values.
+//
+// The function is binary-key safe.
+func (m NiceMD) Set(key string, value string) NiceMD {
+ k, v := encodeKeyValue(key, value)
+ m[k] = []string{v}
+ return m
+}
+
+// Add retrieves a single value from the metadata.
+//
+// It works analogously to http.Header.Add, as it appends to any existing values associated with key.
+//
+// The function is binary-key safe.
+func (m NiceMD) Add(key string, value string) NiceMD {
+ k, v := encodeKeyValue(key, value)
+ m[k] = append(m[k], v)
+ return m
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/single_key.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/single_key.go
new file mode 100644
index 00000000..8a538716
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/single_key.go
@@ -0,0 +1,22 @@
+// Copyright 2016 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+package metautils
+
+import (
+ "encoding/base64"
+ "strings"
+)
+
+const (
+ binHdrSuffix = "-bin"
+)
+
+func encodeKeyValue(k, v string) (string, string) {
+ k = strings.ToLower(k)
+ if strings.HasSuffix(k, binHdrSuffix) {
+ val := base64.StdEncoding.EncodeToString([]byte(v))
+ v = string(val)
+ }
+ return k, v
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/wrappers.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/wrappers.go
new file mode 100644
index 00000000..597b8624
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/wrappers.go
@@ -0,0 +1,29 @@
+// Copyright 2016 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+package grpc_middleware
+
+import (
+ "golang.org/x/net/context"
+ "google.golang.org/grpc"
+)
+
+// WrappedServerStream is a thin wrapper around grpc.ServerStream that allows modifying context.
+type WrappedServerStream struct {
+ grpc.ServerStream
+ // WrappedContext is the wrapper's own Context. You can assign it.
+ WrappedContext context.Context
+}
+
+// Context returns the wrapper's WrappedContext, overwriting the nested grpc.ServerStream.Context()
+func (w *WrappedServerStream) Context() context.Context {
+ return w.WrappedContext
+}
+
+// WrapServerStream returns a ServerStream that has the ability to overwrite context.
+func WrapServerStream(stream grpc.ServerStream) *WrappedServerStream {
+ if existing, ok := stream.(*WrappedServerStream); ok {
+ return existing
+ }
+ return &WrappedServerStream{ServerStream: stream, WrappedContext: stream.Context()}
+}