mirror of
https://github.com/go-micro/go-micro.git
synced 2025-06-18 22:17:44 +02:00
feat(logger): add logger option to all micro components (override DefaultLogger) closes #2556 (#2559)
* feat(logger): add logger option to all components * fix: refactor api/rpc.go * fix: refactor api/stream.go * fix: api/options.go comment * fix(logger): do not use logger.Helper internally * fix(logger): fix comments * fix(logger): use level.Enabled method * fix: rename mlogger to log * fix: run go fmt * fix: log level * fix: factories Co-authored-by: Mohamed MHAMDI <mmhamdi@hubside.com> Co-authored-by: Davincible <david.brouwer.99@gmail.com>
This commit is contained in:
@ -3,6 +3,7 @@ package handler
|
|||||||
import (
|
import (
|
||||||
"go-micro.dev/v4/api/router"
|
"go-micro.dev/v4/api/router"
|
||||||
"go-micro.dev/v4/client"
|
"go-micro.dev/v4/client"
|
||||||
|
"go-micro.dev/v4/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -14,13 +15,17 @@ type Options struct {
|
|||||||
Namespace string
|
Namespace string
|
||||||
Router router.Router
|
Router router.Router
|
||||||
Client client.Client
|
Client client.Client
|
||||||
|
Logger logger.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
type Option func(o *Options)
|
type Option func(o *Options)
|
||||||
|
|
||||||
// NewOptions fills in the blanks
|
// NewOptions fills in the blanks
|
||||||
func NewOptions(opts ...Option) Options {
|
func NewOptions(opts ...Option) Options {
|
||||||
var options Options
|
options := Options{
|
||||||
|
Logger: logger.DefaultLogger,
|
||||||
|
}
|
||||||
|
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(&options)
|
o(&options)
|
||||||
}
|
}
|
||||||
@ -33,6 +38,10 @@ func NewOptions(opts ...Option) Options {
|
|||||||
options.MaxRecvSize = DefaultMaxRecvSize
|
options.MaxRecvSize = DefaultMaxRecvSize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if options.Logger == nil {
|
||||||
|
options.Logger = logger.LoggerOrDefault(options.Logger)
|
||||||
|
}
|
||||||
|
|
||||||
return options
|
return options
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,9 +65,16 @@ func WithClient(c client.Client) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithmaxRecvSize specifies max body size
|
// WithMaxRecvSize specifies max body size
|
||||||
func WithMaxRecvSize(size int64) Option {
|
func WithMaxRecvSize(size int64) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.MaxRecvSize = size
|
o.MaxRecvSize = size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithLogger specifies the logger
|
||||||
|
func WithLogger(l logger.Logger) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.Logger = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
|
|
||||||
jsonpatch "github.com/evanphx/json-patch/v5"
|
jsonpatch "github.com/evanphx/json-patch/v5"
|
||||||
"github.com/oxtoacart/bpool"
|
"github.com/oxtoacart/bpool"
|
||||||
|
|
||||||
"go-micro.dev/v4/api/handler"
|
"go-micro.dev/v4/api/handler"
|
||||||
"go-micro.dev/v4/api/internal/proto"
|
"go-micro.dev/v4/api/internal/proto"
|
||||||
"go-micro.dev/v4/api/router"
|
"go-micro.dev/v4/api/router"
|
||||||
@ -19,7 +20,7 @@ import (
|
|||||||
"go-micro.dev/v4/codec/jsonrpc"
|
"go-micro.dev/v4/codec/jsonrpc"
|
||||||
"go-micro.dev/v4/codec/protorpc"
|
"go-micro.dev/v4/codec/protorpc"
|
||||||
"go-micro.dev/v4/errors"
|
"go-micro.dev/v4/errors"
|
||||||
"go-micro.dev/v4/logger"
|
log "go-micro.dev/v4/logger"
|
||||||
"go-micro.dev/v4/metadata"
|
"go-micro.dev/v4/metadata"
|
||||||
"go-micro.dev/v4/registry"
|
"go-micro.dev/v4/registry"
|
||||||
"go-micro.dev/v4/selector"
|
"go-micro.dev/v4/selector"
|
||||||
@ -29,6 +30,7 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
Handler = "rpc"
|
Handler = "rpc"
|
||||||
|
packageID = "go.micro.api"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -73,6 +75,7 @@ func strategy(services []*registry.Service) selector.Strategy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *rpcHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (h *rpcHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
logger := h.opts.Logger
|
||||||
bsize := handler.DefaultMaxRecvSize
|
bsize := handler.DefaultMaxRecvSize
|
||||||
if h.opts.MaxRecvSize > 0 {
|
if h.opts.MaxRecvSize > 0 {
|
||||||
bsize = h.opts.MaxRecvSize
|
bsize = h.opts.MaxRecvSize
|
||||||
@ -87,13 +90,19 @@ func (h *rpcHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
// try get service from router
|
// try get service from router
|
||||||
s, err := h.opts.Router.Route(r)
|
s, err := h.opts.Router.Route(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(w, r, errors.InternalServerError("go.micro.api", err.Error()))
|
werr := writeError(w, r, errors.InternalServerError(packageID, err.Error()))
|
||||||
|
if werr != nil {
|
||||||
|
logger.Log(log.ErrorLevel, werr)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
service = s
|
service = s
|
||||||
} else {
|
} else {
|
||||||
// we have no way of routing the request
|
// we have no way of routing the request
|
||||||
writeError(w, r, errors.InternalServerError("go.micro.api", "no route found"))
|
werr := writeError(w, r, errors.InternalServerError(packageID, "no route found"))
|
||||||
|
if werr != nil {
|
||||||
|
logger.Log(log.ErrorLevel, werr)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,7 +142,9 @@ func (h *rpcHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
// drop older context as it can have timeouts and create new
|
// drop older context as it can have timeouts and create new
|
||||||
// md, _ := metadata.FromContext(cx)
|
// md, _ := metadata.FromContext(cx)
|
||||||
//serveWebsocket(context.TODO(), w, r, service, c)
|
//serveWebsocket(context.TODO(), w, r, service, c)
|
||||||
serveWebsocket(cx, w, r, service, c)
|
if err := serveWebsocket(cx, w, r, service, c); err != nil {
|
||||||
|
logger.Log(log.ErrorLevel, err)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +155,9 @@ func (h *rpcHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
// get payload
|
// get payload
|
||||||
br, err := requestPayload(r)
|
br, err := requestPayload(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(w, r, err)
|
if werr := writeError(w, r, err); werr != nil {
|
||||||
|
logger.Log(log.ErrorLevel, werr)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,14 +184,18 @@ func (h *rpcHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// make the call
|
// make the call
|
||||||
if err := c.Call(cx, req, response, client.WithSelectOption(so)); err != nil {
|
if err := c.Call(cx, req, response, client.WithSelectOption(so)); err != nil {
|
||||||
writeError(w, r, err)
|
if werr := writeError(w, r, err); werr != nil {
|
||||||
|
logger.Log(log.ErrorLevel, werr)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// marshall response
|
// marshall response
|
||||||
rsp, err = response.Marshal()
|
rsp, err = response.Marshal()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(w, r, err)
|
if werr := writeError(w, r, err); werr != nil {
|
||||||
|
logger.Log(log.ErrorLevel, werr)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,20 +223,26 @@ func (h *rpcHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
)
|
)
|
||||||
// make the call
|
// make the call
|
||||||
if err := c.Call(cx, req, &response, client.WithSelectOption(so)); err != nil {
|
if err := c.Call(cx, req, &response, client.WithSelectOption(so)); err != nil {
|
||||||
writeError(w, r, err)
|
if werr := writeError(w, r, err); werr != nil {
|
||||||
|
logger.Log(log.ErrorLevel, werr)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// marshall response
|
// marshall response
|
||||||
rsp, err = response.MarshalJSON()
|
rsp, err = response.MarshalJSON()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(w, r, err)
|
if werr := writeError(w, r, err); werr != nil {
|
||||||
|
logger.Log(log.ErrorLevel, werr)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// write the response
|
// write the response
|
||||||
writeResponse(w, r, rsp)
|
if err := writeResponse(w, r, rsp); err != nil {
|
||||||
|
logger.Log(log.ErrorLevel, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rh *rpcHandler) String() string {
|
func (rh *rpcHandler) String() string {
|
||||||
@ -275,7 +298,9 @@ func requestPayload(r *http.Request) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
return raw.Marshal()
|
return raw.Marshal()
|
||||||
case strings.Contains(ct, "application/www-x-form-urlencoded"):
|
case strings.Contains(ct, "application/www-x-form-urlencoded"):
|
||||||
r.ParseForm()
|
if err := r.ParseForm(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// generate a new set of values from the form
|
// generate a new set of values from the form
|
||||||
vals := make(map[string]string)
|
vals := make(map[string]string)
|
||||||
@ -441,14 +466,14 @@ func requestPayload(r *http.Request) ([]byte, error) {
|
|||||||
return []byte{}, nil
|
return []byte{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeError(w http.ResponseWriter, r *http.Request, err error) {
|
func writeError(w http.ResponseWriter, r *http.Request, err error) error {
|
||||||
ce := errors.Parse(err.Error())
|
ce := errors.Parse(err.Error())
|
||||||
|
|
||||||
switch ce.Code {
|
switch ce.Code {
|
||||||
case 0:
|
case 0:
|
||||||
// assuming it's totally screwed
|
// assuming it's totally screwed
|
||||||
ce.Code = 500
|
ce.Code = 500
|
||||||
ce.Id = "go.micro.api"
|
ce.Id = packageID
|
||||||
ce.Status = http.StatusText(500)
|
ce.Status = http.StatusText(500)
|
||||||
ce.Detail = "error during request: " + ce.Detail
|
ce.Detail = "error during request: " + ce.Detail
|
||||||
w.WriteHeader(500)
|
w.WriteHeader(500)
|
||||||
@ -468,14 +493,10 @@ func writeError(w http.ResponseWriter, r *http.Request, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_, werr := w.Write([]byte(ce.Error()))
|
_, werr := w.Write([]byte(ce.Error()))
|
||||||
if werr != nil {
|
return werr
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
|
||||||
logger.Error(werr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeResponse(w http.ResponseWriter, r *http.Request, rsp []byte) {
|
func writeResponse(w http.ResponseWriter, r *http.Request, rsp []byte) error {
|
||||||
w.Header().Set("Content-Type", r.Header.Get("Content-Type"))
|
w.Header().Set("Content-Type", r.Header.Get("Content-Type"))
|
||||||
w.Header().Set("Content-Length", strconv.Itoa(len(rsp)))
|
w.Header().Set("Content-Length", strconv.Itoa(len(rsp)))
|
||||||
|
|
||||||
@ -494,12 +515,7 @@ func writeResponse(w http.ResponseWriter, r *http.Request, rsp []byte) {
|
|||||||
|
|
||||||
// write response
|
// write response
|
||||||
_, err := w.Write(rsp)
|
_, err := w.Write(rsp)
|
||||||
if err != nil {
|
return err
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
|
||||||
logger.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHandler(opts ...handler.Option) handler.Handler {
|
func NewHandler(opts ...handler.Option) handler.Handler {
|
||||||
|
@ -12,15 +12,15 @@ import (
|
|||||||
"github.com/gobwas/httphead"
|
"github.com/gobwas/httphead"
|
||||||
"github.com/gobwas/ws"
|
"github.com/gobwas/ws"
|
||||||
"github.com/gobwas/ws/wsutil"
|
"github.com/gobwas/ws/wsutil"
|
||||||
|
|
||||||
"go-micro.dev/v4/api/router"
|
"go-micro.dev/v4/api/router"
|
||||||
"go-micro.dev/v4/client"
|
"go-micro.dev/v4/client"
|
||||||
raw "go-micro.dev/v4/codec/bytes"
|
raw "go-micro.dev/v4/codec/bytes"
|
||||||
"go-micro.dev/v4/logger"
|
|
||||||
"go-micro.dev/v4/selector"
|
"go-micro.dev/v4/selector"
|
||||||
)
|
)
|
||||||
|
|
||||||
// serveWebsocket will stream rpc back over websockets assuming json
|
// serveWebsocket will stream rpc back over websockets assuming json
|
||||||
func serveWebsocket(ctx context.Context, w http.ResponseWriter, r *http.Request, service *router.Route, c client.Client) {
|
func serveWebsocket(ctx context.Context, w http.ResponseWriter, r *http.Request, service *router.Route, c client.Client) (err error) {
|
||||||
var op ws.OpCode
|
var op ws.OpCode
|
||||||
|
|
||||||
ct := r.Header.Get("Content-Type")
|
ct := r.Header.Get("Content-Type")
|
||||||
@ -49,9 +49,6 @@ func serveWebsocket(ctx context.Context, w http.ResponseWriter, r *http.Request,
|
|||||||
}
|
}
|
||||||
payload, err := requestPayload(r)
|
payload, err := requestPayload(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
|
||||||
logger.Error(err)
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,18 +69,12 @@ func serveWebsocket(ctx context.Context, w http.ResponseWriter, r *http.Request,
|
|||||||
|
|
||||||
conn, rw, _, err := upgrader.Upgrade(r, w)
|
conn, rw, _, err := upgrader.Upgrade(r, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
|
||||||
logger.Error(err)
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := conn.Close(); err != nil {
|
if cErr := conn.Close(); cErr != nil && err == nil {
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
err = cErr
|
||||||
logger.Error(err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -114,22 +105,20 @@ func serveWebsocket(ctx context.Context, w http.ResponseWriter, r *http.Request,
|
|||||||
// create a new stream
|
// create a new stream
|
||||||
stream, err := c.Stream(ctx, req, client.WithSelectOption(so))
|
stream, err := c.Stream(ctx, req, client.WithSelectOption(so))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
|
||||||
logger.Error(err)
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if request != nil {
|
if request != nil {
|
||||||
if err = stream.Send(request); err != nil {
|
if err = stream.Send(request); err != nil {
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
|
||||||
logger.Error(err)
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
go writeLoop(rw, stream)
|
go func() {
|
||||||
|
if wErr := writeLoop(rw, stream); wErr != nil && err == nil {
|
||||||
|
err = wErr
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
rsp := stream.Response()
|
rsp := stream.Response()
|
||||||
|
|
||||||
@ -137,49 +126,40 @@ func serveWebsocket(ctx context.Context, w http.ResponseWriter, r *http.Request,
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return
|
return nil
|
||||||
case <-stream.Context().Done():
|
case <-stream.Context().Done():
|
||||||
return
|
return nil
|
||||||
default:
|
default:
|
||||||
// read backend response body
|
// read backend response body
|
||||||
buf, err := rsp.Read()
|
buf, err := rsp.Read()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// wants to avoid import grpc/status.Status
|
// wants to avoid import grpc/status.Status
|
||||||
if strings.Contains(err.Error(), "context canceled") {
|
if strings.Contains(err.Error(), "context canceled") {
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
return err
|
||||||
logger.Error(err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// write the response
|
// write the response
|
||||||
if err := wsutil.WriteServerMessage(rw, op, buf); err != nil {
|
if err = wsutil.WriteServerMessage(rw, op, buf); err != nil {
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
return err
|
||||||
logger.Error(err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if err = rw.Flush(); err != nil {
|
if err = rw.Flush(); err != nil {
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
return err
|
||||||
logger.Error(err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeLoop
|
// writeLoop
|
||||||
func writeLoop(rw io.ReadWriter, stream client.Stream) {
|
func writeLoop(rw io.ReadWriter, stream client.Stream) error {
|
||||||
// close stream when done
|
// close stream when done
|
||||||
defer stream.Close()
|
defer stream.Close()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-stream.Context().Done():
|
case <-stream.Context().Done():
|
||||||
return
|
return nil
|
||||||
default:
|
default:
|
||||||
buf, op, err := wsutil.ReadClientData(rw)
|
buf, op, err := wsutil.ReadClientData(rw)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -187,16 +167,13 @@ func writeLoop(rw io.ReadWriter, stream client.Stream) {
|
|||||||
switch wserr.Code {
|
switch wserr.Code {
|
||||||
case ws.StatusGoingAway:
|
case ws.StatusGoingAway:
|
||||||
// this happens when user leave the page
|
// this happens when user leave the page
|
||||||
return
|
return nil
|
||||||
case ws.StatusNormalClosure, ws.StatusNoStatusRcvd:
|
case ws.StatusNormalClosure, ws.StatusNoStatusRcvd:
|
||||||
// this happens when user close ws connection, or we don't get any status
|
// this happens when user close ws connection, or we don't get any status
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
return err
|
||||||
logger.Error(err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
switch op {
|
switch op {
|
||||||
default:
|
default:
|
||||||
@ -210,10 +187,7 @@ func writeLoop(rw io.ReadWriter, stream client.Stream) {
|
|||||||
// if the extracted payload isn't empty lets use it
|
// if the extracted payload isn't empty lets use it
|
||||||
request := &raw.Frame{Data: buf}
|
request := &raw.Frame{Data: buf}
|
||||||
if err := stream.Send(request); err != nil {
|
if err := stream.Send(request); err != nil {
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
return err
|
||||||
logger.Error(err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package router
|
|||||||
import (
|
import (
|
||||||
"go-micro.dev/v4/api/resolver"
|
"go-micro.dev/v4/api/resolver"
|
||||||
"go-micro.dev/v4/api/resolver/vpath"
|
"go-micro.dev/v4/api/resolver/vpath"
|
||||||
|
"go-micro.dev/v4/logger"
|
||||||
"go-micro.dev/v4/registry"
|
"go-micro.dev/v4/registry"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -10,6 +11,7 @@ type Options struct {
|
|||||||
Handler string
|
Handler string
|
||||||
Registry registry.Registry
|
Registry registry.Registry
|
||||||
Resolver resolver.Resolver
|
Resolver resolver.Resolver
|
||||||
|
Logger logger.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
type Option func(o *Options)
|
type Option func(o *Options)
|
||||||
@ -18,6 +20,7 @@ func NewOptions(opts ...Option) Options {
|
|||||||
options := Options{
|
options := Options{
|
||||||
Handler: "meta",
|
Handler: "meta",
|
||||||
Registry: registry.DefaultRegistry,
|
Registry: registry.DefaultRegistry,
|
||||||
|
Logger: logger.DefaultLogger,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
@ -50,3 +53,10 @@ func WithResolver(r resolver.Resolver) Option {
|
|||||||
o.Resolver = r
|
o.Resolver = r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithLogger sets the underline logger
|
||||||
|
func WithLogger(l logger.Logger) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.Logger = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
|
|
||||||
"go-micro.dev/v4/api/router"
|
"go-micro.dev/v4/api/router"
|
||||||
"go-micro.dev/v4/api/router/util"
|
"go-micro.dev/v4/api/router/util"
|
||||||
"go-micro.dev/v4/logger"
|
log "go-micro.dev/v4/logger"
|
||||||
"go-micro.dev/v4/metadata"
|
"go-micro.dev/v4/metadata"
|
||||||
"go-micro.dev/v4/registry"
|
"go-micro.dev/v4/registry"
|
||||||
"go-micro.dev/v4/registry/cache"
|
"go-micro.dev/v4/registry/cache"
|
||||||
@ -51,14 +51,13 @@ func (r *registryRouter) isStopped() bool {
|
|||||||
// refresh list of api services
|
// refresh list of api services
|
||||||
func (r *registryRouter) refresh() {
|
func (r *registryRouter) refresh() {
|
||||||
var attempts int
|
var attempts int
|
||||||
|
logger := r.Options().Logger
|
||||||
|
|
||||||
for {
|
for {
|
||||||
services, err := r.opts.Registry.ListServices()
|
services, err := r.opts.Registry.ListServices()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
attempts++
|
attempts++
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
logger.Logf(log.ErrorLevel, "unable to list services: %v", err)
|
||||||
logger.Errorf("unable to list services: %v", err)
|
|
||||||
}
|
|
||||||
time.Sleep(time.Duration(attempts) * time.Second)
|
time.Sleep(time.Duration(attempts) * time.Second)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -69,9 +68,7 @@ func (r *registryRouter) refresh() {
|
|||||||
for _, s := range services {
|
for _, s := range services {
|
||||||
service, err := r.rc.GetService(s.Name)
|
service, err := r.rc.GetService(s.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
logger.Logf(log.ErrorLevel, "unable to get service: %v", err)
|
||||||
logger.Errorf("unable to get service: %v", err)
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
r.store(service)
|
r.store(service)
|
||||||
@ -89,6 +86,7 @@ func (r *registryRouter) refresh() {
|
|||||||
|
|
||||||
// process watch event
|
// process watch event
|
||||||
func (r *registryRouter) process(res *registry.Result) {
|
func (r *registryRouter) process(res *registry.Result) {
|
||||||
|
logger := r.Options().Logger
|
||||||
// skip these things
|
// skip these things
|
||||||
if res == nil || res.Service == nil {
|
if res == nil || res.Service == nil {
|
||||||
return
|
return
|
||||||
@ -97,9 +95,7 @@ func (r *registryRouter) process(res *registry.Result) {
|
|||||||
// get entry from cache
|
// get entry from cache
|
||||||
service, err := r.rc.GetService(res.Service.Name)
|
service, err := r.rc.GetService(res.Service.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
logger.Logf(log.ErrorLevel, "unable to get service: %v", err)
|
||||||
logger.Errorf("unable to get service: %v", err)
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,6 +105,7 @@ func (r *registryRouter) process(res *registry.Result) {
|
|||||||
|
|
||||||
// store local endpoint cache
|
// store local endpoint cache
|
||||||
func (r *registryRouter) store(services []*registry.Service) {
|
func (r *registryRouter) store(services []*registry.Service) {
|
||||||
|
logger := r.Options().Logger
|
||||||
// endpoints
|
// endpoints
|
||||||
eps := map[string]*router.Route{}
|
eps := map[string]*router.Route{}
|
||||||
|
|
||||||
@ -129,9 +126,7 @@ func (r *registryRouter) store(services []*registry.Service) {
|
|||||||
|
|
||||||
// if we got nothing skip
|
// if we got nothing skip
|
||||||
if err := router.Validate(end); err != nil {
|
if err := router.Validate(end); err != nil {
|
||||||
if logger.V(logger.TraceLevel, logger.DefaultLogger) {
|
logger.Logf(log.TraceLevel, "endpoint validation failed: %v", err)
|
||||||
logger.Tracef("endpoint validation failed: %v", err)
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,9 +171,7 @@ func (r *registryRouter) store(services []*registry.Service) {
|
|||||||
}
|
}
|
||||||
hostreg, err := regexp.CompilePOSIX(h)
|
hostreg, err := regexp.CompilePOSIX(h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if logger.V(logger.TraceLevel, logger.DefaultLogger) {
|
logger.Logf(log.TraceLevel, "endpoint have invalid host regexp: %v", err)
|
||||||
logger.Tracef("endpoint have invalid host regexp: %v", err)
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
cep.hostregs = append(cep.hostregs, hostreg)
|
cep.hostregs = append(cep.hostregs, hostreg)
|
||||||
@ -197,20 +190,16 @@ func (r *registryRouter) store(services []*registry.Service) {
|
|||||||
|
|
||||||
rule, err := util.Parse(p)
|
rule, err := util.Parse(p)
|
||||||
if err != nil && !pcreok {
|
if err != nil && !pcreok {
|
||||||
if logger.V(logger.TraceLevel, logger.DefaultLogger) {
|
logger.Logf(log.TraceLevel, "endpoint have invalid path pattern: %v", err)
|
||||||
logger.Tracef("endpoint have invalid path pattern: %v", err)
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
} else if err != nil && pcreok {
|
} else if err != nil && pcreok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
tpl := rule.Compile()
|
tpl := rule.Compile()
|
||||||
pathreg, err := util.NewPattern(tpl.Version, tpl.OpCodes, tpl.Pool, "")
|
pathreg, err := util.NewPattern(tpl.Version, tpl.OpCodes, tpl.Pool, "", util.PatternLogger(logger))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if logger.V(logger.TraceLevel, logger.DefaultLogger) {
|
logger.Logf(log.TraceLevel, "endpoint have invalid path pattern: %v", err)
|
||||||
logger.Tracef("endpoint have invalid path pattern: %v", err)
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
cep.pathregs = append(cep.pathregs, pathreg)
|
cep.pathregs = append(cep.pathregs, pathreg)
|
||||||
@ -223,6 +212,7 @@ func (r *registryRouter) store(services []*registry.Service) {
|
|||||||
// watch for endpoint changes
|
// watch for endpoint changes
|
||||||
func (r *registryRouter) watch() {
|
func (r *registryRouter) watch() {
|
||||||
var attempts int
|
var attempts int
|
||||||
|
logger := r.Options().Logger
|
||||||
|
|
||||||
for {
|
for {
|
||||||
if r.isStopped() {
|
if r.isStopped() {
|
||||||
@ -233,9 +223,7 @@ func (r *registryRouter) watch() {
|
|||||||
w, err := r.opts.Registry.Watch()
|
w, err := r.opts.Registry.Watch()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
attempts++
|
attempts++
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
logger.Logf(log.ErrorLevel, "error watching endpoints: %v", err)
|
||||||
logger.Errorf("error watching endpoints: %v", err)
|
|
||||||
}
|
|
||||||
time.Sleep(time.Duration(attempts) * time.Second)
|
time.Sleep(time.Duration(attempts) * time.Second)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -258,9 +246,7 @@ func (r *registryRouter) watch() {
|
|||||||
// process next event
|
// process next event
|
||||||
res, err := w.Next()
|
res, err := w.Next()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
logger.Logf(log.ErrorLevel, "error getting next endoint: %v", err)
|
||||||
logger.Errorf("error getting next endoint: %v", err)
|
|
||||||
}
|
|
||||||
close(ch)
|
close(ch)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -293,6 +279,7 @@ func (r *registryRouter) Deregister(ep *router.Route) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *registryRouter) Endpoint(req *http.Request) (*router.Route, error) {
|
func (r *registryRouter) Endpoint(req *http.Request) (*router.Route, error) {
|
||||||
|
logger := r.Options().Logger
|
||||||
if r.isStopped() {
|
if r.isStopped() {
|
||||||
return nil, errors.New("router closed")
|
return nil, errors.New("router closed")
|
||||||
}
|
}
|
||||||
@ -325,9 +312,8 @@ func (r *registryRouter) Endpoint(req *http.Request) (*router.Route, error) {
|
|||||||
if !mMatch {
|
if !mMatch {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
|
||||||
logger.Debugf("api method match %s", req.Method)
|
logger.Logf(log.DebugLevel, "api method match %s", req.Method)
|
||||||
}
|
|
||||||
|
|
||||||
// 2. try host
|
// 2. try host
|
||||||
if len(ep.Host) == 0 {
|
if len(ep.Host) == 0 {
|
||||||
@ -348,22 +334,17 @@ func (r *registryRouter) Endpoint(req *http.Request) (*router.Route, error) {
|
|||||||
if !hMatch {
|
if !hMatch {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
|
||||||
logger.Debugf("api host match %s", req.URL.Host)
|
logger.Logf(log.DebugLevel, "api host match %s", req.URL.Host)
|
||||||
}
|
|
||||||
|
|
||||||
// 3. try path via google.api path matching
|
// 3. try path via google.api path matching
|
||||||
for _, pathreg := range cep.pathregs {
|
for _, pathreg := range cep.pathregs {
|
||||||
matches, err := pathreg.Match(path, "")
|
matches, err := pathreg.Match(path, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "api gpath not match %s != %v", path, pathreg)
|
||||||
logger.Debugf("api gpath not match %s != %v", path, pathreg)
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "api gpath match %s = %v", path, pathreg)
|
||||||
logger.Debugf("api gpath match %s = %v", path, pathreg)
|
|
||||||
}
|
|
||||||
pMatch = true
|
pMatch = true
|
||||||
ctx := req.Context()
|
ctx := req.Context()
|
||||||
md, ok := metadata.FromContext(ctx)
|
md, ok := metadata.FromContext(ctx)
|
||||||
@ -381,14 +362,10 @@ func (r *registryRouter) Endpoint(req *http.Request) (*router.Route, error) {
|
|||||||
// 4. try path via pcre path matching
|
// 4. try path via pcre path matching
|
||||||
for _, pathreg := range cep.pcreregs {
|
for _, pathreg := range cep.pcreregs {
|
||||||
if !pathreg.MatchString(req.URL.Path) {
|
if !pathreg.MatchString(req.URL.Path) {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "api pcre path not match %s != %v", path, pathreg)
|
||||||
logger.Debugf("api pcre path not match %s != %v", path, pathreg)
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "api pcre path match %s != %v", path, pathreg)
|
||||||
logger.Debugf("api pcre path match %s != %v", path, pathreg)
|
|
||||||
}
|
|
||||||
pMatch = true
|
pMatch = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
|
|
||||||
"go-micro.dev/v4/api/router"
|
"go-micro.dev/v4/api/router"
|
||||||
"go-micro.dev/v4/api/router/util"
|
"go-micro.dev/v4/api/router/util"
|
||||||
"go-micro.dev/v4/logger"
|
log "go-micro.dev/v4/logger"
|
||||||
"go-micro.dev/v4/metadata"
|
"go-micro.dev/v4/metadata"
|
||||||
"go-micro.dev/v4/registry"
|
"go-micro.dev/v4/registry"
|
||||||
rutil "go-micro.dev/v4/util/registry"
|
rutil "go-micro.dev/v4/util/registry"
|
||||||
@ -129,7 +129,7 @@ func (r *staticRouter) Register(route *router.Route) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tpl := rule.Compile()
|
tpl := rule.Compile()
|
||||||
pathreg, err := util.NewPattern(tpl.Version, tpl.OpCodes, tpl.Pool, "")
|
pathreg, err := util.NewPattern(tpl.Version, tpl.OpCodes, tpl.Pool, "", util.PatternLogger(r.Options().Logger))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -222,6 +222,7 @@ func (r *staticRouter) Endpoint(req *http.Request) (*router.Route, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *staticRouter) endpoint(req *http.Request) (*endpoint, error) {
|
func (r *staticRouter) endpoint(req *http.Request) (*endpoint, error) {
|
||||||
|
logger := r.Options().Logger
|
||||||
if r.isStopd() {
|
if r.isStopd() {
|
||||||
return nil, errors.New("router closed")
|
return nil, errors.New("router closed")
|
||||||
}
|
}
|
||||||
@ -250,9 +251,7 @@ func (r *staticRouter) endpoint(req *http.Request) (*endpoint, error) {
|
|||||||
if !mMatch {
|
if !mMatch {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "api method match %s", req.Method)
|
||||||
logger.Debugf("api method match %s", req.Method)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. try host
|
// 2. try host
|
||||||
if len(ep.apiep.Host) == 0 {
|
if len(ep.apiep.Host) == 0 {
|
||||||
@ -273,22 +272,16 @@ func (r *staticRouter) endpoint(req *http.Request) (*endpoint, error) {
|
|||||||
if !hMatch {
|
if !hMatch {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "api host match %s", req.URL.Host)
|
||||||
logger.Debugf("api host match %s", req.URL.Host)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. try google.api path
|
// 3. try google.api path
|
||||||
for _, pathreg := range ep.pathregs {
|
for _, pathreg := range ep.pathregs {
|
||||||
matches, err := pathreg.Match(path, "")
|
matches, err := pathreg.Match(path, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "api gpath not match %s != %v", path, pathreg)
|
||||||
logger.Debugf("api gpath not match %s != %v", path, pathreg)
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "api gpath match %s = %v", path, pathreg)
|
||||||
logger.Debugf("api gpath match %s = %v", path, pathreg)
|
|
||||||
}
|
|
||||||
pMatch = true
|
pMatch = true
|
||||||
ctx := req.Context()
|
ctx := req.Context()
|
||||||
md, ok := metadata.FromContext(ctx)
|
md, ok := metadata.FromContext(ctx)
|
||||||
@ -306,9 +299,7 @@ func (r *staticRouter) endpoint(req *http.Request) (*endpoint, error) {
|
|||||||
// 4. try path via pcre path matching
|
// 4. try path via pcre path matching
|
||||||
for _, pathreg := range ep.pcreregs {
|
for _, pathreg := range ep.pcreregs {
|
||||||
if !pathreg.MatchString(req.URL.Path) {
|
if !pathreg.MatchString(req.URL.Path) {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "api pcre path not match %s != %v", req.URL.Path, pathreg)
|
||||||
logger.Debugf("api pcre path not match %s != %v", req.URL.Path, pathreg)
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
pMatch = true
|
pMatch = true
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"go-micro.dev/v4/logger"
|
log "go-micro.dev/v4/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
// InvalidTemplateError indicates that the path template is not valid.
|
// InvalidTemplateError indicates that the path template is not valid.
|
||||||
@ -98,38 +98,36 @@ func tokenize(path string) (tokens []string, verb string) {
|
|||||||
type parser struct {
|
type parser struct {
|
||||||
tokens []string
|
tokens []string
|
||||||
accepted []string
|
accepted []string
|
||||||
|
logger log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
// topLevelSegments is the target of this parser.
|
// topLevelSegments is the target of this parser.
|
||||||
func (p *parser) topLevelSegments() ([]segment, error) {
|
func (p *parser) topLevelSegments() ([]segment, error) {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger := log.LoggerOrDefault(p.logger)
|
||||||
logger.Debugf("Parsing %q", p.tokens)
|
|
||||||
}
|
logger.Logf(log.DebugLevel, "Parsing %q", p.tokens)
|
||||||
|
|
||||||
segs, err := p.segments()
|
segs, err := p.segments()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "accept segments: %q; %q", p.accepted, p.tokens)
|
||||||
logger.Debugf("accept segments: %q; %q", p.accepted, p.tokens)
|
|
||||||
}
|
|
||||||
if _, err := p.accept(typeEOF); err != nil {
|
if _, err := p.accept(typeEOF); err != nil {
|
||||||
return nil, fmt.Errorf("unexpected token %q after segments %q", p.tokens[0], strings.Join(p.accepted, ""))
|
return nil, fmt.Errorf("unexpected token %q after segments %q", p.tokens[0], strings.Join(p.accepted, ""))
|
||||||
}
|
}
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "accept eof: %q; %q", p.accepted, p.tokens)
|
||||||
logger.Debugf("accept eof: %q; %q", p.accepted, p.tokens)
|
|
||||||
}
|
|
||||||
return segs, nil
|
return segs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) segments() ([]segment, error) {
|
func (p *parser) segments() ([]segment, error) {
|
||||||
|
logger := log.LoggerOrDefault(p.logger)
|
||||||
s, err := p.segment()
|
s, err := p.segment()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "accept segment: %q; %q", p.accepted, p.tokens)
|
||||||
logger.Debugf("accept segment: %q; %q", p.accepted, p.tokens)
|
|
||||||
}
|
|
||||||
segs := []segment{s}
|
segs := []segment{s}
|
||||||
for {
|
for {
|
||||||
if _, err := p.accept("/"); err != nil {
|
if _, err := p.accept("/"); err != nil {
|
||||||
@ -140,9 +138,7 @@ func (p *parser) segments() ([]segment, error) {
|
|||||||
return segs, err
|
return segs, err
|
||||||
}
|
}
|
||||||
segs = append(segs, s)
|
segs = append(segs, s)
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "accept segment: %q; %q", p.accepted, p.tokens)
|
||||||
logger.Debugf("accept segment: %q; %q", p.accepted, p.tokens)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,6 +266,7 @@ func (p *parser) accept(term termType) (string, error) {
|
|||||||
// expectPChars determines if "t" consists of only pchars defined in RFC3986.
|
// expectPChars determines if "t" consists of only pchars defined in RFC3986.
|
||||||
//
|
//
|
||||||
// https://www.ietf.org/rfc/rfc3986.txt, P.49
|
// https://www.ietf.org/rfc/rfc3986.txt, P.49
|
||||||
|
//
|
||||||
// pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
// pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
||||||
// unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
// unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
||||||
// sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
// sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"go-micro.dev/v4/logger"
|
log "go-micro.dev/v4/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -43,11 +43,19 @@ type Pattern struct {
|
|||||||
|
|
||||||
type patternOptions struct {
|
type patternOptions struct {
|
||||||
assumeColonVerb bool
|
assumeColonVerb bool
|
||||||
|
logger log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
// PatternOpt is an option for creating Patterns.
|
// PatternOpt is an option for creating Patterns.
|
||||||
type PatternOpt func(*patternOptions)
|
type PatternOpt func(*patternOptions)
|
||||||
|
|
||||||
|
// Logger sets the logger
|
||||||
|
func PatternLogger(l log.Logger) PatternOpt {
|
||||||
|
return func(po *patternOptions) {
|
||||||
|
po.logger = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NewPattern returns a new Pattern from the given definition values.
|
// NewPattern returns a new Pattern from the given definition values.
|
||||||
// "ops" is a sequence of op codes. "pool" is a constant pool.
|
// "ops" is a sequence of op codes. "pool" is a constant pool.
|
||||||
// "verb" is the verb part of the pattern. It is empty if the pattern does not have the part.
|
// "verb" is the verb part of the pattern. It is empty if the pattern does not have the part.
|
||||||
@ -61,18 +69,16 @@ func NewPattern(version int, ops []int, pool []string, verb string, opts ...Patt
|
|||||||
o(&options)
|
o(&options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger := log.LoggerOrDefault(options.logger)
|
||||||
|
|
||||||
if version != 1 {
|
if version != 1 {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "unsupported version: %d", version)
|
||||||
logger.Debugf("unsupported version: %d", version)
|
|
||||||
}
|
|
||||||
return Pattern{}, ErrInvalidPattern
|
return Pattern{}, ErrInvalidPattern
|
||||||
}
|
}
|
||||||
|
|
||||||
l := len(ops)
|
l := len(ops)
|
||||||
if l%2 != 0 {
|
if l%2 != 0 {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "odd number of ops codes: %d", l)
|
||||||
logger.Debugf("odd number of ops codes: %d", l)
|
|
||||||
}
|
|
||||||
return Pattern{}, ErrInvalidPattern
|
return Pattern{}, ErrInvalidPattern
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,18 +101,14 @@ func NewPattern(version int, ops []int, pool []string, verb string, opts ...Patt
|
|||||||
stack++
|
stack++
|
||||||
case OpPushM:
|
case OpPushM:
|
||||||
if pushMSeen {
|
if pushMSeen {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "pushM appears twice")
|
||||||
logger.Debug("pushM appears twice")
|
|
||||||
}
|
|
||||||
return Pattern{}, ErrInvalidPattern
|
return Pattern{}, ErrInvalidPattern
|
||||||
}
|
}
|
||||||
pushMSeen = true
|
pushMSeen = true
|
||||||
stack++
|
stack++
|
||||||
case OpLitPush:
|
case OpLitPush:
|
||||||
if op.operand < 0 || len(pool) <= op.operand {
|
if op.operand < 0 || len(pool) <= op.operand {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "negative literal index: %d", op.operand)
|
||||||
logger.Debugf("negative literal index: %d", op.operand)
|
|
||||||
}
|
|
||||||
return Pattern{}, ErrInvalidPattern
|
return Pattern{}, ErrInvalidPattern
|
||||||
}
|
}
|
||||||
if pushMSeen {
|
if pushMSeen {
|
||||||
@ -115,24 +117,18 @@ func NewPattern(version int, ops []int, pool []string, verb string, opts ...Patt
|
|||||||
stack++
|
stack++
|
||||||
case OpConcatN:
|
case OpConcatN:
|
||||||
if op.operand <= 0 {
|
if op.operand <= 0 {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "negative concat size: %d", op.operand)
|
||||||
logger.Debugf("negative concat size: %d", op.operand)
|
|
||||||
}
|
|
||||||
return Pattern{}, ErrInvalidPattern
|
return Pattern{}, ErrInvalidPattern
|
||||||
}
|
}
|
||||||
stack -= op.operand
|
stack -= op.operand
|
||||||
if stack < 0 {
|
if stack < 0 {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "stack underflow")
|
||||||
logger.Debug("stack underflow")
|
|
||||||
}
|
|
||||||
return Pattern{}, ErrInvalidPattern
|
return Pattern{}, ErrInvalidPattern
|
||||||
}
|
}
|
||||||
stack++
|
stack++
|
||||||
case OpCapture:
|
case OpCapture:
|
||||||
if op.operand < 0 || len(pool) <= op.operand {
|
if op.operand < 0 || len(pool) <= op.operand {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "variable name index out of bound: %d", op.operand)
|
||||||
logger.Debugf("variable name index out of bound: %d", op.operand)
|
|
||||||
}
|
|
||||||
return Pattern{}, ErrInvalidPattern
|
return Pattern{}, ErrInvalidPattern
|
||||||
}
|
}
|
||||||
v := pool[op.operand]
|
v := pool[op.operand]
|
||||||
@ -140,15 +136,11 @@ func NewPattern(version int, ops []int, pool []string, verb string, opts ...Patt
|
|||||||
vars = append(vars, v)
|
vars = append(vars, v)
|
||||||
stack--
|
stack--
|
||||||
if stack < 0 {
|
if stack < 0 {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "stack underflow")
|
||||||
logger.Debug("stack underflow")
|
|
||||||
}
|
|
||||||
return Pattern{}, ErrInvalidPattern
|
return Pattern{}, ErrInvalidPattern
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "invalid opcode: %d", op.code)
|
||||||
logger.Debugf("invalid opcode: %d", op.code)
|
|
||||||
}
|
|
||||||
return Pattern{}, ErrInvalidPattern
|
return Pattern{}, ErrInvalidPattern
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,9 +163,7 @@ func NewPattern(version int, ops []int, pool []string, verb string, opts ...Patt
|
|||||||
// MustPattern is a helper function which makes it easier to call NewPattern in variable initialization.
|
// MustPattern is a helper function which makes it easier to call NewPattern in variable initialization.
|
||||||
func MustPattern(p Pattern, err error) Pattern {
|
func MustPattern(p Pattern, err error) Pattern {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
log.Logf(log.FatalLevel, "Pattern initialization failed: %v", err)
|
||||||
logger.Fatalf("Pattern initialization failed: %v", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,16 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"go-micro.dev/v4/api/server/acme"
|
|
||||||
"go-micro.dev/v4/logger"
|
|
||||||
"golang.org/x/crypto/acme/autocert"
|
"golang.org/x/crypto/acme/autocert"
|
||||||
|
|
||||||
|
"go-micro.dev/v4/api/server/acme"
|
||||||
|
log "go-micro.dev/v4/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
// autoCertACME is the ACME provider from golang.org/x/crypto/acme/autocert
|
// autoCertACME is the ACME provider from golang.org/x/crypto/acme/autocert
|
||||||
type autocertProvider struct{}
|
type autocertProvider struct {
|
||||||
|
logger log.Logger
|
||||||
|
}
|
||||||
|
|
||||||
// Listen implements acme.Provider
|
// Listen implements acme.Provider
|
||||||
func (a *autocertProvider) Listen(hosts ...string) (net.Listener, error) {
|
func (a *autocertProvider) Listen(hosts ...string) (net.Listener, error) {
|
||||||
@ -22,6 +25,7 @@ func (a *autocertProvider) Listen(hosts ...string) (net.Listener, error) {
|
|||||||
|
|
||||||
// TLSConfig returns a new tls config
|
// TLSConfig returns a new tls config
|
||||||
func (a *autocertProvider) TLSConfig(hosts ...string) (*tls.Config, error) {
|
func (a *autocertProvider) TLSConfig(hosts ...string) (*tls.Config, error) {
|
||||||
|
logger := log.LoggerOrDefault(a.logger)
|
||||||
// create a new manager
|
// create a new manager
|
||||||
m := &autocert.Manager{
|
m := &autocert.Manager{
|
||||||
Prompt: autocert.AcceptTOS,
|
Prompt: autocert.AcceptTOS,
|
||||||
@ -31,9 +35,7 @@ func (a *autocertProvider) TLSConfig(hosts ...string) (*tls.Config, error) {
|
|||||||
}
|
}
|
||||||
dir := cacheDir()
|
dir := cacheDir()
|
||||||
if err := os.MkdirAll(dir, 0700); err != nil {
|
if err := os.MkdirAll(dir, 0700); err != nil {
|
||||||
if logger.V(logger.InfoLevel, logger.DefaultLogger) {
|
logger.Logf(log.InfoLevel, "warning: autocert not using a cache: %v", err)
|
||||||
logger.Infof("warning: autocert not using a cache: %v", err)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
m.Cache = autocert.DirCache(dir)
|
m.Cache = autocert.DirCache(dir)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
package acme
|
package acme
|
||||||
|
|
||||||
import "github.com/go-acme/lego/v4/challenge"
|
import (
|
||||||
|
"github.com/go-acme/lego/v4/challenge"
|
||||||
|
|
||||||
|
"go-micro.dev/v4/logger"
|
||||||
|
)
|
||||||
|
|
||||||
// Option (or Options) are passed to New() to configure providers
|
// Option (or Options) are passed to New() to configure providers
|
||||||
type Option func(o *Options)
|
type Option func(o *Options)
|
||||||
@ -22,6 +26,9 @@ type Options struct {
|
|||||||
// there's no defined interface, so if you consume this option
|
// there's no defined interface, so if you consume this option
|
||||||
// sanity check it before using.
|
// sanity check it before using.
|
||||||
Cache interface{}
|
Cache interface{}
|
||||||
|
|
||||||
|
// Logger is the underling logging framework
|
||||||
|
Logger logger.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
// AcceptToS indicates whether you accept your CA's terms of service
|
// AcceptToS indicates whether you accept your CA's terms of service
|
||||||
@ -63,6 +70,13 @@ func Cache(c interface{}) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Logger sets the underline logger
|
||||||
|
func Logger(l logger.Logger) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.Logger = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// DefaultOptions uses the Let's Encrypt Production CA, with DNS Challenge disabled.
|
// DefaultOptions uses the Let's Encrypt Production CA, with DNS Challenge disabled.
|
||||||
func DefaultOptions() Options {
|
func DefaultOptions() Options {
|
||||||
return Options{
|
return Options{
|
||||||
|
@ -9,9 +9,10 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/gorilla/handlers"
|
"github.com/gorilla/handlers"
|
||||||
|
|
||||||
"go-micro.dev/v4/api/server"
|
"go-micro.dev/v4/api/server"
|
||||||
"go-micro.dev/v4/api/server/cors"
|
"go-micro.dev/v4/api/server/cors"
|
||||||
"go-micro.dev/v4/logger"
|
log "go-micro.dev/v4/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
type httpServer struct {
|
type httpServer struct {
|
||||||
@ -24,10 +25,7 @@ type httpServer struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewServer(address string, opts ...server.Option) server.Server {
|
func NewServer(address string, opts ...server.Option) server.Server {
|
||||||
var options server.Options
|
options := server.NewOptions(opts...)
|
||||||
for _, o := range opts {
|
|
||||||
o(&options)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &httpServer{
|
return &httpServer{
|
||||||
opts: options,
|
opts: options,
|
||||||
@ -70,6 +68,7 @@ func (s *httpServer) Handle(path string, handler http.Handler) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *httpServer) Start() error {
|
func (s *httpServer) Start() error {
|
||||||
|
logger := s.opts.Logger
|
||||||
var l net.Listener
|
var l net.Listener
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@ -86,9 +85,7 @@ func (s *httpServer) Start() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if logger.V(logger.InfoLevel, logger.DefaultLogger) {
|
logger.Logf(log.InfoLevel, "HTTP API Listening on %s", l.Addr().String())
|
||||||
logger.Infof("HTTP API Listening on %s", l.Addr().String())
|
|
||||||
}
|
|
||||||
|
|
||||||
s.mtx.Lock()
|
s.mtx.Lock()
|
||||||
s.address = l.Addr().String()
|
s.address = l.Addr().String()
|
||||||
@ -97,7 +94,8 @@ func (s *httpServer) Start() error {
|
|||||||
go func() {
|
go func() {
|
||||||
if err := http.Serve(l, s.mux); err != nil {
|
if err := http.Serve(l, s.mux); err != nil {
|
||||||
// temporary fix
|
// temporary fix
|
||||||
//logger.Fatal(err)
|
//logger.Log(log.FatalLevel, err)
|
||||||
|
logger.Log(log.ErrorLevel, err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -2,9 +2,11 @@ package server
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"go-micro.dev/v4/api/server/cors"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"go-micro.dev/v4/api/server/cors"
|
||||||
|
"go-micro.dev/v4/logger"
|
||||||
|
|
||||||
"go-micro.dev/v4/api/resolver"
|
"go-micro.dev/v4/api/resolver"
|
||||||
"go-micro.dev/v4/api/server/acme"
|
"go-micro.dev/v4/api/server/acme"
|
||||||
)
|
)
|
||||||
@ -21,10 +23,23 @@ type Options struct {
|
|||||||
TLSConfig *tls.Config
|
TLSConfig *tls.Config
|
||||||
Resolver resolver.Resolver
|
Resolver resolver.Resolver
|
||||||
Wrappers []Wrapper
|
Wrappers []Wrapper
|
||||||
|
Logger logger.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
type Wrapper func(h http.Handler) http.Handler
|
type Wrapper func(h http.Handler) http.Handler
|
||||||
|
|
||||||
|
func NewOptions(opts ...Option) Options {
|
||||||
|
options := Options{
|
||||||
|
Logger: logger.DefaultLogger,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, o := range opts {
|
||||||
|
o(&options)
|
||||||
|
}
|
||||||
|
|
||||||
|
return options
|
||||||
|
}
|
||||||
|
|
||||||
func WrapHandler(w Wrapper) Option {
|
func WrapHandler(w Wrapper) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Wrappers = append(o.Wrappers, w)
|
o.Wrappers = append(o.Wrappers, w)
|
||||||
@ -78,3 +93,10 @@ func Resolver(r resolver.Resolver) Option {
|
|||||||
o.Resolver = r
|
o.Resolver = r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Logger sets the underline logging framework
|
||||||
|
func Logger(l logger.Logger) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.Logger = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,13 +3,19 @@ package auth
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"go-micro.dev/v4/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewOptions(opts ...Option) Options {
|
func NewOptions(opts ...Option) Options {
|
||||||
var options Options
|
options := Options{
|
||||||
|
Logger: logger.DefaultLogger,
|
||||||
|
}
|
||||||
|
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(&options)
|
o(&options)
|
||||||
}
|
}
|
||||||
|
|
||||||
return options
|
return options
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,6 +34,8 @@ type Options struct {
|
|||||||
PrivateKey string
|
PrivateKey string
|
||||||
// Addrs sets the addresses of auth
|
// Addrs sets the addresses of auth
|
||||||
Addrs []string
|
Addrs []string
|
||||||
|
// Logger is the underline logger
|
||||||
|
Logger logger.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
type Option func(o *Options)
|
type Option func(o *Options)
|
||||||
@ -60,6 +68,13 @@ func PrivateKey(key string) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithLogger sets the underline logger
|
||||||
|
func WithLogger(l logger.Logger) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.Logger = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Credentials sets the auth credentials
|
// Credentials sets the auth credentials
|
||||||
func Credentials(id, secret string) Option {
|
func Credentials(id, secret string) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
|
@ -3,7 +3,6 @@ package broker
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -17,6 +16,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"golang.org/x/net/http2"
|
||||||
|
|
||||||
"go-micro.dev/v4/codec/json"
|
"go-micro.dev/v4/codec/json"
|
||||||
merr "go-micro.dev/v4/errors"
|
merr "go-micro.dev/v4/errors"
|
||||||
"go-micro.dev/v4/registry"
|
"go-micro.dev/v4/registry"
|
||||||
@ -24,7 +25,6 @@ import (
|
|||||||
maddr "go-micro.dev/v4/util/addr"
|
maddr "go-micro.dev/v4/util/addr"
|
||||||
mnet "go-micro.dev/v4/util/net"
|
mnet "go-micro.dev/v4/util/net"
|
||||||
mls "go-micro.dev/v4/util/tls"
|
mls "go-micro.dev/v4/util/tls"
|
||||||
"golang.org/x/net/http2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// HTTP Broker is a point to point async broker
|
// HTTP Broker is a point to point async broker
|
||||||
@ -107,11 +107,10 @@ func newTransport(config *tls.Config) *http.Transport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newHttpBroker(opts ...Option) Broker {
|
func newHttpBroker(opts ...Option) Broker {
|
||||||
options := Options{
|
options := *NewOptions(opts...)
|
||||||
Codec: json.Marshaler{},
|
|
||||||
Context: context.TODO(),
|
options.Registry = registry.DefaultRegistry
|
||||||
Registry: registry.DefaultRegistry,
|
options.Codec = json.Marshaler{}
|
||||||
}
|
|
||||||
|
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(&options)
|
o(&options)
|
||||||
|
@ -2,20 +2,20 @@
|
|||||||
package broker
|
package broker
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"errors"
|
"errors"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"go-micro.dev/v4/logger"
|
|
||||||
|
log "go-micro.dev/v4/logger"
|
||||||
maddr "go-micro.dev/v4/util/addr"
|
maddr "go-micro.dev/v4/util/addr"
|
||||||
mnet "go-micro.dev/v4/util/net"
|
mnet "go-micro.dev/v4/util/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
type memoryBroker struct {
|
type memoryBroker struct {
|
||||||
opts Options
|
opts *Options
|
||||||
|
|
||||||
addr string
|
addr string
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
@ -24,7 +24,7 @@ type memoryBroker struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type memoryEvent struct {
|
type memoryEvent struct {
|
||||||
opts Options
|
opts *Options
|
||||||
topic string
|
topic string
|
||||||
err error
|
err error
|
||||||
message interface{}
|
message interface{}
|
||||||
@ -39,7 +39,7 @@ type memorySubscriber struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *memoryBroker) Options() Options {
|
func (m *memoryBroker) Options() Options {
|
||||||
return m.opts
|
return *m.opts
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *memoryBroker) Address() string {
|
func (m *memoryBroker) Address() string {
|
||||||
@ -84,7 +84,7 @@ func (m *memoryBroker) Disconnect() error {
|
|||||||
|
|
||||||
func (m *memoryBroker) Init(opts ...Option) error {
|
func (m *memoryBroker) Init(opts ...Option) error {
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(&m.opts)
|
o(m.opts)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -190,9 +190,7 @@ func (m *memoryEvent) Message() *Message {
|
|||||||
case []byte:
|
case []byte:
|
||||||
msg := &Message{}
|
msg := &Message{}
|
||||||
if err := m.opts.Codec.Unmarshal(v, msg); err != nil {
|
if err := m.opts.Codec.Unmarshal(v, msg); err != nil {
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
m.opts.Logger.Logf(log.ErrorLevel, "[memory]: failed to unmarshal: %v\n", err)
|
||||||
logger.Errorf("[memory]: failed to unmarshal: %v\n", err)
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return msg
|
return msg
|
||||||
@ -223,14 +221,9 @@ func (m *memorySubscriber) Unsubscribe() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewMemoryBroker(opts ...Option) Broker {
|
func NewMemoryBroker(opts ...Option) Broker {
|
||||||
options := Options{
|
options := NewOptions(opts...)
|
||||||
Context: context.Background(),
|
|
||||||
}
|
|
||||||
|
|
||||||
rand.Seed(time.Now().UnixNano())
|
rand.Seed(time.Now().UnixNano())
|
||||||
for _, o := range opts {
|
|
||||||
o(&options)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &memoryBroker{
|
return &memoryBroker{
|
||||||
opts: options,
|
opts: options,
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
|
||||||
"go-micro.dev/v4/codec"
|
"go-micro.dev/v4/codec"
|
||||||
|
"go-micro.dev/v4/logger"
|
||||||
"go-micro.dev/v4/registry"
|
"go-micro.dev/v4/registry"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -13,6 +14,9 @@ type Options struct {
|
|||||||
Secure bool
|
Secure bool
|
||||||
Codec codec.Marshaler
|
Codec codec.Marshaler
|
||||||
|
|
||||||
|
// Logger is the underlying logger
|
||||||
|
Logger logger.Logger
|
||||||
|
|
||||||
// Handler executed when error happens in broker mesage
|
// Handler executed when error happens in broker mesage
|
||||||
// processing
|
// processing
|
||||||
ErrorHandler Handler
|
ErrorHandler Handler
|
||||||
@ -58,6 +62,19 @@ func PublishContext(ctx context.Context) PublishOption {
|
|||||||
|
|
||||||
type SubscribeOption func(*SubscribeOptions)
|
type SubscribeOption func(*SubscribeOptions)
|
||||||
|
|
||||||
|
func NewOptions(opts ...Option) *Options {
|
||||||
|
options := Options{
|
||||||
|
Context: context.Background(),
|
||||||
|
Logger: logger.DefaultLogger,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, o := range opts {
|
||||||
|
o(&options)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &options
|
||||||
|
}
|
||||||
|
|
||||||
func NewSubscribeOptions(opts ...SubscribeOption) SubscribeOptions {
|
func NewSubscribeOptions(opts ...SubscribeOption) SubscribeOptions {
|
||||||
opt := SubscribeOptions{
|
opt := SubscribeOptions{
|
||||||
AutoAck: true,
|
AutoAck: true,
|
||||||
@ -128,6 +145,13 @@ func TLSConfig(t *tls.Config) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Logger sets the underline logger
|
||||||
|
func Logger(l logger.Logger) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.Logger = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// SubscribeContext set context
|
// SubscribeContext set context
|
||||||
func SubscribeContext(ctx context.Context) SubscribeOption {
|
func SubscribeContext(ctx context.Context) SubscribeOption {
|
||||||
return func(o *SubscribeOptions) {
|
return func(o *SubscribeOptions) {
|
||||||
|
1
cache/cache.go
vendored
1
cache/cache.go
vendored
@ -22,7 +22,6 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Cache is the interface that wraps the cache.
|
// Cache is the interface that wraps the cache.
|
||||||
//
|
|
||||||
type Cache interface {
|
type Cache interface {
|
||||||
// Get gets a cached value by key.
|
// Get gets a cached value by key.
|
||||||
Get(ctx context.Context, key string) (interface{}, time.Time, error)
|
Get(ctx context.Context, key string) (interface{}, time.Time, error)
|
||||||
|
12
cache/options.go
vendored
12
cache/options.go
vendored
@ -3,6 +3,8 @@ package cache
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"go-micro.dev/v4/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Options represents the options for the cache.
|
// Options represents the options for the cache.
|
||||||
@ -13,6 +15,8 @@ type Options struct {
|
|||||||
Address string
|
Address string
|
||||||
// Context should contain all implementation specific options, using context.WithValue.
|
// Context should contain all implementation specific options, using context.WithValue.
|
||||||
Context context.Context
|
Context context.Context
|
||||||
|
// Logger is the be used logger
|
||||||
|
Logger logger.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
// Option manipulates the Options passed.
|
// Option manipulates the Options passed.
|
||||||
@ -46,11 +50,19 @@ func WithContext(c context.Context) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithLogger sets underline logger
|
||||||
|
func WithLogger(l logger.Logger) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.Logger = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NewOptions returns a new options struct.
|
// NewOptions returns a new options struct.
|
||||||
func NewOptions(opts ...Option) Options {
|
func NewOptions(opts ...Option) Options {
|
||||||
options := Options{
|
options := Options{
|
||||||
Expiration: DefaultExpiration,
|
Expiration: DefaultExpiration,
|
||||||
Items: make(map[string]Item),
|
Items: make(map[string]Item),
|
||||||
|
Logger: logger.DefaultLogger,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
|
|
||||||
"go-micro.dev/v4/broker"
|
"go-micro.dev/v4/broker"
|
||||||
"go-micro.dev/v4/codec"
|
"go-micro.dev/v4/codec"
|
||||||
|
"go-micro.dev/v4/logger"
|
||||||
"go-micro.dev/v4/registry"
|
"go-micro.dev/v4/registry"
|
||||||
"go-micro.dev/v4/selector"
|
"go-micro.dev/v4/selector"
|
||||||
"go-micro.dev/v4/transport"
|
"go-micro.dev/v4/transport"
|
||||||
@ -38,6 +39,9 @@ type Options struct {
|
|||||||
// Default Call Options
|
// Default Call Options
|
||||||
CallOptions CallOptions
|
CallOptions CallOptions
|
||||||
|
|
||||||
|
// Logger is the underline logger
|
||||||
|
Logger logger.Logger
|
||||||
|
|
||||||
// Other options for implementations of the interface
|
// Other options for implementations of the interface
|
||||||
// can be stored in a context
|
// can be stored in a context
|
||||||
Context context.Context
|
Context context.Context
|
||||||
@ -113,6 +117,7 @@ func NewOptions(options ...Option) Options {
|
|||||||
Selector: selector.DefaultSelector,
|
Selector: selector.DefaultSelector,
|
||||||
Registry: registry.DefaultRegistry,
|
Registry: registry.DefaultRegistry,
|
||||||
Transport: transport.DefaultTransport,
|
Transport: transport.DefaultTransport,
|
||||||
|
Logger: logger.DefaultLogger,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, o := range options {
|
for _, o := range options {
|
||||||
@ -364,3 +369,10 @@ func WithRouter(r Router) Option {
|
|||||||
o.Router = r
|
o.Router = r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithLogger sets the underline logger
|
||||||
|
func WithLogger(l logger.Logger) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.Logger = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -89,6 +89,7 @@ func (c *cliSource) String() string {
|
|||||||
// command line flags have already been parsed.
|
// command line flags have already been parsed.
|
||||||
//
|
//
|
||||||
// Example:
|
// Example:
|
||||||
|
//
|
||||||
// cli.StringFlag{Name: "db-host"},
|
// cli.StringFlag{Name: "db-host"},
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
1
config/source/env/env.go
vendored
1
config/source/env/env.go
vendored
@ -117,6 +117,7 @@ func (e *env) String() string {
|
|||||||
// Underscores are delimiters for nesting, and all keys are lowercased.
|
// Underscores are delimiters for nesting, and all keys are lowercased.
|
||||||
//
|
//
|
||||||
// Example:
|
// Example:
|
||||||
|
//
|
||||||
// "DATABASE_SERVER_HOST=localhost" will convert to
|
// "DATABASE_SERVER_HOST=localhost" will convert to
|
||||||
//
|
//
|
||||||
// {
|
// {
|
||||||
|
@ -89,6 +89,7 @@ func (fs *flagsrc) String() string {
|
|||||||
// Hyphens are delimiters for nesting, and all keys are lowercased.
|
// Hyphens are delimiters for nesting, and all keys are lowercased.
|
||||||
//
|
//
|
||||||
// Example:
|
// Example:
|
||||||
|
//
|
||||||
// dbhost := flag.String("database-host", "localhost", "the db host name")
|
// dbhost := flag.String("database-host", "localhost", "the db host name")
|
||||||
//
|
//
|
||||||
// {
|
// {
|
||||||
|
@ -8,18 +8,17 @@ import (
|
|||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"go-micro.dev/v4/logger"
|
|
||||||
|
log "go-micro.dev/v4/logger"
|
||||||
"go-micro.dev/v4/store"
|
"go-micro.dev/v4/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewStream returns an initialized memory stream
|
// NewStream returns an initialized memory stream
|
||||||
func NewStream(opts ...Option) (Stream, error) {
|
func NewStream(opts ...Option) (Stream, error) {
|
||||||
// parse the options
|
// parse the options
|
||||||
var options Options
|
options := NewOptions(opts...)
|
||||||
for _, o := range opts {
|
|
||||||
o(&options)
|
return &mem{store: store.NewMemoryStore(), options: options}, nil
|
||||||
}
|
|
||||||
return &mem{store: store.NewMemoryStore()}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type subscriber struct {
|
type subscriber struct {
|
||||||
@ -35,6 +34,7 @@ type subscriber struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type mem struct {
|
type mem struct {
|
||||||
|
options *Options
|
||||||
store store.Store
|
store store.Store
|
||||||
|
|
||||||
subs []*subscriber
|
subs []*subscriber
|
||||||
@ -147,10 +147,8 @@ func (m *mem) Consume(topic string, opts ...ConsumeOption) (<-chan Event, error)
|
|||||||
func (m *mem) lookupPreviousEvents(sub *subscriber, startTime time.Time) {
|
func (m *mem) lookupPreviousEvents(sub *subscriber, startTime time.Time) {
|
||||||
// lookup all events which match the topic (a blank topic will return all results)
|
// lookup all events which match the topic (a blank topic will return all results)
|
||||||
recs, err := m.store.Read(sub.Topic+"/", store.ReadPrefix())
|
recs, err := m.store.Read(sub.Topic+"/", store.ReadPrefix())
|
||||||
if err != nil && logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
if err != nil {
|
||||||
logger.Errorf("Error looking up previous events: %v", err)
|
m.options.Logger.Logf(log.ErrorLevel, "Error looking up previous events: %v", err)
|
||||||
return
|
|
||||||
} else if err != nil {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,7 +170,7 @@ func (m *mem) handleEvent(ev *Event) {
|
|||||||
m.RLock()
|
m.RLock()
|
||||||
subs := m.subs
|
subs := m.subs
|
||||||
m.RUnlock()
|
m.RUnlock()
|
||||||
|
logger := m.options.Logger
|
||||||
// filteredSubs is a KV map of the queue name and subscribers. This is used to prevent a message
|
// filteredSubs is a KV map of the queue name and subscribers. This is used to prevent a message
|
||||||
// being sent to two subscribers with the same queue.
|
// being sent to two subscribers with the same queue.
|
||||||
filteredSubs := map[string]*subscriber{}
|
filteredSubs := map[string]*subscriber{}
|
||||||
@ -186,16 +184,19 @@ func (m *mem) handleEvent(ev *Event) {
|
|||||||
|
|
||||||
// send the message to each channel async (since one channel might be blocked)
|
// send the message to each channel async (since one channel might be blocked)
|
||||||
for _, sub := range filteredSubs {
|
for _, sub := range filteredSubs {
|
||||||
sendEvent(ev, sub)
|
go func(s *subscriber) {
|
||||||
|
if err := sendEvent(ev, s); err != nil {
|
||||||
|
logger.Log(log.ErrorLevel, err)
|
||||||
|
}
|
||||||
|
}(sub)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendEvent(ev *Event, sub *subscriber) {
|
func sendEvent(ev *Event, s *subscriber) error {
|
||||||
go func(s *subscriber) {
|
|
||||||
evCopy := *ev
|
evCopy := *ev
|
||||||
if s.autoAck {
|
if s.autoAck {
|
||||||
s.Channel <- evCopy
|
s.Channel <- evCopy
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
evCopy.SetAckFunc(ackFunc(s, evCopy))
|
evCopy.SetAckFunc(ackFunc(s, evCopy))
|
||||||
evCopy.SetNackFunc(nackFunc(s, evCopy))
|
evCopy.SetNackFunc(nackFunc(s, evCopy))
|
||||||
@ -212,20 +213,17 @@ func sendEvent(ev *Event, sub *subscriber) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if s.retryLimit > -1 && count > s.retryLimit {
|
if s.retryLimit > -1 && count > s.retryLimit {
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
|
||||||
logger.Errorf("Message retry limit reached, discarding: %v %d %d", evCopy.ID, count, s.retryLimit)
|
|
||||||
}
|
|
||||||
s.Lock()
|
s.Lock()
|
||||||
delete(s.retryMap, evCopy.ID)
|
delete(s.retryMap, evCopy.ID)
|
||||||
s.Unlock()
|
s.Unlock()
|
||||||
return
|
return fmt.Errorf("Message retry limit reached, discarding: %v %d %d", evCopy.ID, count, s.retryLimit)
|
||||||
}
|
}
|
||||||
s.Channel <- evCopy
|
s.Channel <- evCopy
|
||||||
s.Lock()
|
s.Lock()
|
||||||
s.retryMap[evCopy.ID] = count + 1
|
s.retryMap[evCopy.ID] = count + 1
|
||||||
s.Unlock()
|
s.Unlock()
|
||||||
}
|
}
|
||||||
}(sub)
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ackFunc(s *subscriber, evCopy Event) func() error {
|
func ackFunc(s *subscriber, evCopy Event) func() error {
|
||||||
|
@ -1,18 +1,44 @@
|
|||||||
package events
|
package events
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
type Options struct{}
|
"go-micro.dev/v4/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Options struct {
|
||||||
|
Logger logger.Logger
|
||||||
|
}
|
||||||
|
|
||||||
type Option func(o *Options)
|
type Option func(o *Options)
|
||||||
|
|
||||||
|
func NewOptions(opts ...Option) *Options {
|
||||||
|
options := Options{
|
||||||
|
Logger: logger.DefaultLogger,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, o := range opts {
|
||||||
|
o(&options)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &options
|
||||||
|
}
|
||||||
|
|
||||||
type StoreOptions struct {
|
type StoreOptions struct {
|
||||||
TTL time.Duration
|
TTL time.Duration
|
||||||
Backup Backup
|
Backup Backup
|
||||||
|
Logger logger.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
type StoreOption func(o *StoreOptions)
|
type StoreOption func(o *StoreOptions)
|
||||||
|
|
||||||
|
// WithLogger sets the underline logger
|
||||||
|
func WithLogger(l logger.Logger) StoreOption {
|
||||||
|
return func(o *StoreOptions) {
|
||||||
|
o.Logger = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// PublishOptions contains all the options which can be provided when publishing an event
|
// PublishOptions contains all the options which can be provided when publishing an event
|
||||||
type PublishOptions struct {
|
type PublishOptions struct {
|
||||||
// Metadata contains any keys which can be used to query the data, for example a customer id
|
// Metadata contains any keys which can be used to query the data, for example a customer id
|
||||||
|
@ -5,7 +5,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"go-micro.dev/v4/logger"
|
|
||||||
|
log "go-micro.dev/v4/logger"
|
||||||
"go-micro.dev/v4/store"
|
"go-micro.dev/v4/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -22,6 +23,8 @@ func NewStore(opts ...StoreOption) Store {
|
|||||||
options.TTL = time.Hour * 24
|
options.TTL = time.Hour * 24
|
||||||
}
|
}
|
||||||
|
|
||||||
|
options.Logger = log.LoggerOrDefault(options.Logger)
|
||||||
|
|
||||||
// return the store
|
// return the store
|
||||||
evs := &evStore{
|
evs := &evStore{
|
||||||
opts: options,
|
opts: options,
|
||||||
@ -114,7 +117,7 @@ func (s *evStore) backupLoop() {
|
|||||||
for {
|
for {
|
||||||
err := s.opts.Backup.Snapshot(s.store)
|
err := s.opts.Backup.Snapshot(s.store)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("Error running backup %s", err)
|
s.opts.Logger.Logf(log.ErrorLevel, "Error running backup %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(1 * time.Hour)
|
time.Sleep(1 * time.Hour)
|
||||||
|
@ -135,7 +135,7 @@ func (l *defaultLogger) Log(level Level, v ...interface{}) {
|
|||||||
|
|
||||||
func (l *defaultLogger) Logf(level Level, format string, v ...interface{}) {
|
func (l *defaultLogger) Logf(level Level, format string, v ...interface{}) {
|
||||||
// TODO decide does we need to write message if log level not used?
|
// TODO decide does we need to write message if log level not used?
|
||||||
if level < l.opts.Level {
|
if !l.opts.Level.Enabled(level) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,3 +129,10 @@ func (h *Helper) WithError(err error) *Helper {
|
|||||||
func (h *Helper) WithFields(fields map[string]interface{}) *Helper {
|
func (h *Helper) WithFields(fields map[string]interface{}) *Helper {
|
||||||
return &Helper{logger: h.logger.Fields(fields)}
|
return &Helper{logger: h.logger.Fields(fields)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func HelperOrDefault(h *Helper) *Helper {
|
||||||
|
if h == nil {
|
||||||
|
return DefaultHelper
|
||||||
|
}
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
@ -4,6 +4,9 @@ package logger
|
|||||||
var (
|
var (
|
||||||
// Default logger
|
// Default logger
|
||||||
DefaultLogger Logger = NewLogger()
|
DefaultLogger Logger = NewLogger()
|
||||||
|
|
||||||
|
// Default logger helper
|
||||||
|
DefaultHelper *Helper = NewHelper(DefaultLogger)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Logger is a generic logging interface
|
// Logger is a generic logging interface
|
||||||
@ -41,3 +44,10 @@ func Logf(level Level, format string, v ...interface{}) {
|
|||||||
func String() string {
|
func String() string {
|
||||||
return DefaultLogger.String()
|
return DefaultLogger.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func LoggerOrDefault(l Logger) Logger {
|
||||||
|
if l == nil {
|
||||||
|
return DefaultLogger
|
||||||
|
}
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
11
options.go
11
options.go
@ -12,6 +12,7 @@ import (
|
|||||||
"go-micro.dev/v4/config"
|
"go-micro.dev/v4/config"
|
||||||
"go-micro.dev/v4/debug/profile"
|
"go-micro.dev/v4/debug/profile"
|
||||||
"go-micro.dev/v4/debug/trace"
|
"go-micro.dev/v4/debug/trace"
|
||||||
|
"go-micro.dev/v4/logger"
|
||||||
"go-micro.dev/v4/registry"
|
"go-micro.dev/v4/registry"
|
||||||
"go-micro.dev/v4/runtime"
|
"go-micro.dev/v4/runtime"
|
||||||
"go-micro.dev/v4/selector"
|
"go-micro.dev/v4/selector"
|
||||||
@ -35,7 +36,7 @@ type Options struct {
|
|||||||
Runtime runtime.Runtime
|
Runtime runtime.Runtime
|
||||||
Transport transport.Transport
|
Transport transport.Transport
|
||||||
Profile profile.Profile
|
Profile profile.Profile
|
||||||
|
Logger logger.Logger
|
||||||
// Before and After funcs
|
// Before and After funcs
|
||||||
BeforeStart []func() error
|
BeforeStart []func() error
|
||||||
BeforeStop []func() error
|
BeforeStop []func() error
|
||||||
@ -64,6 +65,7 @@ func newOptions(opts ...Option) Options {
|
|||||||
Transport: transport.DefaultTransport,
|
Transport: transport.DefaultTransport,
|
||||||
Context: context.Background(),
|
Context: context.Background(),
|
||||||
Signal: true,
|
Signal: true,
|
||||||
|
Logger: logger.DefaultLogger,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
@ -340,3 +342,10 @@ func AfterStop(fn func() error) Option {
|
|||||||
o.AfterStop = append(o.AfterStop, fn)
|
o.AfterStop = append(o.AfterStop, fn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Logger sets the logger for the service
|
||||||
|
func Logger(l logger.Logger) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.Logger = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
18
registry/cache/cache.go
vendored
18
registry/cache/cache.go
vendored
@ -7,10 +7,11 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"go-micro.dev/v4/logger"
|
"golang.org/x/sync/singleflight"
|
||||||
|
|
||||||
|
log "go-micro.dev/v4/logger"
|
||||||
"go-micro.dev/v4/registry"
|
"go-micro.dev/v4/registry"
|
||||||
util "go-micro.dev/v4/util/registry"
|
util "go-micro.dev/v4/util/registry"
|
||||||
"golang.org/x/sync/singleflight"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Cache is the registry cache interface
|
// Cache is the registry cache interface
|
||||||
@ -24,6 +25,8 @@ type Cache interface {
|
|||||||
type Options struct {
|
type Options struct {
|
||||||
// TTL is the cache TTL
|
// TTL is the cache TTL
|
||||||
TTL time.Duration
|
TTL time.Duration
|
||||||
|
|
||||||
|
Logger log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
type Option func(o *Options)
|
type Option func(o *Options)
|
||||||
@ -320,7 +323,7 @@ func (c *cache) run(service string) {
|
|||||||
c.Lock()
|
c.Lock()
|
||||||
c.watchedRunning[service] = true
|
c.watchedRunning[service] = true
|
||||||
c.Unlock()
|
c.Unlock()
|
||||||
|
logger := c.opts.Logger
|
||||||
// reset watcher on exit
|
// reset watcher on exit
|
||||||
defer func() {
|
defer func() {
|
||||||
c.Lock()
|
c.Lock()
|
||||||
@ -352,9 +355,7 @@ func (c *cache) run(service string) {
|
|||||||
c.setStatus(err)
|
c.setStatus(err)
|
||||||
|
|
||||||
if a > 3 {
|
if a > 3 {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "rcache: ", err, " backing off ", d)
|
||||||
logger.Debug("rcache: ", err, " backing off ", d)
|
|
||||||
}
|
|
||||||
a = 0
|
a = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,9 +378,7 @@ func (c *cache) run(service string) {
|
|||||||
c.setStatus(err)
|
c.setStatus(err)
|
||||||
|
|
||||||
if b > 3 {
|
if b > 3 {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "rcache: ", err, " backing off ", d)
|
||||||
logger.Debug("rcache: ", err, " backing off ", d)
|
|
||||||
}
|
|
||||||
b = 0
|
b = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -468,6 +467,7 @@ func New(r registry.Registry, opts ...Option) Cache {
|
|||||||
rand.Seed(time.Now().UnixNano())
|
rand.Seed(time.Now().UnixNano())
|
||||||
options := Options{
|
options := Options{
|
||||||
TTL: DefaultTTL,
|
TTL: DefaultTTL,
|
||||||
|
Logger: log.DefaultLogger,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
|
9
registry/cache/options.go
vendored
9
registry/cache/options.go
vendored
@ -2,6 +2,8 @@ package cache
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"go-micro.dev/v4/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
// WithTTL sets the cache TTL
|
// WithTTL sets the cache TTL
|
||||||
@ -10,3 +12,10 @@ func WithTTL(t time.Duration) Option {
|
|||||||
o.TTL = t
|
o.TTL = t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithLogger sets the underline logger
|
||||||
|
func WithLogger(l logger.Logger) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.Logger = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -16,7 +16,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"go-micro.dev/v4/logger"
|
|
||||||
|
log "go-micro.dev/v4/logger"
|
||||||
"go-micro.dev/v4/util/mdns"
|
"go-micro.dev/v4/util/mdns"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -38,7 +39,7 @@ type mdnsEntry struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type mdnsRegistry struct {
|
type mdnsRegistry struct {
|
||||||
opts Options
|
opts *Options
|
||||||
// the mdns domain
|
// the mdns domain
|
||||||
domain string
|
domain string
|
||||||
|
|
||||||
@ -128,14 +129,8 @@ func decode(record []string) (*mdnsTxt, error) {
|
|||||||
return txt, nil
|
return txt, nil
|
||||||
}
|
}
|
||||||
func newRegistry(opts ...Option) Registry {
|
func newRegistry(opts ...Option) Registry {
|
||||||
options := Options{
|
mergedOpts := append([]Option{Timeout(time.Millisecond * 100)}, opts...)
|
||||||
Context: context.Background(),
|
options := NewOptions(mergedOpts...)
|
||||||
Timeout: time.Millisecond * 100,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, o := range opts {
|
|
||||||
o(&options)
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the domain
|
// set the domain
|
||||||
domain := mdnsDomain
|
domain := mdnsDomain
|
||||||
@ -155,19 +150,20 @@ func newRegistry(opts ...Option) Registry {
|
|||||||
|
|
||||||
func (m *mdnsRegistry) Init(opts ...Option) error {
|
func (m *mdnsRegistry) Init(opts ...Option) error {
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(&m.opts)
|
o(m.opts)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mdnsRegistry) Options() Options {
|
func (m *mdnsRegistry) Options() Options {
|
||||||
return m.opts
|
return *m.opts
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mdnsRegistry) Register(service *Service, opts ...RegisterOption) error {
|
func (m *mdnsRegistry) Register(service *Service, opts ...RegisterOption) error {
|
||||||
m.Lock()
|
m.Lock()
|
||||||
defer m.Unlock()
|
defer m.Unlock()
|
||||||
|
|
||||||
|
logger := m.opts.Logger
|
||||||
entries, ok := m.services[service.Name]
|
entries, ok := m.services[service.Name]
|
||||||
// first entry, create wildcard used for list queries
|
// first entry, create wildcard used for list queries
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -234,9 +230,8 @@ func (m *mdnsRegistry) Register(service *Service, opts ...RegisterOption) error
|
|||||||
}
|
}
|
||||||
port, _ := strconv.Atoi(pt)
|
port, _ := strconv.Atoi(pt)
|
||||||
|
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "[mdns] registry create new service with ip: %s for: %s", net.ParseIP(host).String(), host)
|
||||||
logger.Debugf("[mdns] registry create new service with ip: %s for: %s", net.ParseIP(host).String(), host)
|
|
||||||
}
|
|
||||||
// we got here, new node
|
// we got here, new node
|
||||||
s, err := mdns.NewMDNSService(
|
s, err := mdns.NewMDNSService(
|
||||||
node.Id,
|
node.Id,
|
||||||
@ -305,6 +300,7 @@ func (m *mdnsRegistry) Deregister(service *Service, opts ...DeregisterOption) er
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *mdnsRegistry) GetService(service string, opts ...GetOption) ([]*Service, error) {
|
func (m *mdnsRegistry) GetService(service string, opts ...GetOption) ([]*Service, error) {
|
||||||
|
logger := m.opts.Logger
|
||||||
serviceMap := make(map[string]*Service)
|
serviceMap := make(map[string]*Service)
|
||||||
entries := make(chan *mdns.ServiceEntry, 10)
|
entries := make(chan *mdns.ServiceEntry, 10)
|
||||||
done := make(chan bool)
|
done := make(chan bool)
|
||||||
@ -359,9 +355,7 @@ func (m *mdnsRegistry) GetService(service string, opts ...GetOption) ([]*Service
|
|||||||
} else if len(e.AddrV6) > 0 {
|
} else if len(e.AddrV6) > 0 {
|
||||||
addr = net.JoinHostPort(e.AddrV6.String(), fmt.Sprint(e.Port))
|
addr = net.JoinHostPort(e.AddrV6.String(), fmt.Sprint(e.Port))
|
||||||
} else {
|
} else {
|
||||||
if logger.V(logger.InfoLevel, logger.DefaultLogger) {
|
logger.Logf(log.InfoLevel, "[mdns]: invalid endpoint received: %v", e)
|
||||||
logger.Infof("[mdns]: invalid endpoint received: %v", e)
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
s.Nodes = append(s.Nodes, &Node{
|
s.Nodes = append(s.Nodes, &Node{
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
package registry
|
package registry
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"go-micro.dev/v4/logger"
|
|
||||||
|
log "go-micro.dev/v4/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -29,7 +29,7 @@ type record struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type memRegistry struct {
|
type memRegistry struct {
|
||||||
options Options
|
options *Options
|
||||||
|
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
records map[string]map[string]*record
|
records map[string]map[string]*record
|
||||||
@ -37,13 +37,7 @@ type memRegistry struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewMemoryRegistry(opts ...Option) Registry {
|
func NewMemoryRegistry(opts ...Option) Registry {
|
||||||
options := Options{
|
options := NewOptions(opts...)
|
||||||
Context: context.Background(),
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, o := range opts {
|
|
||||||
o(&options)
|
|
||||||
}
|
|
||||||
|
|
||||||
records := getServiceRecords(options.Context)
|
records := getServiceRecords(options.Context)
|
||||||
if records == nil {
|
if records == nil {
|
||||||
@ -62,6 +56,7 @@ func NewMemoryRegistry(opts ...Option) Registry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *memRegistry) ttlPrune() {
|
func (m *memRegistry) ttlPrune() {
|
||||||
|
logger := m.options.Logger
|
||||||
prune := time.NewTicker(ttlPruneTime)
|
prune := time.NewTicker(ttlPruneTime)
|
||||||
defer prune.Stop()
|
defer prune.Stop()
|
||||||
|
|
||||||
@ -73,9 +68,7 @@ func (m *memRegistry) ttlPrune() {
|
|||||||
for version, record := range records {
|
for version, record := range records {
|
||||||
for id, n := range record.Nodes {
|
for id, n := range record.Nodes {
|
||||||
if n.TTL != 0 && time.Since(n.LastSeen) > n.TTL {
|
if n.TTL != 0 && time.Since(n.LastSeen) > n.TTL {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "Registry TTL expired for node %s of service %s", n.Id, name)
|
||||||
logger.Debugf("Registry TTL expired for node %s of service %s", n.Id, name)
|
|
||||||
}
|
|
||||||
delete(m.records[name][version].Nodes, id)
|
delete(m.records[name][version].Nodes, id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,7 +104,7 @@ func (m *memRegistry) sendEvent(r *Result) {
|
|||||||
|
|
||||||
func (m *memRegistry) Init(opts ...Option) error {
|
func (m *memRegistry) Init(opts ...Option) error {
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(&m.options)
|
o(m.options)
|
||||||
}
|
}
|
||||||
|
|
||||||
// add services
|
// add services
|
||||||
@ -138,13 +131,13 @@ func (m *memRegistry) Init(opts ...Option) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *memRegistry) Options() Options {
|
func (m *memRegistry) Options() Options {
|
||||||
return m.options
|
return *m.options
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *memRegistry) Register(s *Service, opts ...RegisterOption) error {
|
func (m *memRegistry) Register(s *Service, opts ...RegisterOption) error {
|
||||||
m.Lock()
|
m.Lock()
|
||||||
defer m.Unlock()
|
defer m.Unlock()
|
||||||
|
logger := m.options.Logger
|
||||||
var options RegisterOptions
|
var options RegisterOptions
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(&options)
|
o(&options)
|
||||||
@ -158,9 +151,7 @@ func (m *memRegistry) Register(s *Service, opts ...RegisterOption) error {
|
|||||||
|
|
||||||
if _, ok := m.records[s.Name][s.Version]; !ok {
|
if _, ok := m.records[s.Name][s.Version]; !ok {
|
||||||
m.records[s.Name][s.Version] = r
|
m.records[s.Name][s.Version] = r
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "Registry added new service: %s, version: %s", s.Name, s.Version)
|
||||||
logger.Debugf("Registry added new service: %s, version: %s", s.Name, s.Version)
|
|
||||||
}
|
|
||||||
go m.sendEvent(&Result{Action: "update", Service: s})
|
go m.sendEvent(&Result{Action: "update", Service: s})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -186,18 +177,14 @@ func (m *memRegistry) Register(s *Service, opts ...RegisterOption) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if addedNodes {
|
if addedNodes {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "Registry added new node to service: %s, version: %s", s.Name, s.Version)
|
||||||
logger.Debugf("Registry added new node to service: %s, version: %s", s.Name, s.Version)
|
|
||||||
}
|
|
||||||
go m.sendEvent(&Result{Action: "update", Service: s})
|
go m.sendEvent(&Result{Action: "update", Service: s})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// refresh TTL and timestamp
|
// refresh TTL and timestamp
|
||||||
for _, n := range s.Nodes {
|
for _, n := range s.Nodes {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "Updated registration for service: %s, version: %s", s.Name, s.Version)
|
||||||
logger.Debugf("Updated registration for service: %s, version: %s", s.Name, s.Version)
|
|
||||||
}
|
|
||||||
m.records[s.Name][s.Version].Nodes[n.Id].TTL = options.TTL
|
m.records[s.Name][s.Version].Nodes[n.Id].TTL = options.TTL
|
||||||
m.records[s.Name][s.Version].Nodes[n.Id].LastSeen = time.Now()
|
m.records[s.Name][s.Version].Nodes[n.Id].LastSeen = time.Now()
|
||||||
}
|
}
|
||||||
@ -208,29 +195,23 @@ func (m *memRegistry) Register(s *Service, opts ...RegisterOption) error {
|
|||||||
func (m *memRegistry) Deregister(s *Service, opts ...DeregisterOption) error {
|
func (m *memRegistry) Deregister(s *Service, opts ...DeregisterOption) error {
|
||||||
m.Lock()
|
m.Lock()
|
||||||
defer m.Unlock()
|
defer m.Unlock()
|
||||||
|
logger := m.options.Logger
|
||||||
if _, ok := m.records[s.Name]; ok {
|
if _, ok := m.records[s.Name]; ok {
|
||||||
if _, ok := m.records[s.Name][s.Version]; ok {
|
if _, ok := m.records[s.Name][s.Version]; ok {
|
||||||
for _, n := range s.Nodes {
|
for _, n := range s.Nodes {
|
||||||
if _, ok := m.records[s.Name][s.Version].Nodes[n.Id]; ok {
|
if _, ok := m.records[s.Name][s.Version].Nodes[n.Id]; ok {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "Registry removed node from service: %s, version: %s", s.Name, s.Version)
|
||||||
logger.Debugf("Registry removed node from service: %s, version: %s", s.Name, s.Version)
|
|
||||||
}
|
|
||||||
delete(m.records[s.Name][s.Version].Nodes, n.Id)
|
delete(m.records[s.Name][s.Version].Nodes, n.Id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(m.records[s.Name][s.Version].Nodes) == 0 {
|
if len(m.records[s.Name][s.Version].Nodes) == 0 {
|
||||||
delete(m.records[s.Name], s.Version)
|
delete(m.records[s.Name], s.Version)
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "Registry removed service: %s, version: %s", s.Name, s.Version)
|
||||||
logger.Debugf("Registry removed service: %s, version: %s", s.Name, s.Version)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(m.records[s.Name]) == 0 {
|
if len(m.records[s.Name]) == 0 {
|
||||||
delete(m.records, s.Name)
|
delete(m.records, s.Name)
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "Registry removed service: %s", s.Name)
|
||||||
logger.Debugf("Registry removed service: %s", s.Name)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
go m.sendEvent(&Result{Action: "delete", Service: s})
|
go m.sendEvent(&Result{Action: "delete", Service: s})
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"go-micro.dev/v4/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Options struct {
|
type Options struct {
|
||||||
@ -11,6 +13,7 @@ type Options struct {
|
|||||||
Timeout time.Duration
|
Timeout time.Duration
|
||||||
Secure bool
|
Secure bool
|
||||||
TLSConfig *tls.Config
|
TLSConfig *tls.Config
|
||||||
|
Logger logger.Logger
|
||||||
// Other options for implementations of the interface
|
// Other options for implementations of the interface
|
||||||
// can be stored in a context
|
// can be stored in a context
|
||||||
Context context.Context
|
Context context.Context
|
||||||
@ -44,6 +47,19 @@ type ListOptions struct {
|
|||||||
Context context.Context
|
Context context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewOptions(opts ...Option) *Options {
|
||||||
|
options := Options{
|
||||||
|
Context: context.Background(),
|
||||||
|
Logger: logger.DefaultLogger,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, o := range opts {
|
||||||
|
o(&options)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &options
|
||||||
|
}
|
||||||
|
|
||||||
// Addrs is the registry addresses to use
|
// Addrs is the registry addresses to use
|
||||||
func Addrs(addrs ...string) Option {
|
func Addrs(addrs ...string) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
@ -146,3 +162,10 @@ func Services(s map[string][]*Service) Option {
|
|||||||
o.Context = context.WithValue(o.Context, servicesKey{}, s)
|
o.Context = context.WithValue(o.Context, servicesKey{}, s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Logger sets the underline logger
|
||||||
|
func Logger(l logger.Logger) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.Logger = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
@ -14,7 +13,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/nxadm/tail"
|
"github.com/nxadm/tail"
|
||||||
"go-micro.dev/v4/logger"
|
|
||||||
|
log "go-micro.dev/v4/logger"
|
||||||
"go-micro.dev/v4/runtime/local/git"
|
"go-micro.dev/v4/runtime/local/git"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ const defaultNamespace = "default"
|
|||||||
type runtime struct {
|
type runtime struct {
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
// options configure runtime
|
// options configure runtime
|
||||||
options Options
|
options *Options
|
||||||
// used to stop the runtime
|
// used to stop the runtime
|
||||||
closed chan bool
|
closed chan bool
|
||||||
// used to start new services
|
// used to start new services
|
||||||
@ -39,12 +39,7 @@ type runtime struct {
|
|||||||
// NewRuntime creates new local runtime and returns it
|
// NewRuntime creates new local runtime and returns it
|
||||||
func NewRuntime(opts ...Option) Runtime {
|
func NewRuntime(opts ...Option) Runtime {
|
||||||
// get default options
|
// get default options
|
||||||
options := Options{}
|
options := NewOptions(opts...)
|
||||||
|
|
||||||
// apply requested options
|
|
||||||
for _, o := range opts {
|
|
||||||
o(&options)
|
|
||||||
}
|
|
||||||
|
|
||||||
// make the logs directory
|
// make the logs directory
|
||||||
path := filepath.Join(os.TempDir(), "micro", "logs")
|
path := filepath.Join(os.TempDir(), "micro", "logs")
|
||||||
@ -181,7 +176,7 @@ func (r *runtime) Init(opts ...Option) error {
|
|||||||
defer r.Unlock()
|
defer r.Unlock()
|
||||||
|
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(&r.options)
|
o(r.options)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -192,6 +187,7 @@ func (r *runtime) run(events <-chan Event) {
|
|||||||
t := time.NewTicker(time.Second * 5)
|
t := time.NewTicker(time.Second * 5)
|
||||||
defer t.Stop()
|
defer t.Stop()
|
||||||
|
|
||||||
|
logger := r.options.Logger
|
||||||
// process event processes an incoming event
|
// process event processes an incoming event
|
||||||
processEvent := func(event Event, service *service, ns string) error {
|
processEvent := func(event Event, service *service, ns string) error {
|
||||||
// get current vals
|
// get current vals
|
||||||
@ -205,9 +201,7 @@ func (r *runtime) run(events <-chan Event) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "Runtime updating service %s in %v namespace", name, ns)
|
||||||
logger.Debugf("Runtime updating service %s in %v namespace", name, ns)
|
|
||||||
}
|
|
||||||
|
|
||||||
// this will cause a delete followed by created
|
// this will cause a delete followed by created
|
||||||
if err := r.Update(service.Service, UpdateNamespace(ns)); err != nil {
|
if err := r.Update(service.Service, UpdateNamespace(ns)); err != nil {
|
||||||
@ -234,13 +228,10 @@ func (r *runtime) run(events <-chan Event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check service error
|
// TODO: check service error
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "Runtime starting %s", service.Name)
|
||||||
logger.Debugf("Runtime starting %s", service.Name)
|
|
||||||
}
|
|
||||||
if err := service.Start(); err != nil {
|
if err := service.Start(); err != nil {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "Runtime error starting %s: %v", service.Name, err)
|
||||||
logger.Debugf("Runtime error starting %s: %v", service.Name, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -250,18 +241,13 @@ func (r *runtime) run(events <-chan Event) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// TODO: check service error
|
// TODO: check service error
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "Runtime starting service %s", service.Name)
|
||||||
logger.Debugf("Runtime starting service %s", service.Name)
|
|
||||||
}
|
|
||||||
if err := service.Start(); err != nil {
|
if err := service.Start(); err != nil {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "Runtime error starting service %s: %v", service.Name, err)
|
||||||
logger.Debugf("Runtime error starting service %s: %v", service.Name, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
case event := <-events:
|
case event := <-events:
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "Runtime received notification event: %v", event)
|
||||||
logger.Debugf("Runtime received notification event: %v", event)
|
|
||||||
}
|
|
||||||
// NOTE: we only handle Update events for now
|
// NOTE: we only handle Update events for now
|
||||||
switch event.Type {
|
switch event.Type {
|
||||||
case Update:
|
case Update:
|
||||||
@ -273,22 +259,18 @@ func (r *runtime) run(events <-chan Event) {
|
|||||||
|
|
||||||
r.RLock()
|
r.RLock()
|
||||||
if _, ok := r.namespaces[ns]; !ok {
|
if _, ok := r.namespaces[ns]; !ok {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "Runtime unknown namespace: %s", ns)
|
||||||
logger.Debugf("Runtime unknown namespace: %s", ns)
|
|
||||||
}
|
|
||||||
r.RUnlock()
|
r.RUnlock()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
service, ok := r.namespaces[ns][fmt.Sprintf("%v:%v", event.Service.Name, event.Service.Version)]
|
service, ok := r.namespaces[ns][fmt.Sprintf("%v:%v", event.Service.Name, event.Service.Version)]
|
||||||
r.RUnlock()
|
r.RUnlock()
|
||||||
if !ok {
|
if !ok {
|
||||||
logger.Debugf("Runtime unknown service: %s", event.Service)
|
logger.Logf(log.DebugLevel, "Runtime unknown service: %s", event.Service)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := processEvent(event, service, ns); err != nil {
|
if err := processEvent(event, service, ns); err != nil {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "Runtime error updating service %s: %v", event.Service, err)
|
||||||
logger.Debugf("Runtime error updating service %s: %v", event.Service, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -301,17 +283,13 @@ func (r *runtime) run(events <-chan Event) {
|
|||||||
for ns, services := range namespaces {
|
for ns, services := range namespaces {
|
||||||
for _, service := range services {
|
for _, service := range services {
|
||||||
if err := processEvent(event, service, ns); err != nil {
|
if err := processEvent(event, service, ns); err != nil {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "Runtime error updating service %s: %v", service.Name, err)
|
||||||
logger.Debugf("Runtime error updating service %s: %v", service.Name, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case <-r.closed:
|
case <-r.closed:
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "Runtime stopped")
|
||||||
logger.Debugf("Runtime stopped")
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -357,11 +335,11 @@ func (r *runtime) Create(s *Service, opts ...CreateOption) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create new service
|
// create new service
|
||||||
service := newService(s, options)
|
service := newService(s, options, r.options.Logger)
|
||||||
|
|
||||||
f, err := os.OpenFile(logFile(service.Name), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
f, err := os.OpenFile(logFile(service.Name), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
r.options.Logger.Log(log.FatalLevel, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if service.output != nil {
|
if service.output != nil {
|
||||||
@ -400,10 +378,12 @@ func (r *runtime) Logs(s *Service, options ...LogsOption) (LogStream, error) {
|
|||||||
for _, o := range options {
|
for _, o := range options {
|
||||||
o(&lopts)
|
o(&lopts)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret := &logStream{
|
ret := &logStream{
|
||||||
service: s.Name,
|
service: s.Name,
|
||||||
stream: make(chan LogRecord),
|
stream: make(chan LogRecord),
|
||||||
stop: make(chan bool),
|
stop: make(chan bool),
|
||||||
|
logger: r.options.Logger,
|
||||||
}
|
}
|
||||||
|
|
||||||
fpath := logFile(s.Name)
|
fpath := logFile(s.Name)
|
||||||
@ -463,6 +443,7 @@ type logStream struct {
|
|||||||
sync.Mutex
|
sync.Mutex
|
||||||
stop chan bool
|
stop chan bool
|
||||||
err error
|
err error
|
||||||
|
logger log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *logStream) Chan() chan LogRecord {
|
func (l *logStream) Chan() chan LogRecord {
|
||||||
@ -485,7 +466,7 @@ func (l *logStream) Stop() error {
|
|||||||
close(l.stream)
|
close(l.stream)
|
||||||
err := l.tail.Stop()
|
err := l.tail.Stop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("Error stopping tail: %v", err)
|
l.logger.Logf(log.ErrorLevel, "Error stopping tail: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -565,7 +546,7 @@ func (r *runtime) Update(s *Service, opts ...UpdateOption) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := service.Stop(); err != nil && err.Error() != "no such process" {
|
if err := service.Stop(); err != nil && err.Error() != "no such process" {
|
||||||
logger.Errorf("Error stopping service %s: %s", service.Name, err)
|
r.options.Logger.Logf(log.ErrorLevel, "Error stopping service %s: %s", service.Name, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -590,9 +571,7 @@ func (r *runtime) Delete(s *Service, opts ...DeleteOption) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
r.options.Logger.Logf(log.DebugLevel, "Runtime deleting service %s", s.Name)
|
||||||
logger.Debugf("Runtime deleting service %s", s.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
service, ok := srvs[serviceKey(s)]
|
service, ok := srvs[serviceKey(s)]
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -635,9 +614,7 @@ func (r *runtime) Start() error {
|
|||||||
events, err = r.options.Scheduler.Notify()
|
events, err = r.options.Scheduler.Notify()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: should we bail here?
|
// TODO: should we bail here?
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
r.options.Logger.Logf(log.DebugLevel, "Runtime failed to start update notifier")
|
||||||
logger.Debugf("Runtime failed to start update notifier")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -667,9 +644,7 @@ func (r *runtime) Stop() error {
|
|||||||
// stop all the services
|
// stop all the services
|
||||||
for _, services := range r.namespaces {
|
for _, services := range r.namespaces {
|
||||||
for _, service := range services {
|
for _, service := range services {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
r.options.Logger.Logf(log.DebugLevel, "Runtime stopping %s", service.Name)
|
||||||
logger.Debugf("Runtime stopping %s", service.Name)
|
|
||||||
}
|
|
||||||
service.Stop()
|
service.Stop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ type action int
|
|||||||
type kubernetes struct {
|
type kubernetes struct {
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
// options configure runtime
|
// options configure runtime
|
||||||
options runtime.Options
|
options *runtime.Options
|
||||||
// indicates if we're running
|
// indicates if we're running
|
||||||
running bool
|
running bool
|
||||||
// used to stop the runtime
|
// used to stop the runtime
|
||||||
@ -235,7 +235,7 @@ func (k *kubernetes) getService(labels map[string]string, opts ...client.GetOpti
|
|||||||
func (k *kubernetes) run(events <-chan runtime.Event) {
|
func (k *kubernetes) run(events <-chan runtime.Event) {
|
||||||
t := time.NewTicker(time.Second * 10)
|
t := time.NewTicker(time.Second * 10)
|
||||||
defer t.Stop()
|
defer t.Stop()
|
||||||
|
logger := k.options.Logger
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-t.C:
|
case <-t.C:
|
||||||
@ -243,9 +243,7 @@ func (k *kubernetes) run(events <-chan runtime.Event) {
|
|||||||
// - do we even need the ticker for k8s services?
|
// - do we even need the ticker for k8s services?
|
||||||
case event := <-events:
|
case event := <-events:
|
||||||
// NOTE: we only handle Update events for now
|
// NOTE: we only handle Update events for now
|
||||||
if log.V(log.DebugLevel, log.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "Runtime received notification event: %v", event)
|
||||||
log.Debugf("Runtime received notification event: %v", event)
|
|
||||||
}
|
|
||||||
switch event.Type {
|
switch event.Type {
|
||||||
case runtime.Update:
|
case runtime.Update:
|
||||||
// only process if there's an actual service
|
// only process if there's an actual service
|
||||||
@ -277,9 +275,7 @@ func (k *kubernetes) run(events <-chan runtime.Event) {
|
|||||||
}, client.GetLabels(labels))
|
}, client.GetLabels(labels))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if log.V(log.DebugLevel, log.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "Runtime update failed to get service %s: %v", event.Service, err)
|
||||||
log.Debugf("Runtime update failed to get service %s: %v", event.Service, err)
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,21 +294,15 @@ func (k *kubernetes) run(events <-chan runtime.Event) {
|
|||||||
// update the build time
|
// update the build time
|
||||||
service.Spec.Template.Metadata.Annotations["updated"] = fmt.Sprintf("%d", event.Timestamp.Unix())
|
service.Spec.Template.Metadata.Annotations["updated"] = fmt.Sprintf("%d", event.Timestamp.Unix())
|
||||||
|
|
||||||
if log.V(log.DebugLevel, log.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "Runtime updating service: %s deployment: %s", event.Service, service.Metadata.Name)
|
||||||
log.Debugf("Runtime updating service: %s deployment: %s", event.Service, service.Metadata.Name)
|
|
||||||
}
|
|
||||||
if err := k.client.Update(deploymentResource(&service)); err != nil {
|
if err := k.client.Update(deploymentResource(&service)); err != nil {
|
||||||
if log.V(log.DebugLevel, log.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "Runtime failed to update service %s: %v", event.Service, err)
|
||||||
log.Debugf("Runtime failed to update service %s: %v", event.Service, err)
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case <-k.closed:
|
case <-k.closed:
|
||||||
if log.V(log.DebugLevel, log.DefaultLogger) {
|
logger.Logf(log.DebugLevel, "Runtime stopped")
|
||||||
log.Debugf("Runtime stopped")
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -324,7 +314,7 @@ func (k *kubernetes) Init(opts ...runtime.Option) error {
|
|||||||
defer k.Unlock()
|
defer k.Unlock()
|
||||||
|
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(&k.options)
|
o(k.options)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -341,7 +331,7 @@ func (k *kubernetes) Logs(s *runtime.Service, options ...runtime.LogsOption) (ru
|
|||||||
go func() {
|
go func() {
|
||||||
records, err := klo.Read()
|
records, err := klo.Read()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Failed to get logs for service '%v' from k8s: %v", err)
|
k.options.Logger.Logf(log.ErrorLevel, "Failed to get logs for service '%v' from k8s: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// @todo: this might actually not run before podLogStream starts
|
// @todo: this might actually not run before podLogStream starts
|
||||||
@ -425,7 +415,7 @@ func (k *kubernetes) Create(s *runtime.Service, opts ...runtime.CreateOption) er
|
|||||||
options.Image = k.getImage(s, options)
|
options.Image = k.getImage(s, options)
|
||||||
|
|
||||||
// create new service
|
// create new service
|
||||||
service := newService(s, options)
|
service := newService(s, options, k.options.Logger)
|
||||||
|
|
||||||
// start the service
|
// start the service
|
||||||
return service.Start(k.client, client.CreateNamespace(options.Namespace))
|
return service.Start(k.client, client.CreateNamespace(options.Namespace))
|
||||||
@ -542,7 +532,7 @@ func (k *kubernetes) Delete(s *runtime.Service, opts ...runtime.DeleteOption) er
|
|||||||
service := newService(s, runtime.CreateOptions{
|
service := newService(s, runtime.CreateOptions{
|
||||||
Type: k.options.Type,
|
Type: k.options.Type,
|
||||||
Namespace: options.Namespace,
|
Namespace: options.Namespace,
|
||||||
})
|
}, k.options.Logger)
|
||||||
|
|
||||||
return service.Stop(k.client, client.DeleteNamespace(options.Namespace))
|
return service.Stop(k.client, client.DeleteNamespace(options.Namespace))
|
||||||
}
|
}
|
||||||
@ -567,9 +557,7 @@ func (k *kubernetes) Start() error {
|
|||||||
events, err = k.options.Scheduler.Notify()
|
events, err = k.options.Scheduler.Notify()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: should we bail here?
|
// TODO: should we bail here?
|
||||||
if log.V(log.DebugLevel, log.DefaultLogger) {
|
k.options.Logger.Logf(log.DebugLevel, "Runtime failed to start update notifier")
|
||||||
log.Debugf("Runtime failed to start update notifier")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -611,15 +599,9 @@ func (k *kubernetes) String() string {
|
|||||||
// NewRuntime creates new kubernetes runtime
|
// NewRuntime creates new kubernetes runtime
|
||||||
func NewRuntime(opts ...runtime.Option) runtime.Runtime {
|
func NewRuntime(opts ...runtime.Option) runtime.Runtime {
|
||||||
// get default options
|
// get default options
|
||||||
options := runtime.Options{
|
|
||||||
// Create labels with type "micro": "service"
|
// Create labels with type "micro": "service"
|
||||||
Type: "service",
|
mtops := append([]runtime.Option{runtime.WithType("service")}, opts...)
|
||||||
}
|
options := runtime.NewOptions(mtops...)
|
||||||
|
|
||||||
// apply requested options
|
|
||||||
for _, o := range opts {
|
|
||||||
o(&options)
|
|
||||||
}
|
|
||||||
|
|
||||||
// kubernetes client
|
// kubernetes client
|
||||||
client := client.NewClusterClient()
|
client := client.NewClusterClient()
|
||||||
|
@ -5,7 +5,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"go-micro.dev/v4/logger"
|
log "go-micro.dev/v4/logger"
|
||||||
"go-micro.dev/v4/runtime"
|
"go-micro.dev/v4/runtime"
|
||||||
"go-micro.dev/v4/util/kubernetes/api"
|
"go-micro.dev/v4/util/kubernetes/api"
|
||||||
"go-micro.dev/v4/util/kubernetes/client"
|
"go-micro.dev/v4/util/kubernetes/client"
|
||||||
@ -18,6 +18,8 @@ type service struct {
|
|||||||
kservice *client.Service
|
kservice *client.Service
|
||||||
// Kubernetes deployment
|
// Kubernetes deployment
|
||||||
kdeploy *client.Deployment
|
kdeploy *client.Deployment
|
||||||
|
// to be used logger
|
||||||
|
logger log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseError(err error) *api.Status {
|
func parseError(err error) *api.Status {
|
||||||
@ -26,7 +28,7 @@ func parseError(err error) *api.Status {
|
|||||||
return status
|
return status
|
||||||
}
|
}
|
||||||
|
|
||||||
func newService(s *runtime.Service, c runtime.CreateOptions) *service {
|
func newService(s *runtime.Service, c runtime.CreateOptions, l log.Logger) *service {
|
||||||
// use pre-formatted name/version
|
// use pre-formatted name/version
|
||||||
name := client.Format(s.Name)
|
name := client.Format(s.Name)
|
||||||
version := client.Format(s.Version)
|
version := client.Format(s.Version)
|
||||||
@ -93,6 +95,7 @@ func newService(s *runtime.Service, c runtime.CreateOptions) *service {
|
|||||||
Service: s,
|
Service: s,
|
||||||
kservice: kservice,
|
kservice: kservice,
|
||||||
kdeploy: kdeploy,
|
kdeploy: kdeploy,
|
||||||
|
logger: log.LoggerOrDefault(l),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,9 +119,7 @@ func serviceResource(s *client.Service) *client.Resource {
|
|||||||
func (s *service) Start(k client.Client, opts ...client.CreateOption) error {
|
func (s *service) Start(k client.Client, opts ...client.CreateOption) error {
|
||||||
// create deployment first; if we fail, we dont create service
|
// create deployment first; if we fail, we dont create service
|
||||||
if err := k.Create(deploymentResource(s.kdeploy), opts...); err != nil {
|
if err := k.Create(deploymentResource(s.kdeploy), opts...); err != nil {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
s.logger.Logf(log.DebugLevel, "Runtime failed to create deployment: %v", err)
|
||||||
logger.Debugf("Runtime failed to create deployment: %v", err)
|
|
||||||
}
|
|
||||||
s.Status("error", err)
|
s.Status("error", err)
|
||||||
v := parseError(err)
|
v := parseError(err)
|
||||||
if v.Reason == "AlreadyExists" {
|
if v.Reason == "AlreadyExists" {
|
||||||
@ -128,9 +129,7 @@ func (s *service) Start(k client.Client, opts ...client.CreateOption) error {
|
|||||||
}
|
}
|
||||||
// create service now that the deployment has been created
|
// create service now that the deployment has been created
|
||||||
if err := k.Create(serviceResource(s.kservice), opts...); err != nil {
|
if err := k.Create(serviceResource(s.kservice), opts...); err != nil {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
s.logger.Logf(log.DebugLevel, "Runtime failed to create service: %v", err)
|
||||||
logger.Debugf("Runtime failed to create service: %v", err)
|
|
||||||
}
|
|
||||||
s.Status("error", err)
|
s.Status("error", err)
|
||||||
v := parseError(err)
|
v := parseError(err)
|
||||||
if v.Reason == "AlreadyExists" {
|
if v.Reason == "AlreadyExists" {
|
||||||
@ -147,17 +146,13 @@ func (s *service) Start(k client.Client, opts ...client.CreateOption) error {
|
|||||||
func (s *service) Stop(k client.Client, opts ...client.DeleteOption) error {
|
func (s *service) Stop(k client.Client, opts ...client.DeleteOption) error {
|
||||||
// first attempt to delete service
|
// first attempt to delete service
|
||||||
if err := k.Delete(serviceResource(s.kservice), opts...); err != nil {
|
if err := k.Delete(serviceResource(s.kservice), opts...); err != nil {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
s.logger.Logf(log.DebugLevel, "Runtime failed to delete service: %v", err)
|
||||||
logger.Debugf("Runtime failed to delete service: %v", err)
|
|
||||||
}
|
|
||||||
s.Status("error", err)
|
s.Status("error", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// delete deployment once the service has been deleted
|
// delete deployment once the service has been deleted
|
||||||
if err := k.Delete(deploymentResource(s.kdeploy), opts...); err != nil {
|
if err := k.Delete(deploymentResource(s.kdeploy), opts...); err != nil {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
s.logger.Logf(log.DebugLevel, "Runtime failed to delete deployment: %v", err)
|
||||||
logger.Debugf("Runtime failed to delete deployment: %v", err)
|
|
||||||
}
|
|
||||||
s.Status("error", err)
|
s.Status("error", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -169,16 +164,12 @@ func (s *service) Stop(k client.Client, opts ...client.DeleteOption) error {
|
|||||||
|
|
||||||
func (s *service) Update(k client.Client, opts ...client.UpdateOption) error {
|
func (s *service) Update(k client.Client, opts ...client.UpdateOption) error {
|
||||||
if err := k.Update(deploymentResource(s.kdeploy), opts...); err != nil {
|
if err := k.Update(deploymentResource(s.kdeploy), opts...); err != nil {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
s.logger.Logf(log.DebugLevel, "Runtime failed to update deployment: %v", err)
|
||||||
logger.Debugf("Runtime failed to update deployment: %v", err)
|
|
||||||
}
|
|
||||||
s.Status("error", err)
|
s.Status("error", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := k.Update(serviceResource(s.kservice), opts...); err != nil {
|
if err := k.Update(serviceResource(s.kservice), opts...); err != nil {
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
s.logger.Logf(log.DebugLevel, "Runtime failed to update service: %v", err)
|
||||||
logger.Debugf("Runtime failed to update service: %v", err)
|
|
||||||
}
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ func NewBuilder(opts ...build.Option) build.Builder {
|
|||||||
endpoint := "unix:///var/run/docker.sock"
|
endpoint := "unix:///var/run/docker.sock"
|
||||||
client, err := docker.NewClient(endpoint)
|
client, err := docker.NewClient(endpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatal(err)
|
logger.Log(logger.FatalLevel, err)
|
||||||
}
|
}
|
||||||
return &Builder{
|
return &Builder{
|
||||||
Options: options,
|
Options: options,
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
|
|
||||||
"go-micro.dev/v4/client"
|
"go-micro.dev/v4/client"
|
||||||
|
"go-micro.dev/v4/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Option func(o *Options)
|
type Option func(o *Options)
|
||||||
@ -21,6 +22,20 @@ type Options struct {
|
|||||||
Image string
|
Image string
|
||||||
// Client to use when making requests
|
// Client to use when making requests
|
||||||
Client client.Client
|
Client client.Client
|
||||||
|
// Logger underline logger
|
||||||
|
Logger logger.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewOptions(opts ...Option) *Options {
|
||||||
|
options := &Options{
|
||||||
|
Logger: logger.DefaultLogger,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, o := range opts {
|
||||||
|
o(options)
|
||||||
|
}
|
||||||
|
|
||||||
|
return options
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithSource sets the base image / repository
|
// WithSource sets the base image / repository
|
||||||
@ -58,6 +73,13 @@ func WithClient(c client.Client) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithLogger sets the underline logger
|
||||||
|
func WithLogger(l logger.Logger) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.Logger = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type CreateOption func(o *CreateOptions)
|
type CreateOption func(o *CreateOptions)
|
||||||
|
|
||||||
type ReadOption func(o *ReadOptions)
|
type ReadOption func(o *ReadOptions)
|
||||||
|
@ -8,7 +8,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"go-micro.dev/v4/logger"
|
log "go-micro.dev/v4/logger"
|
||||||
"go-micro.dev/v4/runtime/local/build"
|
"go-micro.dev/v4/runtime/local/build"
|
||||||
"go-micro.dev/v4/runtime/local/process"
|
"go-micro.dev/v4/runtime/local/process"
|
||||||
proc "go-micro.dev/v4/runtime/local/process/os"
|
proc "go-micro.dev/v4/runtime/local/process/os"
|
||||||
@ -36,9 +36,11 @@ type service struct {
|
|||||||
Exec *process.Executable
|
Exec *process.Executable
|
||||||
// process pid
|
// process pid
|
||||||
PID *process.PID
|
PID *process.PID
|
||||||
|
// to be used logger
|
||||||
|
Logger log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func newService(s *Service, c CreateOptions) *service {
|
func newService(s *Service, c CreateOptions, l log.Logger) *service {
|
||||||
var exec string
|
var exec string
|
||||||
var args []string
|
var args []string
|
||||||
|
|
||||||
@ -58,6 +60,7 @@ func newService(s *Service, c CreateOptions) *service {
|
|||||||
Args: args,
|
Args: args,
|
||||||
Dir: s.Source,
|
Dir: s.Source,
|
||||||
},
|
},
|
||||||
|
Logger: log.LoggerOrDefault(l),
|
||||||
closed: make(chan bool),
|
closed: make(chan bool),
|
||||||
output: c.Output,
|
output: c.Output,
|
||||||
updated: time.Now(),
|
updated: time.Now(),
|
||||||
@ -101,7 +104,6 @@ func (s *service) Start() error {
|
|||||||
if !s.shouldStart() {
|
if !s.shouldStart() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset
|
// reset
|
||||||
s.err = nil
|
s.err = nil
|
||||||
s.closed = make(chan bool)
|
s.closed = make(chan bool)
|
||||||
@ -113,9 +115,7 @@ func (s *service) Start() error {
|
|||||||
s.Status("starting", nil)
|
s.Status("starting", nil)
|
||||||
|
|
||||||
// TODO: pull source & build binary
|
// TODO: pull source & build binary
|
||||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
s.Logger.Log(log.DebugLevel, "Runtime service %s forking new process", s.Service.Name)
|
||||||
logger.Debugf("Runtime service %s forking new process", s.Service.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
p, err := s.Process.Fork(s.Exec)
|
p, err := s.Process.Fork(s.Exec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -207,15 +207,13 @@ func (s *service) Wait() {
|
|||||||
|
|
||||||
if s.PID.ID != thisPID.ID {
|
if s.PID.ID != thisPID.ID {
|
||||||
// trying to update when it's already been switched out, ignore
|
// trying to update when it's already been switched out, ignore
|
||||||
logger.Warnf("Trying to update a process status but PID doesn't match. Old %s, New %s. Skipping update.", thisPID.ID, s.PID.ID)
|
s.Logger.Logf(log.WarnLevel, "Trying to update a process status but PID doesn't match. Old %s, New %s. Skipping update.", thisPID.ID, s.PID.ID)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// save the error
|
// save the error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
s.Logger.Logf(log.ErrorLevel, "Service %s terminated with error %s", s.Name, err)
|
||||||
logger.Errorf("Service %s terminated with error %s", s.Name, err)
|
|
||||||
}
|
|
||||||
s.retries++
|
s.retries++
|
||||||
s.Status("error", err)
|
s.Status("error", err)
|
||||||
s.Metadata["retries"] = strconv.Itoa(s.retries)
|
s.Metadata["retries"] = strconv.Itoa(s.retries)
|
||||||
|
@ -3,6 +3,7 @@ package selector
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"go-micro.dev/v4/logger"
|
||||||
"go-micro.dev/v4/registry"
|
"go-micro.dev/v4/registry"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -13,6 +14,8 @@ type Options struct {
|
|||||||
// Other options for implementations of the interface
|
// Other options for implementations of the interface
|
||||||
// can be stored in a context
|
// can be stored in a context
|
||||||
Context context.Context
|
Context context.Context
|
||||||
|
// Logger is the underline logger
|
||||||
|
Logger logger.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
type SelectOptions struct {
|
type SelectOptions struct {
|
||||||
@ -58,3 +61,10 @@ func WithStrategy(fn Strategy) SelectOption {
|
|||||||
o.Strategy = fn
|
o.Strategy = fn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithLogger sets the underline logger
|
||||||
|
func WithLogger(l logger.Logger) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.Logger = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -9,10 +9,36 @@ import (
|
|||||||
"go-micro.dev/v4/broker"
|
"go-micro.dev/v4/broker"
|
||||||
"go-micro.dev/v4/codec"
|
"go-micro.dev/v4/codec"
|
||||||
"go-micro.dev/v4/debug/trace"
|
"go-micro.dev/v4/debug/trace"
|
||||||
|
"go-micro.dev/v4/logger"
|
||||||
"go-micro.dev/v4/registry"
|
"go-micro.dev/v4/registry"
|
||||||
"go-micro.dev/v4/transport"
|
"go-micro.dev/v4/transport"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type RouterOptions struct {
|
||||||
|
Logger logger.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
type RouterOption func(o *RouterOptions)
|
||||||
|
|
||||||
|
func newRouterOptions(opt ...RouterOption) RouterOptions {
|
||||||
|
opts := RouterOptions{
|
||||||
|
Logger: logger.DefaultLogger,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, o := range opt {
|
||||||
|
o(&opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
return opts
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithRouterLogger sets the underline router logger
|
||||||
|
func WithRouterLogger(l logger.Logger) RouterOption {
|
||||||
|
return func(o *RouterOptions) {
|
||||||
|
o.Logger = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type Options struct {
|
type Options struct {
|
||||||
Codecs map[string]codec.NewCodec
|
Codecs map[string]codec.NewCodec
|
||||||
Broker broker.Broker
|
Broker broker.Broker
|
||||||
@ -28,6 +54,7 @@ type Options struct {
|
|||||||
HdlrWrappers []HandlerWrapper
|
HdlrWrappers []HandlerWrapper
|
||||||
SubWrappers []SubscriberWrapper
|
SubWrappers []SubscriberWrapper
|
||||||
ListenOptions []transport.ListenOption
|
ListenOptions []transport.ListenOption
|
||||||
|
Logger logger.Logger
|
||||||
|
|
||||||
// RegisterCheck runs a check function before registering the service
|
// RegisterCheck runs a check function before registering the service
|
||||||
RegisterCheck func(context.Context) error
|
RegisterCheck func(context.Context) error
|
||||||
@ -53,6 +80,7 @@ func newOptions(opt ...Option) Options {
|
|||||||
Metadata: map[string]string{},
|
Metadata: map[string]string{},
|
||||||
RegisterInterval: DefaultRegisterInterval,
|
RegisterInterval: DefaultRegisterInterval,
|
||||||
RegisterTTL: DefaultRegisterTTL,
|
RegisterTTL: DefaultRegisterTTL,
|
||||||
|
Logger: logger.DefaultLogger,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, o := range opt {
|
for _, o := range opt {
|
||||||
@ -228,6 +256,13 @@ func WithRouter(r Router) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithLogger sets the underline logger
|
||||||
|
func WithLogger(l logger.Logger) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.Logger = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Wait tells the server to wait for requests to finish before exiting
|
// Wait tells the server to wait for requests to finish before exiting
|
||||||
// If `wg` is nil, server only wait for completion of rpc handler.
|
// If `wg` is nil, server only wait for completion of rpc handler.
|
||||||
// For user need finer grained control, pass a concrete `wg` here, server will
|
// For user need finer grained control, pass a concrete `wg` here, server will
|
||||||
|
@ -20,11 +20,12 @@ import (
|
|||||||
|
|
||||||
"go-micro.dev/v4/codec"
|
"go-micro.dev/v4/codec"
|
||||||
merrors "go-micro.dev/v4/errors"
|
merrors "go-micro.dev/v4/errors"
|
||||||
"go-micro.dev/v4/logger"
|
|
||||||
|
log "go-micro.dev/v4/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
lastStreamResponseError = errors.New("EOS")
|
errLastStreamResponse = errors.New("EOS")
|
||||||
|
|
||||||
// Precompute the reflect type for error. Can't use error directly
|
// Precompute the reflect type for error. Can't use error directly
|
||||||
// because Typeof takes an empty interface value. This is annoying.
|
// because Typeof takes an empty interface value. This is annoying.
|
||||||
@ -60,6 +61,7 @@ type response struct {
|
|||||||
// router represents an RPC router.
|
// router represents an RPC router.
|
||||||
type router struct {
|
type router struct {
|
||||||
name string
|
name string
|
||||||
|
ops RouterOptions
|
||||||
|
|
||||||
mu sync.Mutex // protects the serviceMap
|
mu sync.Mutex // protects the serviceMap
|
||||||
serviceMap map[string]*service
|
serviceMap map[string]*service
|
||||||
@ -93,8 +95,9 @@ func (r rpcRouter) ServeRequest(ctx context.Context, req Request, rsp Response)
|
|||||||
return r.h(ctx, req, rsp)
|
return r.h(ctx, req, rsp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRpcRouter() *router {
|
func newRpcRouter(opts ...RouterOption) *router {
|
||||||
return &router{
|
return &router{
|
||||||
|
ops: newRouterOptions(opts...),
|
||||||
serviceMap: make(map[string]*service),
|
serviceMap: make(map[string]*service),
|
||||||
subscribers: make(map[string][]*subscriber),
|
subscribers: make(map[string][]*subscriber),
|
||||||
}
|
}
|
||||||
@ -118,7 +121,7 @@ func isExportedOrBuiltinType(t reflect.Type) bool {
|
|||||||
|
|
||||||
// prepareMethod returns a methodType for the provided method or nil
|
// prepareMethod returns a methodType for the provided method or nil
|
||||||
// in case if the method was unsuitable.
|
// in case if the method was unsuitable.
|
||||||
func prepareMethod(method reflect.Method) *methodType {
|
func prepareMethod(method reflect.Method, logger log.Logger) *methodType {
|
||||||
mtype := method.Type
|
mtype := method.Type
|
||||||
mname := method.Name
|
mname := method.Name
|
||||||
var replyType, argType, contextType reflect.Type
|
var replyType, argType, contextType reflect.Type
|
||||||
@ -141,7 +144,7 @@ func prepareMethod(method reflect.Method) *methodType {
|
|||||||
replyType = mtype.In(3)
|
replyType = mtype.In(3)
|
||||||
contextType = mtype.In(1)
|
contextType = mtype.In(1)
|
||||||
default:
|
default:
|
||||||
logger.Errorf("method %v of %v has wrong number of ins: %v", mname, mtype, mtype.NumIn())
|
logger.Logf(log.ErrorLevel, "method %v of %v has wrong number of ins: %v", mname, mtype, mtype.NumIn())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +152,7 @@ func prepareMethod(method reflect.Method) *methodType {
|
|||||||
// check stream type
|
// check stream type
|
||||||
streamType := reflect.TypeOf((*Stream)(nil)).Elem()
|
streamType := reflect.TypeOf((*Stream)(nil)).Elem()
|
||||||
if !argType.Implements(streamType) {
|
if !argType.Implements(streamType) {
|
||||||
logger.Errorf("%v argument does not implement Stream interface: %v", mname, argType)
|
logger.Logf(log.ErrorLevel, "%v argument does not implement Stream interface: %v", mname, argType)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -157,30 +160,30 @@ func prepareMethod(method reflect.Method) *methodType {
|
|||||||
|
|
||||||
// First arg need not be a pointer.
|
// First arg need not be a pointer.
|
||||||
if !isExportedOrBuiltinType(argType) {
|
if !isExportedOrBuiltinType(argType) {
|
||||||
logger.Errorf("%v argument type not exported: %v", mname, argType)
|
logger.Logf(log.ErrorLevel, "%v argument type not exported: %v", mname, argType)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if replyType.Kind() != reflect.Ptr {
|
if replyType.Kind() != reflect.Ptr {
|
||||||
logger.Errorf("method %v reply type not a pointer: %v", mname, replyType)
|
logger.Logf(log.ErrorLevel, "method %v reply type not a pointer: %v", mname, replyType)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reply type must be exported.
|
// Reply type must be exported.
|
||||||
if !isExportedOrBuiltinType(replyType) {
|
if !isExportedOrBuiltinType(replyType) {
|
||||||
logger.Errorf("method %v reply type not exported: %v", mname, replyType)
|
logger.Logf(log.ErrorLevel, "method %v reply type not exported: %v", mname, replyType)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method needs one out.
|
// Method needs one out.
|
||||||
if mtype.NumOut() != 1 {
|
if mtype.NumOut() != 1 {
|
||||||
logger.Errorf("method %v has wrong number of outs: %v", mname, mtype.NumOut())
|
logger.Logf(log.ErrorLevel, "method %v has wrong number of outs: %v", mname, mtype.NumOut())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// The return type of the method must be error.
|
// The return type of the method must be error.
|
||||||
if returnType := mtype.Out(0); returnType != typeOfError {
|
if returnType := mtype.Out(0); returnType != typeOfError {
|
||||||
logger.Errorf("method %v returns %v not error", mname, returnType.String())
|
logger.Logf(log.ErrorLevel, "method %v returns %v not error", mname, returnType.String())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return &methodType{method: method, ArgType: argType, ReplyType: replyType, ContextType: contextType, stream: stream}
|
return &methodType{method: method, ArgType: argType, ReplyType: replyType, ContextType: contextType, stream: stream}
|
||||||
@ -266,7 +269,7 @@ func (s *service) call(ctx context.Context, router *router, sending *sync.Mutex,
|
|||||||
return nil
|
return nil
|
||||||
} else {
|
} else {
|
||||||
// no error, we send the special EOS error
|
// no error, we send the special EOS error
|
||||||
return lastStreamResponseError
|
return errLastStreamResponse
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,7 +449,7 @@ func (router *router) Handle(h Handler) error {
|
|||||||
// Install the methods
|
// Install the methods
|
||||||
for m := 0; m < s.typ.NumMethod(); m++ {
|
for m := 0; m < s.typ.NumMethod(); m++ {
|
||||||
method := s.typ.Method(m)
|
method := s.typ.Method(m)
|
||||||
if mt := prepareMethod(method); mt != nil {
|
if mt := prepareMethod(method, router.ops.Logger); mt != nil {
|
||||||
s.method[method.Name] = mt
|
s.method[method.Name] = mt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -509,8 +512,8 @@ func (router *router) ProcessMessage(ctx context.Context, msg Message) (err erro
|
|||||||
defer func() {
|
defer func() {
|
||||||
// recover any panics
|
// recover any panics
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
logger.Errorf("panic recovered: %v", r)
|
router.ops.Logger.Logf(log.ErrorLevel, "panic recovered: %v", r)
|
||||||
logger.Error(string(debug.Stack()))
|
router.ops.Logger.Log(log.ErrorLevel, string(debug.Stack()))
|
||||||
err = merrors.InternalServerError("go.micro.server", "panic recovered: %v", r)
|
err = merrors.InternalServerError("go.micro.server", "panic recovered: %v", r)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
@ -15,7 +15,8 @@ import (
|
|||||||
"go-micro.dev/v4/broker"
|
"go-micro.dev/v4/broker"
|
||||||
"go-micro.dev/v4/codec"
|
"go-micro.dev/v4/codec"
|
||||||
raw "go-micro.dev/v4/codec/bytes"
|
raw "go-micro.dev/v4/codec/bytes"
|
||||||
"go-micro.dev/v4/logger"
|
|
||||||
|
log "go-micro.dev/v4/logger"
|
||||||
"go-micro.dev/v4/metadata"
|
"go-micro.dev/v4/metadata"
|
||||||
"go-micro.dev/v4/registry"
|
"go-micro.dev/v4/registry"
|
||||||
"go-micro.dev/v4/transport"
|
"go-micro.dev/v4/transport"
|
||||||
@ -131,6 +132,7 @@ func (s *rpcServer) HandleEvent(e broker.Event) error {
|
|||||||
|
|
||||||
// ServeConn serves a single connection
|
// ServeConn serves a single connection
|
||||||
func (s *rpcServer) ServeConn(sock transport.Socket) {
|
func (s *rpcServer) ServeConn(sock transport.Socket) {
|
||||||
|
logger := s.opts.Logger
|
||||||
// global error tracking
|
// global error tracking
|
||||||
var gerr error
|
var gerr error
|
||||||
// streams are multiplexed on Micro-Stream or Micro-Id header
|
// streams are multiplexed on Micro-Stream or Micro-Id header
|
||||||
@ -161,10 +163,8 @@ func (s *rpcServer) ServeConn(sock transport.Socket) {
|
|||||||
|
|
||||||
// recover any panics
|
// recover any panics
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
logger.Log(log.ErrorLevel, "panic recovered: ", r)
|
||||||
logger.Error("panic recovered: ", r)
|
logger.Log(log.ErrorLevel, string(debug.Stack()))
|
||||||
logger.Error(string(debug.Stack()))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -227,7 +227,7 @@ func (s *rpcServer) ServeConn(sock transport.Socket) {
|
|||||||
if !ok && stream {
|
if !ok && stream {
|
||||||
// check if its a last stream EOS error
|
// check if its a last stream EOS error
|
||||||
err := msg.Header["Micro-Error"]
|
err := msg.Header["Micro-Error"]
|
||||||
if err == lastStreamResponseError.Error() {
|
if err == errLastStreamResponse.Error() {
|
||||||
pool.Release(psock)
|
pool.Release(psock)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -383,10 +383,8 @@ func (s *rpcServer) ServeConn(sock transport.Socket) {
|
|||||||
|
|
||||||
// recover any panics for outbound process
|
// recover any panics for outbound process
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
logger.Log(log.ErrorLevel, "panic recovered: ", r)
|
||||||
logger.Error("panic recovered: ", r)
|
logger.Log(log.ErrorLevel, string(debug.Stack()))
|
||||||
logger.Error(string(debug.Stack()))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -414,8 +412,8 @@ func (s *rpcServer) ServeConn(sock transport.Socket) {
|
|||||||
|
|
||||||
// recover any panics for call handler
|
// recover any panics for call handler
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
logger.Error("panic recovered: ", r)
|
logger.Log(log.ErrorLevel, "panic recovered: ", r)
|
||||||
logger.Error(string(debug.Stack()))
|
logger.Log(log.ErrorLevel, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -430,11 +428,11 @@ func (s *rpcServer) ServeConn(sock transport.Socket) {
|
|||||||
|
|
||||||
// if the server request is an EOS error we let the socket know
|
// if the server request is an EOS error we let the socket know
|
||||||
// sometimes the socket is already closed on the other side, so we can ignore that error
|
// sometimes the socket is already closed on the other side, so we can ignore that error
|
||||||
alreadyClosed := serveRequestError == lastStreamResponseError && writeError == io.EOF
|
alreadyClosed := serveRequestError == errLastStreamResponse && writeError == io.EOF
|
||||||
|
|
||||||
// could not write error response
|
// could not write error response
|
||||||
if writeError != nil && !alreadyClosed {
|
if writeError != nil && !alreadyClosed {
|
||||||
logger.Debugf("rpc: unable to write error response: %v", writeError)
|
logger.Logf(log.DebugLevel, "rpc: unable to write error response: %v", writeError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}(id, psock)
|
}(id, psock)
|
||||||
@ -517,7 +515,7 @@ func (s *rpcServer) Register() error {
|
|||||||
rsvc := s.rsvc
|
rsvc := s.rsvc
|
||||||
config := s.Options()
|
config := s.Options()
|
||||||
s.RUnlock()
|
s.RUnlock()
|
||||||
|
logger := s.opts.Logger
|
||||||
regFunc := func(service *registry.Service) error {
|
regFunc := func(service *registry.Service) error {
|
||||||
// create registry options
|
// create registry options
|
||||||
rOpts := []registry.RegisterOption{registry.RegisterTTL(config.RegisterTTL)}
|
rOpts := []registry.RegisterOption{registry.RegisterTTL(config.RegisterTTL)}
|
||||||
@ -650,9 +648,7 @@ func (s *rpcServer) Register() error {
|
|||||||
s.RUnlock()
|
s.RUnlock()
|
||||||
|
|
||||||
if !registered {
|
if !registered {
|
||||||
if logger.V(logger.InfoLevel, logger.DefaultLogger) {
|
logger.Logf(log.InfoLevel, "Registry [%s] Registering node: %s", config.Registry.String(), node.Id)
|
||||||
logger.Infof("Registry [%s] Registering node: %s", config.Registry.String(), node.Id)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// register the service
|
// register the service
|
||||||
@ -702,9 +698,7 @@ func (s *rpcServer) Register() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if logger.V(logger.InfoLevel, logger.DefaultLogger) {
|
logger.Logf(log.InfoLevel, "Subscribing to topic: %s", sub.Topic())
|
||||||
logger.Infof("Subscribing to topic: %s", sub.Topic())
|
|
||||||
}
|
|
||||||
s.subscribers[sb] = []broker.Subscriber{sub}
|
s.subscribers[sb] = []broker.Subscriber{sub}
|
||||||
}
|
}
|
||||||
if cacheService {
|
if cacheService {
|
||||||
@ -718,7 +712,7 @@ func (s *rpcServer) Register() error {
|
|||||||
func (s *rpcServer) Deregister() error {
|
func (s *rpcServer) Deregister() error {
|
||||||
var err error
|
var err error
|
||||||
var advt, host, port string
|
var advt, host, port string
|
||||||
|
logger := s.opts.Logger
|
||||||
s.RLock()
|
s.RLock()
|
||||||
config := s.Options()
|
config := s.Options()
|
||||||
s.RUnlock()
|
s.RUnlock()
|
||||||
@ -763,9 +757,7 @@ func (s *rpcServer) Deregister() error {
|
|||||||
Nodes: []*registry.Node{node},
|
Nodes: []*registry.Node{node},
|
||||||
}
|
}
|
||||||
|
|
||||||
if logger.V(logger.InfoLevel, logger.DefaultLogger) {
|
logger.Logf(log.InfoLevel, "Registry [%s] Deregistering node: %s", config.Registry.String(), node.Id)
|
||||||
logger.Infof("Registry [%s] Deregistering node: %s", config.Registry.String(), node.Id)
|
|
||||||
}
|
|
||||||
if err := config.Registry.Deregister(service); err != nil {
|
if err := config.Registry.Deregister(service); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -788,9 +780,7 @@ func (s *rpcServer) Deregister() error {
|
|||||||
|
|
||||||
for sb, subs := range s.subscribers {
|
for sb, subs := range s.subscribers {
|
||||||
for _, sub := range subs {
|
for _, sub := range subs {
|
||||||
if logger.V(logger.InfoLevel, logger.DefaultLogger) {
|
logger.Logf(log.InfoLevel, "Unsubscribing %s from topic: %s", node.Id, sub.Topic())
|
||||||
logger.Infof("Unsubscribing %s from topic: %s", node.Id, sub.Topic())
|
|
||||||
}
|
|
||||||
sub.Unsubscribe()
|
sub.Unsubscribe()
|
||||||
}
|
}
|
||||||
s.subscribers[sb] = nil
|
s.subscribers[sb] = nil
|
||||||
@ -807,7 +797,7 @@ func (s *rpcServer) Start() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
s.RUnlock()
|
s.RUnlock()
|
||||||
|
logger := s.opts.Logger
|
||||||
config := s.Options()
|
config := s.Options()
|
||||||
|
|
||||||
// start listening on the transport
|
// start listening on the transport
|
||||||
@ -816,9 +806,7 @@ func (s *rpcServer) Start() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if logger.V(logger.InfoLevel, logger.DefaultLogger) {
|
logger.Logf(log.InfoLevel, "Transport [%s] Listening on %s", config.Transport.String(), ts.Addr())
|
||||||
logger.Infof("Transport [%s] Listening on %s", config.Transport.String(), ts.Addr())
|
|
||||||
}
|
|
||||||
|
|
||||||
// swap address
|
// swap address
|
||||||
s.Lock()
|
s.Lock()
|
||||||
@ -830,27 +818,19 @@ func (s *rpcServer) Start() error {
|
|||||||
|
|
||||||
// connect to the broker
|
// connect to the broker
|
||||||
if err := config.Broker.Connect(); err != nil {
|
if err := config.Broker.Connect(); err != nil {
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
logger.Logf(log.ErrorLevel, "Broker [%s] connect error: %v", bname, err)
|
||||||
logger.Errorf("Broker [%s] connect error: %v", bname, err)
|
|
||||||
}
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if logger.V(logger.InfoLevel, logger.DefaultLogger) {
|
logger.Logf(log.InfoLevel, "Broker [%s] Connected to %s", bname, config.Broker.Address())
|
||||||
logger.Infof("Broker [%s] Connected to %s", bname, config.Broker.Address())
|
|
||||||
}
|
|
||||||
|
|
||||||
// use RegisterCheck func before register
|
// use RegisterCheck func before register
|
||||||
if err = s.opts.RegisterCheck(s.opts.Context); err != nil {
|
if err = s.opts.RegisterCheck(s.opts.Context); err != nil {
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
logger.Logf(log.ErrorLevel, "Server %s-%s register check error: %s", config.Name, config.Id, err)
|
||||||
logger.Errorf("Server %s-%s register check error: %s", config.Name, config.Id, err)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// announce self to the world
|
// announce self to the world
|
||||||
if err = s.Register(); err != nil {
|
if err = s.Register(); err != nil {
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
logger.Logf(log.ErrorLevel, "Server %s-%s register error: %s", config.Name, config.Id, err)
|
||||||
logger.Errorf("Server %s-%s register error: %s", config.Name, config.Id, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -871,9 +851,7 @@ func (s *rpcServer) Start() error {
|
|||||||
// check the error and backoff
|
// check the error and backoff
|
||||||
default:
|
default:
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
logger.Logf(log.ErrorLevel, "Accept error: %v", err)
|
||||||
logger.Errorf("Accept error: %v", err)
|
|
||||||
}
|
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -906,25 +884,17 @@ func (s *rpcServer) Start() error {
|
|||||||
s.RUnlock()
|
s.RUnlock()
|
||||||
rerr := s.opts.RegisterCheck(s.opts.Context)
|
rerr := s.opts.RegisterCheck(s.opts.Context)
|
||||||
if rerr != nil && registered {
|
if rerr != nil && registered {
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
logger.Logf(log.ErrorLevel, "Server %s-%s register check error: %s, deregister it", config.Name, config.Id, err)
|
||||||
logger.Errorf("Server %s-%s register check error: %s, deregister it", config.Name, config.Id, err)
|
|
||||||
}
|
|
||||||
// deregister self in case of error
|
// deregister self in case of error
|
||||||
if err := s.Deregister(); err != nil {
|
if err := s.Deregister(); err != nil {
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
logger.Logf(log.ErrorLevel, "Server %s-%s deregister error: %s", config.Name, config.Id, err)
|
||||||
logger.Errorf("Server %s-%s deregister error: %s", config.Name, config.Id, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if rerr != nil && !registered {
|
} else if rerr != nil && !registered {
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
logger.Logf(log.ErrorLevel, "Server %s-%s register check error: %s", config.Name, config.Id, err)
|
||||||
logger.Errorf("Server %s-%s register check error: %s", config.Name, config.Id, err)
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := s.Register(); err != nil {
|
if err := s.Register(); err != nil {
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
logger.Logf(log.ErrorLevel, "Server %s-%s register error: %s", config.Name, config.Id, err)
|
||||||
logger.Errorf("Server %s-%s register error: %s", config.Name, config.Id, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// wait for exit
|
// wait for exit
|
||||||
case ch = <-s.exit:
|
case ch = <-s.exit:
|
||||||
@ -940,9 +910,7 @@ func (s *rpcServer) Start() error {
|
|||||||
if registered {
|
if registered {
|
||||||
// deregister self
|
// deregister self
|
||||||
if err := s.Deregister(); err != nil {
|
if err := s.Deregister(); err != nil {
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
logger.Logf(log.ErrorLevel, "Server %s-%s deregister error: %s", config.Name, config.Id, err)
|
||||||
logger.Errorf("Server %s-%s deregister error: %s", config.Name, config.Id, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -958,14 +926,10 @@ func (s *rpcServer) Start() error {
|
|||||||
// close transport listener
|
// close transport listener
|
||||||
ch <- ts.Close()
|
ch <- ts.Close()
|
||||||
|
|
||||||
if logger.V(logger.InfoLevel, logger.DefaultLogger) {
|
logger.Logf(log.InfoLevel, "Broker [%s] Disconnected from %s", bname, config.Broker.Address())
|
||||||
logger.Infof("Broker [%s] Disconnected from %s", bname, config.Broker.Address())
|
|
||||||
}
|
|
||||||
// disconnect the broker
|
// disconnect the broker
|
||||||
if err := config.Broker.Disconnect(); err != nil {
|
if err := config.Broker.Disconnect(); err != nil {
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
logger.Logf(log.ErrorLevel, "Broker [%s] Disconnect error: %v", bname, err)
|
||||||
logger.Errorf("Broker [%s] Disconnect error: %v", bname, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// swap back address
|
// swap back address
|
||||||
|
@ -65,7 +65,7 @@ func (r *rpcStream) Recv(msg interface{}) error {
|
|||||||
if len(req.Error) > 0 {
|
if len(req.Error) > 0 {
|
||||||
// Check the client closed the stream
|
// Check the client closed the stream
|
||||||
switch req.Error {
|
switch req.Error {
|
||||||
case lastStreamResponseError.Error():
|
case errLastStreamResponse.Error():
|
||||||
// discard body
|
// discard body
|
||||||
r.Unlock()
|
r.Unlock()
|
||||||
r.codec.ReadBody(nil)
|
r.codec.ReadBody(nil)
|
||||||
|
@ -8,8 +8,9 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
|
||||||
"go-micro.dev/v4/codec"
|
"go-micro.dev/v4/codec"
|
||||||
"go-micro.dev/v4/logger"
|
log "go-micro.dev/v4/logger"
|
||||||
"go-micro.dev/v4/registry"
|
"go-micro.dev/v4/registry"
|
||||||
signalutil "go-micro.dev/v4/util/signal"
|
signalutil "go-micro.dev/v4/util/signal"
|
||||||
)
|
)
|
||||||
@ -116,7 +117,6 @@ type Stream interface {
|
|||||||
// func (g *Greeter) Hello(context, request, response) error {
|
// func (g *Greeter) Hello(context, request, response) error {
|
||||||
// return nil
|
// return nil
|
||||||
// }
|
// }
|
||||||
//
|
|
||||||
type Handler interface {
|
type Handler interface {
|
||||||
Name() string
|
Name() string
|
||||||
Handler() interface{}
|
Handler() interface{}
|
||||||
@ -184,7 +184,6 @@ func NewSubscriber(topic string, h interface{}, opts ...SubscriberOption) Subscr
|
|||||||
// func (f *Foo) Bar(ctx, req, rsp) error {
|
// func (f *Foo) Bar(ctx, req, rsp) error {
|
||||||
// return nil
|
// return nil
|
||||||
// }
|
// }
|
||||||
//
|
|
||||||
func NewHandler(h interface{}, opts ...HandlerOption) Handler {
|
func NewHandler(h interface{}, opts ...HandlerOption) Handler {
|
||||||
return DefaultServer.NewHandler(h, opts...)
|
return DefaultServer.NewHandler(h, opts...)
|
||||||
}
|
}
|
||||||
@ -210,27 +209,21 @@ func Run() error {
|
|||||||
|
|
||||||
ch := make(chan os.Signal, 1)
|
ch := make(chan os.Signal, 1)
|
||||||
signal.Notify(ch, signalutil.Shutdown()...)
|
signal.Notify(ch, signalutil.Shutdown()...)
|
||||||
|
DefaultServer.Options().Logger.Logf(log.InfoLevel, "Received signal %s", <-ch)
|
||||||
|
|
||||||
if logger.V(logger.InfoLevel, logger.DefaultLogger) {
|
|
||||||
logger.Infof("Received signal %s", <-ch)
|
|
||||||
}
|
|
||||||
return Stop()
|
return Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start starts the default server
|
// Start starts the default server
|
||||||
func Start() error {
|
func Start() error {
|
||||||
config := DefaultServer.Options()
|
config := DefaultServer.Options()
|
||||||
if logger.V(logger.InfoLevel, logger.DefaultLogger) {
|
config.Logger.Logf(log.InfoLevel, "Starting server %s id %s", config.Name, config.Id)
|
||||||
logger.Infof("Starting server %s id %s", config.Name, config.Id)
|
|
||||||
}
|
|
||||||
return DefaultServer.Start()
|
return DefaultServer.Start()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop stops the default server
|
// Stop stops the default server
|
||||||
func Stop() error {
|
func Stop() error {
|
||||||
if logger.V(logger.InfoLevel, logger.DefaultLogger) {
|
DefaultServer.Options().Logger.Logf(log.InfoLevel, "Stopping server")
|
||||||
logger.Infof("Stopping server")
|
|
||||||
}
|
|
||||||
return DefaultServer.Stop()
|
return DefaultServer.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
14
service.go
14
service.go
@ -7,7 +7,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"go-micro.dev/v4/client"
|
"go-micro.dev/v4/client"
|
||||||
"go-micro.dev/v4/logger"
|
log "go-micro.dev/v4/logger"
|
||||||
"go-micro.dev/v4/server"
|
"go-micro.dev/v4/server"
|
||||||
"go-micro.dev/v4/store"
|
"go-micro.dev/v4/store"
|
||||||
"go-micro.dev/v4/util/cmd"
|
"go-micro.dev/v4/util/cmd"
|
||||||
@ -58,14 +58,14 @@ func (s *service) Init(opts ...Option) {
|
|||||||
cmd.Store(&s.opts.Store),
|
cmd.Store(&s.opts.Store),
|
||||||
cmd.Profile(&s.opts.Profile),
|
cmd.Profile(&s.opts.Profile),
|
||||||
); err != nil {
|
); err != nil {
|
||||||
logger.Fatal(err)
|
s.opts.Logger.Log(log.FatalLevel, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Explicitly set the table name to the service name
|
// Explicitly set the table name to the service name
|
||||||
name := s.opts.Cmd.App().Name
|
name := s.opts.Cmd.App().Name
|
||||||
err := s.opts.Store.Init(store.Table(name))
|
err := s.opts.Store.Init(store.Table(name))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatal(err)
|
s.opts.Logger.Log(log.FatalLevel, err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -125,6 +125,8 @@ func (s *service) Stop() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) Run() (err error) {
|
func (s *service) Run() (err error) {
|
||||||
|
logger := s.opts.Logger
|
||||||
|
|
||||||
// exit when help flag is provided
|
// exit when help flag is provided
|
||||||
for _, v := range os.Args[1:] {
|
for _, v := range os.Args[1:] {
|
||||||
if v == "-h" || v == "--help" {
|
if v == "-h" || v == "--help" {
|
||||||
@ -145,14 +147,12 @@ func (s *service) Run() (err error) {
|
|||||||
defer func() {
|
defer func() {
|
||||||
err = s.opts.Profile.Stop()
|
err = s.opts.Profile.Stop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(err)
|
logger.Log(log.ErrorLevel, err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
if logger.V(logger.InfoLevel, logger.DefaultLogger) {
|
logger.Logf(log.InfoLevel, "Starting [service] %s", s.Name())
|
||||||
logger.Infof("Starting [service] %s", s.Name())
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = s.Start(); err != nil {
|
if err = s.Start(); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"go-micro.dev/v4/client"
|
"go-micro.dev/v4/client"
|
||||||
|
"go-micro.dev/v4/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Options contains configuration for the Store
|
// Options contains configuration for the Store
|
||||||
@ -21,6 +22,8 @@ type Options struct {
|
|||||||
Context context.Context
|
Context context.Context
|
||||||
// Client to use for RPC
|
// Client to use for RPC
|
||||||
Client client.Client
|
Client client.Client
|
||||||
|
// Logger is the underline logger
|
||||||
|
Logger logger.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
// Option sets values in Options
|
// Option sets values in Options
|
||||||
@ -63,6 +66,13 @@ func WithClient(c client.Client) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithLogger sets the underline logger
|
||||||
|
func WithLogger(l logger.Logger) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.Logger = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ReadOptions configures an individual Read operation
|
// ReadOptions configures an individual Read operation
|
||||||
type ReadOptions struct {
|
type ReadOptions struct {
|
||||||
Database, Table string
|
Database, Table string
|
||||||
|
@ -4,6 +4,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"go-micro.dev/v4/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Nodes sets the addresses to use
|
// Nodes sets the addresses to use
|
||||||
@ -47,3 +49,10 @@ func WithContext(c context.Context) Option {
|
|||||||
o.Context = c
|
o.Context = c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithLogger sets the underline logger
|
||||||
|
func WithLogger(l logger.Logger) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.Logger = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -6,6 +6,8 @@ import (
|
|||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"errors"
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"go-micro.dev/v4/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -41,6 +43,7 @@ type Options struct {
|
|||||||
Prefix string
|
Prefix string
|
||||||
TLSConfig *tls.Config
|
TLSConfig *tls.Config
|
||||||
Context context.Context
|
Context context.Context
|
||||||
|
Logger logger.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
type Option func(o *Options)
|
type Option func(o *Options)
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"go-micro.dev/v4/codec"
|
"go-micro.dev/v4/codec"
|
||||||
|
"go-micro.dev/v4/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Options struct {
|
type Options struct {
|
||||||
@ -27,6 +28,8 @@ type Options struct {
|
|||||||
// Other options for implementations of the interface
|
// Other options for implementations of the interface
|
||||||
// can be stored in a context
|
// can be stored in a context
|
||||||
Context context.Context
|
Context context.Context
|
||||||
|
// Logger is the underline logger
|
||||||
|
Logger logger.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
type DialOptions struct {
|
type DialOptions struct {
|
||||||
@ -104,6 +107,13 @@ func WithTimeout(d time.Duration) DialOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithLogger sets the underline logger
|
||||||
|
func WithLogger(l logger.Logger) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.Logger = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NetListener Set net.Listener for httpTransport
|
// NetListener Set net.Listener for httpTransport
|
||||||
func NetListener(customListener net.Listener) ListenOption {
|
func NetListener(customListener net.Listener) ListenOption {
|
||||||
return func(o *ListenOptions) {
|
return func(o *ListenOptions) {
|
||||||
|
@ -3,13 +3,12 @@ package file
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"go-micro.dev/v4/client"
|
"go-micro.dev/v4/client"
|
||||||
|
"go-micro.dev/v4/logger"
|
||||||
proto "go-micro.dev/v4/util/file/proto"
|
proto "go-micro.dev/v4/util/file/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -145,7 +144,7 @@ func (c *fc) DownloadAt(filename, saveFile string, blockId int) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if stat.Type == "Directory" {
|
if stat.Type == "Directory" {
|
||||||
return errors.New(fmt.Sprintf("%s is directory.", filename))
|
return fmt.Errorf("%s is directory", filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
blocks := int(stat.Size / blockSize)
|
blocks := int(stat.Size / blockSize)
|
||||||
@ -153,7 +152,7 @@ func (c *fc) DownloadAt(filename, saveFile string, blockId int) error {
|
|||||||
blocks += 1
|
blocks += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("Download %s in %d blocks\n", filename, blocks-blockId)
|
logger.Logf(logger.InfoLevel, "Download %s in %d blocks\n", filename, blocks-blockId)
|
||||||
|
|
||||||
file, err := os.OpenFile(saveFile, os.O_CREATE|os.O_WRONLY, 0666)
|
file, err := os.OpenFile(saveFile, os.O_CREATE|os.O_WRONLY, 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -176,14 +175,14 @@ func (c *fc) DownloadAt(filename, saveFile string, blockId int) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if i%((blocks-blockId)/100+1) == 0 {
|
if i%((blocks-blockId)/100+1) == 0 {
|
||||||
log.Printf("Downloading %s [%d/%d] blocks", filename, i-blockId+1, blocks-blockId)
|
logger.Logf(logger.InfoLevel, "Downloading %s [%d/%d] blocks", filename, i-blockId+1, blocks-blockId)
|
||||||
}
|
}
|
||||||
|
|
||||||
if rerr == io.EOF {
|
if rerr == io.EOF {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.Printf("Download %s completed", filename)
|
logger.Logf(logger.InfoLevel, "Download %s completed", filename)
|
||||||
|
|
||||||
c.Close(sessionId)
|
c.Close(sessionId)
|
||||||
|
|
||||||
|
@ -6,11 +6,12 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
|
||||||
"go-micro.dev/v4/errors"
|
"go-micro.dev/v4/errors"
|
||||||
"go-micro.dev/v4/logger"
|
log "go-micro.dev/v4/logger"
|
||||||
"go-micro.dev/v4/server"
|
"go-micro.dev/v4/server"
|
||||||
proto "go-micro.dev/v4/util/file/proto"
|
proto "go-micro.dev/v4/util/file/proto"
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewHandler is a handler that can be registered with a micro Server
|
// NewHandler is a handler that can be registered with a micro Server
|
||||||
@ -20,6 +21,7 @@ func NewHandler(readDir string) proto.FileHandler {
|
|||||||
session: &session{
|
session: &session{
|
||||||
files: make(map[int64]*os.File),
|
files: make(map[int64]*os.File),
|
||||||
},
|
},
|
||||||
|
logger: log.DefaultLogger,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,6 +33,7 @@ func RegisterHandler(s server.Server, readDir string) {
|
|||||||
type handler struct {
|
type handler struct {
|
||||||
readDir string
|
readDir string
|
||||||
session *session
|
session *session
|
||||||
|
logger log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handler) Open(ctx context.Context, req *proto.OpenRequest, rsp *proto.OpenResponse) error {
|
func (h *handler) Open(ctx context.Context, req *proto.OpenRequest, rsp *proto.OpenResponse) error {
|
||||||
@ -47,14 +50,14 @@ func (h *handler) Open(ctx context.Context, req *proto.OpenRequest, rsp *proto.O
|
|||||||
rsp.Id = h.session.Add(file)
|
rsp.Id = h.session.Add(file)
|
||||||
rsp.Result = true
|
rsp.Result = true
|
||||||
|
|
||||||
logger.Debugf("Open %s, sessionId=%d", req.Filename, rsp.Id)
|
h.logger.Logf(log.DebugLevel, "Open %s, sessionId=%d", req.Filename, rsp.Id)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handler) Close(ctx context.Context, req *proto.CloseRequest, rsp *proto.CloseResponse) error {
|
func (h *handler) Close(ctx context.Context, req *proto.CloseRequest, rsp *proto.CloseResponse) error {
|
||||||
h.session.Delete(req.Id)
|
h.session.Delete(req.Id)
|
||||||
logger.Debugf("Close sessionId=%d", req.Id)
|
h.logger.Logf(log.DebugLevel, "Close sessionId=%d", req.Id)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +76,7 @@ func (h *handler) Stat(ctx context.Context, req *proto.StatRequest, rsp *proto.S
|
|||||||
}
|
}
|
||||||
|
|
||||||
rsp.LastModified = fi.ModTime().Unix()
|
rsp.LastModified = fi.ModTime().Unix()
|
||||||
logger.Debugf("Stat %s, %#v", req.Filename, rsp)
|
h.logger.Logf(log.DebugLevel, "Stat %s, %#v", req.Filename, rsp)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -97,7 +100,7 @@ func (h *handler) Read(ctx context.Context, req *proto.ReadRequest, rsp *proto.R
|
|||||||
rsp.Size = int64(n)
|
rsp.Size = int64(n)
|
||||||
rsp.Data = rsp.Data[:n]
|
rsp.Data = rsp.Data[:n]
|
||||||
|
|
||||||
logger.Debugf("Read sessionId=%d, Offset=%d, n=%d", req.Id, req.Offset, rsp.Size)
|
h.logger.Logf(log.DebugLevel, "Read sessionId=%d, Offset=%d, n=%d", req.Id, req.Offset, rsp.Size)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -112,7 +115,7 @@ func (h *handler) Write(ctx context.Context, req *proto.WriteRequest, rsp *proto
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Debugf("Write sessionId=%d, Offset=%d, n=%d", req.Id, req.Offset)
|
h.logger.Logf(log.DebugLevel, "Write sessionId=%d, Offset=%d, n=%d", req.Id, req.Offset)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,10 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"go-micro.dev/v4/logger"
|
||||||
"go-micro.dev/v4/metadata"
|
"go-micro.dev/v4/metadata"
|
||||||
"go-micro.dev/v4/registry"
|
"go-micro.dev/v4/registry"
|
||||||
"go-micro.dev/v4/selector"
|
"go-micro.dev/v4/selector"
|
||||||
@ -39,7 +39,7 @@ func WriteInternalServerError(w http.ResponseWriter, err error) {
|
|||||||
"error": err.Error(),
|
"error": err.Error(),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
logger.Log(logger.ErrorLevel, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Write(w, "application/json", 500, string(rawBody))
|
Write(w, "application/json", 500, string(rawBody))
|
||||||
|
@ -20,7 +20,7 @@ var (
|
|||||||
// path to kubernetes service account token
|
// path to kubernetes service account token
|
||||||
serviceAccountPath = "/var/run/secrets/kubernetes.io/serviceaccount"
|
serviceAccountPath = "/var/run/secrets/kubernetes.io/serviceaccount"
|
||||||
// ErrReadNamespace is returned when the names could not be read from service account
|
// ErrReadNamespace is returned when the names could not be read from service account
|
||||||
ErrReadNamespace = errors.New("Could not read namespace from service account secret")
|
ErrReadNamespace = errors.New("could not read namespace from service account secret")
|
||||||
// DefaultImage is default micro image
|
// DefaultImage is default micro image
|
||||||
DefaultImage = "micro/go-micro"
|
DefaultImage = "micro/go-micro"
|
||||||
// DefaultNamespace is the default k8s namespace
|
// DefaultNamespace is the default k8s namespace
|
||||||
@ -228,7 +228,7 @@ func (c *client) Watch(r *Resource, opts ...WatchOption) (Watcher, error) {
|
|||||||
// NewService returns default micro kubernetes service definition
|
// NewService returns default micro kubernetes service definition
|
||||||
func NewService(name, version, typ, namespace string) *Service {
|
func NewService(name, version, typ, namespace string) *Service {
|
||||||
if logger.V(logger.TraceLevel, logger.DefaultLogger) {
|
if logger.V(logger.TraceLevel, logger.DefaultLogger) {
|
||||||
logger.Tracef("kubernetes default service: name: %s, version: %s", name, version)
|
logger.Logf(logger.TraceLevel, "kubernetes default service: name: %s, version: %s", name, version)
|
||||||
}
|
}
|
||||||
|
|
||||||
Labels := map[string]string{
|
Labels := map[string]string{
|
||||||
@ -271,7 +271,7 @@ func NewService(name, version, typ, namespace string) *Service {
|
|||||||
// NewService returns default micro kubernetes deployment definition
|
// NewService returns default micro kubernetes deployment definition
|
||||||
func NewDeployment(name, version, typ, namespace string) *Deployment {
|
func NewDeployment(name, version, typ, namespace string) *Deployment {
|
||||||
if logger.V(logger.TraceLevel, logger.DefaultLogger) {
|
if logger.V(logger.TraceLevel, logger.DefaultLogger) {
|
||||||
logger.Tracef("kubernetes default deployment: name: %s, version: %s", name, version)
|
logger.Logf(logger.TraceLevel, "kubernetes default deployment: name: %s, version: %s", name, version)
|
||||||
}
|
}
|
||||||
|
|
||||||
Labels := map[string]string{
|
Labels := map[string]string{
|
||||||
|
@ -3,7 +3,6 @@ package mdns
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@ -12,6 +11,8 @@ import (
|
|||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
"golang.org/x/net/ipv4"
|
"golang.org/x/net/ipv4"
|
||||||
"golang.org/x/net/ipv6"
|
"golang.org/x/net/ipv6"
|
||||||
|
|
||||||
|
"go-micro.dev/v4/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ServiceEntry is returned after we query for a service
|
// ServiceEntry is returned after we query for a service
|
||||||
@ -146,7 +147,7 @@ func Listen(entries chan<- *ServiceEntry, exit chan struct{}) error {
|
|||||||
m.SetQuestion(e.Name, dns.TypePTR)
|
m.SetQuestion(e.Name, dns.TypePTR)
|
||||||
m.RecursionDesired = false
|
m.RecursionDesired = false
|
||||||
if err := client.sendQuery(m); err != nil {
|
if err := client.sendQuery(m); err != nil {
|
||||||
log.Printf("[ERR] mdns: Failed to query instance %s: %v", e.Name, err)
|
logger.Logf(logger.ErrorLevel, "[mdns] failed to query instance %s: %v", e.Name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -184,7 +185,7 @@ func newClient() (*client, error) {
|
|||||||
uconn4, err4 := net.ListenUDP("udp4", &net.UDPAddr{IP: net.IPv4zero, Port: 0})
|
uconn4, err4 := net.ListenUDP("udp4", &net.UDPAddr{IP: net.IPv4zero, Port: 0})
|
||||||
uconn6, err6 := net.ListenUDP("udp6", &net.UDPAddr{IP: net.IPv6zero, Port: 0})
|
uconn6, err6 := net.ListenUDP("udp6", &net.UDPAddr{IP: net.IPv6zero, Port: 0})
|
||||||
if err4 != nil && err6 != nil {
|
if err4 != nil && err6 != nil {
|
||||||
log.Printf("[ERR] mdns: Failed to bind to udp port: %v %v", err4, err6)
|
logger.Logf(logger.ErrorLevel, "[mdns] failed to bind to udp port: %v %v", err4, err6)
|
||||||
}
|
}
|
||||||
|
|
||||||
if uconn4 == nil && uconn6 == nil {
|
if uconn4 == nil && uconn6 == nil {
|
||||||
@ -202,7 +203,7 @@ func newClient() (*client, error) {
|
|||||||
mconn4, err4 := net.ListenUDP("udp4", mdnsWildcardAddrIPv4)
|
mconn4, err4 := net.ListenUDP("udp4", mdnsWildcardAddrIPv4)
|
||||||
mconn6, err6 := net.ListenUDP("udp6", mdnsWildcardAddrIPv6)
|
mconn6, err6 := net.ListenUDP("udp6", mdnsWildcardAddrIPv6)
|
||||||
if err4 != nil && err6 != nil {
|
if err4 != nil && err6 != nil {
|
||||||
log.Printf("[ERR] mdns: Failed to bind to udp port: %v %v", err4, err6)
|
logger.Logf(logger.ErrorLevel, "[mdns] failed to bind to udp port: %v %v", err4, err6)
|
||||||
}
|
}
|
||||||
|
|
||||||
if mconn4 == nil && mconn6 == nil {
|
if mconn4 == nil && mconn6 == nil {
|
||||||
@ -239,7 +240,7 @@ func newClient() (*client, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(ifaces) == errCount1 && len(ifaces) == errCount2 {
|
if len(ifaces) == errCount1 && len(ifaces) == errCount2 {
|
||||||
return nil, fmt.Errorf("Failed to join multicast group on all interfaces!")
|
return nil, fmt.Errorf("failed to join multicast group on all interfaces")
|
||||||
}
|
}
|
||||||
|
|
||||||
c := &client{
|
c := &client{
|
||||||
@ -375,7 +376,7 @@ func (c *client) query(params *QueryParam) error {
|
|||||||
m.SetQuestion(inp.Name, inp.Type)
|
m.SetQuestion(inp.Name, inp.Type)
|
||||||
m.RecursionDesired = false
|
m.RecursionDesired = false
|
||||||
if err := c.sendQuery(m); err != nil {
|
if err := c.sendQuery(m); err != nil {
|
||||||
log.Printf("[ERR] mdns: Failed to query instance %s: %v", inp.Name, err)
|
logger.Logf(logger.ErrorLevel, "[mdns] failed to query instance %s: %v", inp.Name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case <-params.Context.Done():
|
case <-params.Context.Done():
|
||||||
|
@ -10,6 +10,7 @@ import "github.com/miekg/dns"
|
|||||||
// register only the wrapped instance with the server.
|
// register only the wrapped instance with the server.
|
||||||
//
|
//
|
||||||
// Example usage:
|
// Example usage:
|
||||||
|
//
|
||||||
// service := &mdns.DNSSDService{
|
// service := &mdns.DNSSDService{
|
||||||
// MDNSService: &mdns.MDNSService{
|
// MDNSService: &mdns.MDNSService{
|
||||||
// Instance: "My Foobar Service",
|
// Instance: "My Foobar Service",
|
||||||
|
@ -45,9 +45,12 @@ func Unmarshal(dst interface{}, query string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ToJSON will turn a query string like:
|
// ToJSON will turn a query string like:
|
||||||
|
//
|
||||||
// cat=1&bar%5Bone%5D%5Btwo%5D=2&bar[one][red]=112
|
// cat=1&bar%5Bone%5D%5Btwo%5D=2&bar[one][red]=112
|
||||||
|
//
|
||||||
// Into a JSON object with all the data merged as nicely as
|
// Into a JSON object with all the data merged as nicely as
|
||||||
// possible. Eg the example above would output:
|
// possible. Eg the example above would output:
|
||||||
|
//
|
||||||
// {"bar":{"one":{"two":2,"red":112}}}
|
// {"bar":{"one":{"two":2,"red":112}}}
|
||||||
func ToJSON(query string) ([]byte, error) {
|
func ToJSON(query string) ([]byte, error) {
|
||||||
var (
|
var (
|
||||||
@ -65,6 +68,7 @@ func ToJSON(query string) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// queryToMap turns something like a[b][c]=4 into
|
// queryToMap turns something like a[b][c]=4 into
|
||||||
|
//
|
||||||
// map[string]interface{}{
|
// map[string]interface{}{
|
||||||
// "a": map[string]interface{}{
|
// "a": map[string]interface{}{
|
||||||
// "b": map[string]interface{}{
|
// "b": map[string]interface{}{
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"go-micro.dev/v4"
|
"go-micro.dev/v4"
|
||||||
|
"go-micro.dev/v4/logger"
|
||||||
"go-micro.dev/v4/registry"
|
"go-micro.dev/v4/registry"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -37,6 +38,7 @@ type Options struct {
|
|||||||
|
|
||||||
Registry registry.Registry
|
Registry registry.Registry
|
||||||
Service micro.Service
|
Service micro.Service
|
||||||
|
Logger logger.Logger
|
||||||
|
|
||||||
Secure bool
|
Secure bool
|
||||||
TLSConfig *tls.Config
|
TLSConfig *tls.Config
|
||||||
@ -63,6 +65,7 @@ func newOptions(opts ...Option) Options {
|
|||||||
Service: micro.NewService(),
|
Service: micro.NewService(),
|
||||||
Context: context.TODO(),
|
Context: context.TODO(),
|
||||||
Signal: true,
|
Signal: true,
|
||||||
|
Logger: logger.DefaultLogger,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
@ -257,3 +260,10 @@ func HandleSignal(b bool) Option {
|
|||||||
o.Signal = b
|
o.Signal = b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Logger sets the underline logger
|
||||||
|
func Logger(l logger.Logger) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.Logger = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -13,8 +13,10 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
|
|
||||||
"go-micro.dev/v4"
|
"go-micro.dev/v4"
|
||||||
"go-micro.dev/v4/logger"
|
|
||||||
|
log "go-micro.dev/v4/logger"
|
||||||
"go-micro.dev/v4/registry"
|
"go-micro.dev/v4/registry"
|
||||||
maddr "go-micro.dev/v4/util/addr"
|
maddr "go-micro.dev/v4/util/addr"
|
||||||
"go-micro.dev/v4/util/backoff"
|
"go-micro.dev/v4/util/backoff"
|
||||||
@ -54,11 +56,13 @@ func (s *service) genSrv() *registry.Service {
|
|||||||
var port string
|
var port string
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
logger := s.opts.Logger
|
||||||
|
|
||||||
// default host:port
|
// default host:port
|
||||||
if len(s.opts.Address) > 0 {
|
if len(s.opts.Address) > 0 {
|
||||||
host, port, err = net.SplitHostPort(s.opts.Address)
|
host, port, err = net.SplitHostPort(s.opts.Address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatal(err)
|
logger.Log(log.FatalLevel, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,13 +72,13 @@ func (s *service) genSrv() *registry.Service {
|
|||||||
if len(s.opts.Advertise) > 0 {
|
if len(s.opts.Advertise) > 0 {
|
||||||
host, port, err = net.SplitHostPort(s.opts.Advertise)
|
host, port, err = net.SplitHostPort(s.opts.Advertise)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatal(err)
|
logger.Log(log.FatalLevel, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addr, err := maddr.Extract(host)
|
addr, err := maddr.Extract(host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatal(err)
|
logger.Log(log.FatalLevel, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.Count(addr, ":") > 0 {
|
if strings.Count(addr, ":") > 0 {
|
||||||
@ -120,6 +124,9 @@ func (s *service) register() error {
|
|||||||
if s.srv == nil {
|
if s.srv == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger := s.opts.Logger
|
||||||
|
|
||||||
// default to service registry
|
// default to service registry
|
||||||
r := s.opts.Service.Client().Options().Registry
|
r := s.opts.Service.Client().Options().Registry
|
||||||
// switch to option if specified
|
// switch to option if specified
|
||||||
@ -134,9 +141,7 @@ func (s *service) register() error {
|
|||||||
|
|
||||||
// use RegisterCheck func before register
|
// use RegisterCheck func before register
|
||||||
if err := s.opts.RegisterCheck(s.opts.Context); err != nil {
|
if err := s.opts.RegisterCheck(s.opts.Context); err != nil {
|
||||||
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
logger.Logf(log.ErrorLevel, "Server %s-%s register check error: %s", s.opts.Name, s.opts.Id, err)
|
||||||
logger.Errorf("Server %s-%s register check error: %s", s.opts.Name, s.opts.Id, err)
|
|
||||||
}
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,6 +200,8 @@ func (s *service) start() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger := s.opts.Logger
|
||||||
|
|
||||||
s.opts.Address = l.Addr().String()
|
s.opts.Address = l.Addr().String()
|
||||||
srv := s.genSrv()
|
srv := s.genSrv()
|
||||||
srv.Endpoints = s.srv.Endpoints
|
srv.Endpoints = s.srv.Endpoints
|
||||||
@ -221,9 +228,7 @@ func (s *service) start() error {
|
|||||||
if s.static {
|
if s.static {
|
||||||
_, err := os.Stat(static)
|
_, err := os.Stat(static)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if logger.V(logger.InfoLevel, logger.DefaultLogger) {
|
logger.Logf(log.InfoLevel, "Enabling static file serving from %s", static)
|
||||||
logger.Infof("Enabling static file serving from %s", static)
|
|
||||||
}
|
|
||||||
s.mux.Handle("/", http.FileServer(http.Dir(static)))
|
s.mux.Handle("/", http.FileServer(http.Dir(static)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -255,9 +260,7 @@ func (s *service) start() error {
|
|||||||
ch <- l.Close()
|
ch <- l.Close()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if logger.V(logger.InfoLevel, logger.DefaultLogger) {
|
logger.Logf(log.InfoLevel, "Listening on %v", l.Addr().String())
|
||||||
logger.Infof("Listening on %v", l.Addr().String())
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,9 +282,7 @@ func (s *service) stop() error {
|
|||||||
s.exit <- ch
|
s.exit <- ch
|
||||||
s.running = false
|
s.running = false
|
||||||
|
|
||||||
if logger.V(logger.InfoLevel, logger.DefaultLogger) {
|
s.opts.Logger.Log(log.InfoLevel, "Stopping")
|
||||||
logger.Info("Stopping")
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, fn := range s.opts.AfterStop {
|
for _, fn := range s.opts.AfterStop {
|
||||||
if err := fn(); err != nil {
|
if err := fn(); err != nil {
|
||||||
@ -473,6 +474,7 @@ func (s *service) Run() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger := s.opts.Logger
|
||||||
// start the profiler
|
// start the profiler
|
||||||
if s.opts.Service.Options().Profile != nil {
|
if s.opts.Service.Options().Profile != nil {
|
||||||
// to view mutex contention
|
// to view mutex contention
|
||||||
@ -485,7 +487,7 @@ func (s *service) Run() error {
|
|||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := s.opts.Service.Options().Profile.Stop(); err != nil {
|
if err := s.opts.Service.Options().Profile.Stop(); err != nil {
|
||||||
logger.Error(err)
|
logger.Log(log.ErrorLevel, err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
@ -505,14 +507,10 @@ func (s *service) Run() error {
|
|||||||
select {
|
select {
|
||||||
// wait on kill signal
|
// wait on kill signal
|
||||||
case sig := <-ch:
|
case sig := <-ch:
|
||||||
if logger.V(logger.InfoLevel, logger.DefaultLogger) {
|
logger.Logf(log.InfoLevel, "Received signal %s", sig)
|
||||||
logger.Infof("Received signal %s", sig)
|
|
||||||
}
|
|
||||||
// wait on context cancel
|
// wait on context cancel
|
||||||
case <-s.opts.Context.Done():
|
case <-s.opts.Context.Done():
|
||||||
if logger.V(logger.InfoLevel, logger.DefaultLogger) {
|
logger.Log(log.InfoLevel, "Received context shutdown")
|
||||||
logger.Info("Received context shutdown")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// exit reg loop
|
// exit reg loop
|
||||||
|
@ -57,14 +57,14 @@ func testFunc() {
|
|||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
err := s.Run()
|
err := s.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("micro run error: %v", err)
|
logger.Logf(logger.ErrorLevel, "micro run error: %v", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
err := w.Run()
|
err := w.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("web run error: %v", err)
|
logger.Logf(logger.ErrorLevel, "web run error: %v", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user