From 2195e6ca9544764cf0b64daafd11d591de1ae4ea Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Thu, 12 Apr 2018 15:42:12 +0200 Subject: Add more gRPC dependencies --- .../grpc-ecosystem/go-grpc-middleware/DOC.md | 166 +++++++++ .../grpc-ecosystem/go-grpc-middleware/Gopkg.lock | 123 +++++++ .../grpc-ecosystem/go-grpc-middleware/Gopkg.toml | 35 ++ .../grpc-ecosystem/go-grpc-middleware/LICENSE | 201 +++++++++++ .../grpc-ecosystem/go-grpc-middleware/README.md | 86 +++++ .../grpc-ecosystem/go-grpc-middleware/auth/DOC.md | 148 ++++++++ .../go-grpc-middleware/auth/README.md | 148 ++++++++ .../grpc-ecosystem/go-grpc-middleware/auth/auth.go | 67 ++++ .../grpc-ecosystem/go-grpc-middleware/auth/doc.go | 20 ++ .../go-grpc-middleware/auth/metadata.go | 38 ++ .../grpc-ecosystem/go-grpc-middleware/chain.go | 183 ++++++++++ .../grpc-ecosystem/go-grpc-middleware/doc.go | 69 ++++ .../go-grpc-middleware/logging/DOC.md | 91 +++++ .../go-grpc-middleware/logging/README.md | 91 +++++ .../go-grpc-middleware/logging/common.go | 35 ++ .../go-grpc-middleware/logging/doc.go | 35 ++ .../go-grpc-middleware/logging/logrus/DOC.md | 391 +++++++++++++++++++++ .../go-grpc-middleware/logging/logrus/README.md | 391 +++++++++++++++++++++ .../logging/logrus/client_interceptors.go | 65 ++++ .../go-grpc-middleware/logging/logrus/context.go | 19 + .../logging/logrus/ctxlogrus/DOC.md | 93 +++++ .../logging/logrus/ctxlogrus/README.md | 58 +++ .../logging/logrus/ctxlogrus/context.go | 65 ++++ .../logging/logrus/ctxlogrus/doc.go | 14 + .../logging/logrus/ctxlogrus/noop.go | 16 + .../go-grpc-middleware/logging/logrus/doc.go | 67 ++++ .../logging/logrus/grpclogger.go | 15 + .../go-grpc-middleware/logging/logrus/options.go | 185 ++++++++++ .../logging/logrus/payload_interceptors.go | 144 ++++++++ .../logging/logrus/server_interceptors.go | 129 +++++++ .../grpc-ecosystem/go-grpc-middleware/makefile | 19 + .../go-grpc-middleware/recovery/DOC.md | 107 ++++++ .../go-grpc-middleware/recovery/README.md | 107 ++++++ .../go-grpc-middleware/recovery/doc.go | 15 + .../go-grpc-middleware/recovery/interceptors.go | 48 +++ .../go-grpc-middleware/recovery/options.go | 32 ++ .../grpc-ecosystem/go-grpc-middleware/tags/DOC.md | 188 ++++++++++ .../go-grpc-middleware/tags/README.md | 188 ++++++++++ .../go-grpc-middleware/tags/context.go | 78 ++++ .../grpc-ecosystem/go-grpc-middleware/tags/doc.go | 22 ++ .../go-grpc-middleware/tags/fieldextractor.go | 85 +++++ .../go-grpc-middleware/tags/interceptors.go | 83 +++++ .../go-grpc-middleware/tags/logrus/context.go | 25 ++ .../go-grpc-middleware/tags/options.go | 44 +++ .../go-grpc-middleware/util/metautils/DOC.md | 114 ++++++ .../go-grpc-middleware/util/metautils/README.md | 114 ++++++ .../go-grpc-middleware/util/metautils/doc.go | 19 + .../go-grpc-middleware/util/metautils/nicemd.go | 126 +++++++ .../util/metautils/single_key.go | 22 ++ .../grpc-ecosystem/go-grpc-middleware/wrappers.go | 29 ++ 50 files changed, 4653 insertions(+) create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/DOC.md create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/Gopkg.lock create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/Gopkg.toml create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/LICENSE create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/README.md create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/DOC.md create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/README.md create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/auth.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/doc.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/metadata.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/chain.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/doc.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/DOC.md create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/README.md create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/common.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/doc.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/DOC.md create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/README.md create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/client_interceptors.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/context.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus/DOC.md create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus/README.md create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus/context.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus/doc.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus/noop.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/doc.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/grpclogger.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/options.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/payload_interceptors.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/server_interceptors.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/makefile create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/DOC.md create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/README.md create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/doc.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/interceptors.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/options.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/DOC.md create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/README.md create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/context.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/doc.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/fieldextractor.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/interceptors.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus/context.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/options.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/DOC.md create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/README.md create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/doc.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/nicemd.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/single_key.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/wrappers.go (limited to 'vendor/github.com/grpc-ecosystem/go-grpc-middleware') 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) + +## Overview +`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) + } + +## Imported Packages + +- [golang.org/x/net/context](https://godoc.org/golang.org/x/net/context) +- [google.golang.org/grpc](https://godoc.org/google.golang.org/grpc) + +## Index +* [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) + +#### Package files +[chain.go](./chain.go) [doc.go](./doc.go) [wrappers.go](./wrappers.go) + +## func [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. + +## func [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. + +## func [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. + +## func [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. + +## func [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. + +## func [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. + +## type [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. + +### func [WrapServerStream](./wrappers.go#L24) +``` go +func WrapServerStream(stream grpc.ServerStream) *WrappedServerStream +``` +WrapServerStream returns a ServerStream that has the ability to overwrite context. + +### func (\*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) + +## Overview +`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: + +
+Click to expand code. + +```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)), + ) +} +``` + +
+ +## Imported Packages + +- [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) + +## Index +* [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) + +#### Examples +* [Package (ServerConfig)](#example__serverConfig) + +#### Package files +[auth.go](./auth.go) [doc.go](./doc.go) [metadata.go](./metadata.go) + +## func [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. + +## func [StreamServerInterceptor](./auth.go#L51) +``` go +func StreamServerInterceptor(authFunc AuthFunc) grpc.StreamServerInterceptor +``` +StreamServerInterceptor returns a new unary server interceptors that performs per-request auth. + +## func [UnaryServerInterceptor](./auth.go#L34) +``` go +func UnaryServerInterceptor(authFunc AuthFunc) grpc.UnaryServerInterceptor +``` +UnaryServerInterceptor returns a new unary server interceptors that performs per-request auth. + +## type [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. + +## type [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) + +## Overview +`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: + +
+Click to expand code. + +```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)), + ) +} +``` + +
+ +## Imported Packages + +- [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) + +## Index +* [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) + +#### Examples +* [Package (ServerConfig)](#example__serverConfig) + +#### Package files +[auth.go](./auth.go) [doc.go](./doc.go) [metadata.go](./metadata.go) + +## func [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. + +## func [StreamServerInterceptor](./auth.go#L51) +``` go +func StreamServerInterceptor(authFunc AuthFunc) grpc.StreamServerInterceptor +``` +StreamServerInterceptor returns a new unary server interceptors that performs per-request auth. + +## func [UnaryServerInterceptor](./auth.go#L34) +``` go +func UnaryServerInterceptor(authFunc AuthFunc) grpc.UnaryServerInterceptor +``` +UnaryServerInterceptor returns a new unary server interceptors that performs per-request auth. + +## type [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. + +## type [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) + +## Overview +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. + +## Imported Packages + +- [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) + +## Index +* [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) + +#### Package files +[common.go](./common.go) [doc.go](./doc.go) + +## func [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 + +## func [DefaultErrorToCode](./common.go#L16) +``` go +func DefaultErrorToCode(err error) codes.Code +``` + +## type [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 + +## type [Decider](./common.go#L21) +``` go +type Decider func(fullMethodName string, err error) bool +``` +Decider function defines rules for suppressing any interceptor logs + +## type [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 + +## type [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) + +## Overview +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. + +## Imported Packages + +- [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) + +## Index +* [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) + +#### Package files +[common.go](./common.go) [doc.go](./doc.go) + +## func [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 + +## func [DefaultErrorToCode](./common.go#L16) +``` go +func DefaultErrorToCode(err error) codes.Code +``` + +## type [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 + +## type [Decider](./common.go#L21) +``` go +type Decider func(fullMethodName string, err error) bool +``` +Decider function defines rules for suppressing any interceptor logs + +## type [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 + +## type [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) + +## Overview +`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: + +
+Click to expand code. + +```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...), + ), +) +``` + +
+ +#### Example: + +
+Click to expand code. + +```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...), + ), +) +``` + +
+ +## Imported Packages + +- [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) + +## Index +* [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) + +#### Examples +* [Extract (Unary)](#example_Extract_unary) +* [WithDecider](#example_WithDecider) +* [Package (Initialization)](#example__initialization) +* [Package (InitializationWithDurationFieldOverride)](#example__initializationWithDurationFieldOverride) + +#### Package files +[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) + +## Variables +``` 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{} +) +``` + +## func [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 + +## func [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. + +## func [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. + +## func [DurationToDurationField](./options.go#L179) +``` go +func DurationToDurationField(duration time.Duration) (key string, value interface{}) +``` +DurationToDurationField uses the duration value to log the request duration. + +## func [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`. + +## func [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: + +
+Click to expand code. + +```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 +} +``` + +
+ +## func [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. + +## func [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. + +## func [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. + +## func [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. + +## func [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. + +## func [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. + +## func [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. + +## func [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. + +## func [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. + +## type [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. + +## type [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 + +## type [Option](./options.go#L50) +``` go +type Option func(*options) +``` + +### func [WithCodes](./options.go#L73) +``` go +func WithCodes(f grpc_logging.ErrorToCode) Option +``` +WithCodes customizes the function for mapping errors to error codes. + +### func [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: + +
+Click to expand code. + +```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...)), +} +``` + +
+### func [WithDurationField](./options.go#L80) +``` go +func WithDurationField(f DurationToField) Option +``` +WithDurationField customizes the function for mapping request durations to log fields. + +### func [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) + +## Overview +`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: + +
+Click to expand code. + +```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...), + ), +) +``` + +
+ +#### Example: + +
+Click to expand code. + +```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...), + ), +) +``` + +
+ +## Imported Packages + +- [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) + +## Index +* [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) + +#### Examples +* [Extract (Unary)](#example_Extract_unary) +* [WithDecider](#example_WithDecider) +* [Package (Initialization)](#example__initialization) +* [Package (InitializationWithDurationFieldOverride)](#example__initializationWithDurationFieldOverride) + +#### Package files +[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) + +## Variables +``` 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{} +) +``` + +## func [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 + +## func [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. + +## func [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. + +## func [DurationToDurationField](./options.go#L179) +``` go +func DurationToDurationField(duration time.Duration) (key string, value interface{}) +``` +DurationToDurationField uses the duration value to log the request duration. + +## func [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`. + +## func [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: + +
+Click to expand code. + +```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 +} +``` + +
+ +## func [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. + +## func [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. + +## func [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. + +## func [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. + +## func [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. + +## func [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. + +## func [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. + +## func [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. + +## func [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. + +## type [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. + +## type [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 + +## type [Option](./options.go#L50) +``` go +type Option func(*options) +``` + +### func [WithCodes](./options.go#L73) +``` go +func WithCodes(f grpc_logging.ErrorToCode) Option +``` +WithCodes customizes the function for mapping errors to error codes. + +### func [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: + +
+Click to expand code. + +```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...)), +} +``` + +
+### func [WithDurationField](./options.go#L80) +``` go +func WithDurationField(f DurationToField) Option +``` +WithDurationField customizes the function for mapping request durations to log fields. + +### func [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) + +## Overview +`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. + +## Imported Packages + +- [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) + +## Index +* [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) + +#### Examples +* [Extract (Unary)](#example_Extract_unary) + +#### Package files +[context.go](./context.go) [doc.go](./doc.go) [noop.go](./noop.go) + +## func [AddFields](./context.go#L21) +``` go +func AddFields(ctx context.Context, fields logrus.Fields) +``` +AddFields adds logrus fields to the logger. + +## func [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: + +
+Click to expand code. + +```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") +} +``` + +
+ +## func [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) + +## Overview +`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. + +## Imported Packages + +- [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) + +## Index +* [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) + +#### Package files +[context.go](./context.go) [doc.go](./doc.go) [noop.go](./noop.go) + +## func [AddFields](./context.go#L21) +``` go +func AddFields(ctx context.Context, fields logrus.Fields) +``` +AddFields adds logrus fields to the logger. + +## func [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. + +## func [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) + +## Overview +`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: + +
+Click to expand code. + +```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...), + ), + ) +} +``` + +
+ +## Imported Packages + +- [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) + +## Index +* [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) + +#### Examples +* [Package (Initialization)](#example__initialization) + +#### Package files +[doc.go](./doc.go) [interceptors.go](./interceptors.go) [options.go](./options.go) + +## func [StreamServerInterceptor](./interceptors.go#L30) +``` go +func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor +``` +StreamServerInterceptor returns a new streaming server interceptor for panic recovery. + +## func [UnaryServerInterceptor](./interceptors.go#L16) +``` go +func UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor +``` +UnaryServerInterceptor returns a new unary server interceptor for panic recovery. + +## type [Option](./options.go#L25) +``` go +type Option func(*options) +``` + +### func [WithRecoveryHandler](./options.go#L28) +``` go +func WithRecoveryHandler(f RecoveryHandlerFunc) Option +``` +WithRecoveryHandler customizes the function for recovering from a panic. + +## type [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) + +## Overview +`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: + +
+Click to expand code. + +```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...), + ), + ) +} +``` + +
+ +## Imported Packages + +- [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) + +## Index +* [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) + +#### Examples +* [Package (Initialization)](#example__initialization) + +#### Package files +[doc.go](./doc.go) [interceptors.go](./interceptors.go) [options.go](./options.go) + +## func [StreamServerInterceptor](./interceptors.go#L30) +``` go +func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor +``` +StreamServerInterceptor returns a new streaming server interceptor for panic recovery. + +## func [UnaryServerInterceptor](./interceptors.go#L16) +``` go +func UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor +``` +UnaryServerInterceptor returns a new unary server interceptor for panic recovery. + +## type [Option](./options.go#L25) +``` go +type Option func(*options) +``` + +### func [WithRecoveryHandler](./options.go#L28) +``` go +func WithRecoveryHandler(f RecoveryHandlerFunc) Option +``` +WithRecoveryHandler customizes the function for recovering from a panic. + +## type [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) + +## Overview +`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.`) 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 + +#### Example: + +
+Click to expand code. + +```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...)), +) +``` + +
+ +#### Example: + +
+Click to expand code. + +```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...)), +) +``` + +
+ +## Imported Packages + +- [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) + +## Index +* [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) + +#### Examples +* [Package (InitialisationWithOptions)](#example__initialisationWithOptions) +* [Package (Initialization)](#example__initialization) + +#### Package files +[context.go](./context.go) [doc.go](./doc.go) [fieldextractor.go](./fieldextractor.go) [interceptors.go](./interceptors.go) [options.go](./options.go) + +## func [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. + +## func [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. + +## func [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. + +## type [Option](./options.go#L26) +``` go +type Option func(*options) +``` + +### func [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. + +### func [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. + +## type [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. + +### func [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". + +## type [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. + +### func [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. + +### func (\*Tags) [Has](./context.go#L28) +``` go +func (t *Tags) Has(key string) bool +``` +Has checks if the given key exists. + +### func (\*Tags) [Set](./context.go#L22) +``` go +func (t *Tags) Set(key string, value interface{}) *Tags +``` +Set sets the given key in the metadata tags. + +### func (\*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) + +## Overview +`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.`) 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 + +#### Example: + +
+Click to expand code. + +```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...)), +) +``` + +
+ +#### Example: + +
+Click to expand code. + +```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...)), +) +``` + +
+ +## Imported Packages + +- [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) + +## Index +* [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) + +#### Examples +* [Package (InitialisationWithOptions)](#example__initialisationWithOptions) +* [Package (Initialization)](#example__initialization) + +#### Package files +[context.go](./context.go) [doc.go](./doc.go) [fieldextractor.go](./fieldextractor.go) [interceptors.go](./interceptors.go) [options.go](./options.go) + +## func [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. + +## func [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. + +## func [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. + +## type [Option](./options.go#L26) +``` go +type Option func(*options) +``` + +### func [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. + +### func [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. + +## type [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. + +### func [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". + +## type [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. + +### func [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. + +### func (\*Tags) [Has](./context.go#L28) +``` go +func (t *Tags) Has(key string) bool +``` +Has checks if the given key exists. + +### func (\*Tags) [Set](./context.go#L22) +``` go +func (t *Tags) Set(key string, value interface{}) *Tags +``` +Set sets the given key in the metadata tags. + +### func (\*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.`) 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) + +## Overview + +## Imported Packages + +- [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) + +## Index +* [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) + +#### Package files +[doc.go](./doc.go) [nicemd.go](./nicemd.go) [single_key.go](./single_key.go) + +## type [NiceMD](./nicemd.go#L14) +``` go +type NiceMD metadata.MD +``` +NiceMD is a convenience wrapper definiting extra functions on the metadata. + +### func [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. + +### func [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. + +### func (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. + +### func (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. + +### func (NiceMD) [Del](./nicemd.go#L100) +``` go +func (m NiceMD) Del(key string) NiceMD +``` + +### func (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. + +### func (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. + +### func (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.. + +### func (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) + +## Overview + +## Imported Packages + +- [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) + +## Index +* [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) + +#### Package files +[doc.go](./doc.go) [nicemd.go](./nicemd.go) [single_key.go](./single_key.go) + +## type [NiceMD](./nicemd.go#L14) +``` go +type NiceMD metadata.MD +``` +NiceMD is a convenience wrapper definiting extra functions on the metadata. + +### func [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. + +### func [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. + +### func (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. + +### func (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. + +### func (NiceMD) [Del](./nicemd.go#L100) +``` go +func (m NiceMD) Del(key string) NiceMD +``` + +### func (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. + +### func (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. + +### func (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.. + +### func (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()} +} -- cgit v1.2.3