mirror of
https://github.com/linka-cloud/grpc.git
synced 2024-11-21 18:36:25 +00:00
add http middleware, add option to use custom mux, improved logger kvs
This commit is contained in:
parent
2916a61b3b
commit
43357bc790
@ -9,10 +9,12 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"go.linka.cloud/grpc/client"
|
"go.linka.cloud/grpc/client"
|
||||||
|
"go.linka.cloud/grpc/logger"
|
||||||
"go.linka.cloud/grpc/registry/mdns"
|
"go.linka.cloud/grpc/registry/mdns"
|
||||||
"go.linka.cloud/grpc/service"
|
"go.linka.cloud/grpc/service"
|
||||||
)
|
)
|
||||||
@ -39,6 +41,20 @@ func (g *GreeterHandler) SayHelloStream(req *HelloStreamRequest, s Greeter_SayHe
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func httpLogger(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
|
||||||
|
start := time.Now()
|
||||||
|
log := logger.From(request.Context()).WithFields(
|
||||||
|
"method", request.Method,
|
||||||
|
"host", request.Host,
|
||||||
|
"path", request.URL.Path,
|
||||||
|
"remoteAddress", request.RemoteAddr,
|
||||||
|
)
|
||||||
|
next.ServeHTTP(writer, request)
|
||||||
|
log.WithField("duration", time.Since(start)).Info()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
name := "greeter"
|
name := "greeter"
|
||||||
secure := true
|
secure := true
|
||||||
@ -71,6 +87,7 @@ func main() {
|
|||||||
service.WithGatewayPrefix("/rest"),
|
service.WithGatewayPrefix("/rest"),
|
||||||
service.WithGRPCWeb(true),
|
service.WithGRPCWeb(true),
|
||||||
service.WithGRPCWebPrefix("/grpc"),
|
service.WithGRPCWebPrefix("/grpc"),
|
||||||
|
service.WithMiddlewares(httpLogger),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -142,4 +159,3 @@ func main() {
|
|||||||
cancel()
|
cancel()
|
||||||
<-done
|
<-done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
go.mod
2
go.mod
@ -13,9 +13,11 @@ require (
|
|||||||
github.com/iancoleman/strcase v0.2.0 // indirect
|
github.com/iancoleman/strcase v0.2.0 // indirect
|
||||||
github.com/improbable-eng/grpc-web v0.14.1
|
github.com/improbable-eng/grpc-web v0.14.1
|
||||||
github.com/jinzhu/gorm v1.9.12
|
github.com/jinzhu/gorm v1.9.12
|
||||||
|
github.com/justinas/alice v1.2.0
|
||||||
github.com/lyft/protoc-gen-star v0.6.0 // indirect
|
github.com/lyft/protoc-gen-star v0.6.0 // indirect
|
||||||
github.com/miekg/dns v1.1.35
|
github.com/miekg/dns v1.1.35
|
||||||
github.com/planetscale/vtprotobuf v0.2.0
|
github.com/planetscale/vtprotobuf v0.2.0
|
||||||
|
github.com/rs/cors v1.7.0
|
||||||
github.com/sirupsen/logrus v1.8.1
|
github.com/sirupsen/logrus v1.8.1
|
||||||
github.com/soheilhy/cmux v0.1.5
|
github.com/soheilhy/cmux v0.1.5
|
||||||
github.com/spf13/cobra v1.0.0
|
github.com/spf13/cobra v1.0.0
|
||||||
|
2
go.sum
2
go.sum
@ -368,6 +368,8 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7
|
|||||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||||
|
github.com/justinas/alice v1.2.0 h1:+MHSA/vccVCF4Uq37S42jwlkvI2Xzl7zTPCN5BnZNVo=
|
||||||
|
github.com/justinas/alice v1.2.0/go.mod h1:fN5HRH/reO/zrUflLfTN43t3vXvKzvZIENsNEe7i7qA=
|
||||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package logger
|
package logger
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -14,7 +16,7 @@ func New() Logger {
|
|||||||
|
|
||||||
type Logger interface {
|
type Logger interface {
|
||||||
WithField(key string, value interface{}) Logger
|
WithField(key string, value interface{}) Logger
|
||||||
WithFields(kv ...string) Logger
|
WithFields(kv ...interface{}) Logger
|
||||||
WithError(err error) Logger
|
WithError(err error) Logger
|
||||||
|
|
||||||
Debugf(format string, args ...interface{})
|
Debugf(format string, args ...interface{})
|
||||||
@ -53,9 +55,9 @@ func (l *logger) WithField(key string, value interface{}) Logger {
|
|||||||
return &logger{FieldLogger: l.FieldLogger.WithField(key, value)}
|
return &logger{FieldLogger: l.FieldLogger.WithField(key, value)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *logger) WithFields(kv ...string) Logger {
|
func (l *logger) WithFields(kv ...interface{}) Logger {
|
||||||
for i := 0; i < len(kv); i += 2 {
|
for i := 0; i < len(kv); i += 2 {
|
||||||
l.FieldLogger = l.FieldLogger.WithField(kv[i], kv[i+1])
|
l.FieldLogger = l.FieldLogger.WithField(fmt.Sprintf("%v", kv[i]), kv[i+1])
|
||||||
}
|
}
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
@ -21,9 +21,9 @@ func (s *service) gateway(opts ...runtime.ServeMuxOption) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if s.opts.gatewayPrefix != "" {
|
if s.opts.gatewayPrefix != "" {
|
||||||
s.mux.Handle(s.opts.gatewayPrefix+"/", http.StripPrefix(s.opts.gatewayPrefix, mux))
|
s.opts.mux.Handle(s.opts.gatewayPrefix+"/", http.StripPrefix(s.opts.gatewayPrefix, mux))
|
||||||
} else {
|
} else {
|
||||||
s.mux.Handle("/", mux)
|
s.opts.mux.Handle("/", mux)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
15
service/mux.go
Normal file
15
service/mux.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/justinas/alice"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ServeMux interface {
|
||||||
|
ServeHTTP(http.ResponseWriter, *http.Request)
|
||||||
|
Handle(pattern string, handler http.Handler)
|
||||||
|
HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request))
|
||||||
|
}
|
||||||
|
|
||||||
|
type Middleware = alice.Constructor
|
@ -83,8 +83,8 @@ type Options interface {
|
|||||||
ClientInterceptors() []grpc.UnaryClientInterceptor
|
ClientInterceptors() []grpc.UnaryClientInterceptor
|
||||||
StreamClientInterceptors() []grpc.StreamClientInterceptor
|
StreamClientInterceptors() []grpc.StreamClientInterceptor
|
||||||
|
|
||||||
|
|
||||||
Cors() cors.Options
|
Cors() cors.Options
|
||||||
|
Mux() ServeMux
|
||||||
GRPCWeb() bool
|
GRPCWeb() bool
|
||||||
GRPCWebPrefix() string
|
GRPCWebPrefix() string
|
||||||
GRPCWebOpts() []grpcweb.Option
|
GRPCWebOpts() []grpcweb.Option
|
||||||
@ -266,6 +266,18 @@ func WithCors(opts cors.Options) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WithMux(mux ServeMux) Option {
|
||||||
|
return func(o *options) {
|
||||||
|
o.mux = mux
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithMiddlewares(m ...Middleware) Option {
|
||||||
|
return func(o *options) {
|
||||||
|
o.middlewares = m
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func WithGRPCWeb(b bool) Option {
|
func WithGRPCWeb(b bool) Option {
|
||||||
return func(o *options) {
|
return func(o *options) {
|
||||||
o.grpcWeb = b
|
o.grpcWeb = b
|
||||||
@ -334,6 +346,8 @@ type options struct {
|
|||||||
clientInterceptors []grpc.UnaryClientInterceptor
|
clientInterceptors []grpc.UnaryClientInterceptor
|
||||||
streamClientInterceptors []grpc.StreamClientInterceptor
|
streamClientInterceptors []grpc.StreamClientInterceptor
|
||||||
|
|
||||||
|
mux ServeMux
|
||||||
|
middlewares []Middleware
|
||||||
grpcWeb bool
|
grpcWeb bool
|
||||||
grpcWebOpts []grpcweb.Option
|
grpcWebOpts []grpcweb.Option
|
||||||
grpcWebPrefix string
|
grpcWebPrefix string
|
||||||
@ -433,6 +447,10 @@ func (o *options) Cors() cors.Options {
|
|||||||
return o.cors
|
return o.cors
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *options) Mux() ServeMux {
|
||||||
|
return o.mux
|
||||||
|
}
|
||||||
|
|
||||||
func (o *options) GRPCWeb() bool {
|
func (o *options) GRPCWeb() bool {
|
||||||
return o.grpcWeb
|
return o.grpcWeb
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import (
|
|||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
grpcmiddleware "github.com/grpc-ecosystem/go-grpc-middleware"
|
grpcmiddleware "github.com/grpc-ecosystem/go-grpc-middleware"
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
|
"github.com/justinas/alice"
|
||||||
"github.com/rs/cors"
|
"github.com/rs/cors"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/soheilhy/cmux"
|
"github.com/soheilhy/cmux"
|
||||||
@ -54,7 +55,6 @@ type service struct {
|
|||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
running bool
|
running bool
|
||||||
|
|
||||||
mux *http.ServeMux
|
|
||||||
// inproc Channel is used to serve grpc gateway
|
// inproc Channel is used to serve grpc gateway
|
||||||
inproc *inprocgrpc.Channel
|
inproc *inprocgrpc.Channel
|
||||||
|
|
||||||
@ -71,7 +71,6 @@ func newService(opts ...Option) (*service, error) {
|
|||||||
opts: parseFlags(NewOptions()),
|
opts: parseFlags(NewOptions()),
|
||||||
cmd: cmd,
|
cmd: cmd,
|
||||||
id: uuid.New().String(),
|
id: uuid.New().String(),
|
||||||
mux: http.NewServeMux(),
|
|
||||||
inproc: &inprocgrpc.Channel{},
|
inproc: &inprocgrpc.Channel{},
|
||||||
}
|
}
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
@ -79,6 +78,9 @@ func newService(opts ...Option) (*service, error) {
|
|||||||
for _, f := range opts {
|
for _, f := range opts {
|
||||||
f(s.opts)
|
f(s.opts)
|
||||||
}
|
}
|
||||||
|
if s.opts.mux == nil {
|
||||||
|
s.opts.mux = http.NewServeMux()
|
||||||
|
}
|
||||||
if s.opts.error != nil {
|
if s.opts.error != nil {
|
||||||
return nil, s.opts.error
|
return nil, s.opts.error
|
||||||
}
|
}
|
||||||
@ -194,7 +196,7 @@ func (s *service) run() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
hServer := &http.Server{
|
hServer := &http.Server{
|
||||||
Handler: cors.New(s.opts.cors).Handler(s.mux),
|
Handler: alice.New(s.opts.middlewares...).Then(cors.New(s.opts.cors).Handler(s.opts.mux)),
|
||||||
}
|
}
|
||||||
if s.opts.Gateway() || s.opts.grpcWeb {
|
if s.opts.Gateway() || s.opts.grpcWeb {
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -26,9 +26,9 @@ func (s *service) grpcWeb(opts ...grpcweb.Option) error {
|
|||||||
h := grpcweb.WrapServer(s.server, append(defaultWebOptions, opts...)...)
|
h := grpcweb.WrapServer(s.server, append(defaultWebOptions, opts...)...)
|
||||||
for _, v := range grpcweb.ListGRPCResources(s.server) {
|
for _, v := range grpcweb.ListGRPCResources(s.server) {
|
||||||
if s.opts.grpcWebPrefix != "" {
|
if s.opts.grpcWebPrefix != "" {
|
||||||
s.mux.Handle(s.opts.grpcWebPrefix+v, http.StripPrefix(s.opts.grpcWebPrefix, h))
|
s.opts.mux.Handle(s.opts.grpcWebPrefix+v, http.StripPrefix(s.opts.grpcWebPrefix, h))
|
||||||
} else {
|
} else {
|
||||||
s.mux.Handle(v, h)
|
s.opts.mux.Handle(v, h)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
Loading…
Reference in New Issue
Block a user