diff --git a/.gitignore b/.gitignore index 1d21693..c523002 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ go.work config.yaml servicechecker *.protoset +authn.yaml diff --git a/cmd/servicechecker/main.go b/cmd/servicechecker/main.go index 30a991e..5c4508d 100644 --- a/cmd/servicechecker/main.go +++ b/cmd/servicechecker/main.go @@ -7,21 +7,27 @@ import ( "os/signal" "time" + openapi_v3 "github.com/google/gnostic/openapiv3" grpccli "go.unistack.org/micro-client-grpc/v3" + httpcli "go.unistack.org/micro-client-http/v3" jsoncodec "go.unistack.org/micro-codec-json/v3" jsonpbcodec "go.unistack.org/micro-codec-jsonpb/v3" protocodec "go.unistack.org/micro-codec-proto/v3" victoriametrics "go.unistack.org/micro-meter-victoriametrics/v3" + codecpb "go.unistack.org/micro-proto/v3/codec" httpsrv "go.unistack.org/micro-server-http/v3" healthhandler "go.unistack.org/micro-server-http/v3/handler/health" meterhandler "go.unistack.org/micro-server-http/v3/handler/meter" "go.unistack.org/micro/v3/client" + "go.unistack.org/micro/v3/codec" + "go.unistack.org/micro/v3/logger" "go.unistack.org/micro/v3/logger/slog" "go.unistack.org/micro/v3/meter" "go.unistack.org/micro/v3/semconv" "go.unistack.org/micro/v3/server" "go.unistack.org/servicechecker/pkg/config" "go.unistack.org/servicechecker/pkg/grpcconn" + "go.unistack.org/servicechecker/pkg/httpconn" "go.unistack.org/servicechecker/pkg/scheduler" "google.golang.org/protobuf/reflect/protodesc" "google.golang.org/protobuf/reflect/protoreflect" @@ -29,6 +35,8 @@ import ( "google.golang.org/protobuf/types/dynamicpb" ) +var clients = make(map[string]client.Client) + func main() { ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill) defer stop() @@ -88,7 +96,6 @@ func main() { l.Fatal(ctx, "failed to start http server", err) } - clients := make(map[string]client.Client) gcli := grpccli.NewClient( client.Codec("application/json", jsonpbcodec.NewCodec()), client.Codec("application/grpc", protocodec.NewCodec()), @@ -98,83 +105,193 @@ func main() { client.Retries(0), // client.TLSConfig(&tls.Config{InsecureSkipVerify: true}), ) - protosetBuf, _ := os.ReadFile("card.protoset") - fdset := &descriptorpb.FileDescriptorSet{} - if err = protocodec.NewCodec().Unmarshal(protosetBuf, fdset); err != nil { - l.Fatal(ctx, "failed to unmarshal protoset file", err) + if err = gcli.Init(); err != nil { + l.Fatal(ctx, "failed to init grpc client", err) } - - pfileoptions := protodesc.FileOptions{AllowUnresolvable: true} - pfiles, err := pfileoptions.NewFiles(fdset) - if err != nil { - l.Fatal(ctx, "failed to use protoset file", err) - } - - gcli.Init() clients["grpc"] = gcli + hcli := httpcli.NewClient( + client.Codec("text/html", codec.NewCodec()), + client.Codec("text/plain", codec.NewCodec()), + client.Codec("application/json", jsonpbcodec.NewCodec()), + client.ContentType("application/json"), + client.Retries(0), + // client.TLSConfig(&tls.Config{InsecureSkipVerify: true}), + ) + if err = hcli.Init(); err != nil { + l.Fatal(ctx, "failed to init http client", err) + } + clients["http"] = hcli + for _, check := range cfg.Checks { l.Info(ctx, fmt.Sprintf("check %#+v", check)) + if !check.Active { + continue + } for _, task := range check.Tasks { l.Info(ctx, fmt.Sprintf("task %#+v", task)) - if task.GRPC != nil { - c, ok := clients["grpc"] - if !ok { - l.Error(ctx, fmt.Sprintf("unknown client %s", "grpc")) - continue - } - - pkg, svc, mth := grpcconn.ServiceMethod(task.GRPC.Endpoint) - pdesc, err := pfiles.FindDescriptorByName(protoreflect.FullName(pkg + "." + svc)) - if err != nil { - l.Error(ctx, "failed to find service "+pkg+"."+svc) - continue - } - - sdesc, ok := pdesc.(protoreflect.ServiceDescriptor) - if !ok { - l.Error(ctx, "failed to find service "+pkg+"."+svc) - continue - } - - mdesc := sdesc.Methods().ByName(protoreflect.Name(mth)) - if mdesc == nil { - l.Error(ctx, "failed to find method "+mth) - continue - } - - req := dynamicpb.NewMessageType(mdesc.Input()).New() - rsp := dynamicpb.NewMessageType(mdesc.Output()).New() - - if err = jsonpbcodec.NewCodec().Unmarshal([]byte(task.GRPC.Data), req); err != nil { - l.Error(ctx, "failed to unmarshal", err) - continue - } - - treq := c.NewRequest(pkg, svc+"."+mth, req) - - sch.NewJob(time.Duration(check.Interval), func() { - labels := []string{"check", check.Name, "task", task.Name, "service", svc, "endpoint", mth} - m.Counter(semconv.ClientRequestInflight, labels...).Inc() - ts := time.Now() - l.Info(ctx, fmt.Sprintf("try to call %s.%s via %s", svc, mth, task.GRPC.Addr)) - err = grpcconn.Call(ctx, l, c, task.GRPC.Addr, time.Duration(task.Timeout), - treq, - rsp) - te := time.Since(ts) - m.Summary(semconv.ClientRequestLatencyMicroseconds, labels...).Update(te.Seconds()) - m.Histogram(semconv.ClientRequestDurationSeconds, labels...).Update(te.Seconds()) - m.Counter(semconv.ClientRequestInflight, labels...).Dec() - if err != nil { - m.Counter(semconv.ClientRequestTotal, append(labels, "status", "failure")...).Inc() - } else { - m.Counter(semconv.ClientRequestTotal, append(labels, "status", "success")...).Inc() - } - }) + if !task.Active { + continue } + + var fn any + var args []any + + switch { + case task.GRPC != nil: + fn, args, err = newGRPCTask(ctx, l, m, check.Name, task) + case task.HTTP != nil: + fn, args, err = newHTTPTask(ctx, l, m, check.Name, task) + } + if err != nil { + l.Error(ctx, "failed to create task", err) + continue + } + l.Info(ctx, fmt.Sprintf("add new task %v", fn)) + sch.NewJob(time.Duration(check.Interval), fn, args...) } } <-ctx.Done() l.Info(ctx, "exiting") } + +func newHTTPTask(ctx context.Context, l logger.Logger, m meter.Meter, check string, task *config.Task) (any, []any, error) { + var err error + + openapiBuf, err := os.ReadFile(task.HTTP.OpenAPI) + if err != nil { + l.Error(ctx, "failed to unmarshal openapi file", err) + return nil, nil, err + } + + doc, err := openapi_v3.ParseDocument(openapiBuf) + if err != nil { + l.Error(ctx, "failed to unmarshal openapi file", err) + return nil, nil, err + } + _ = doc + + c, ok := clients["http"] + if !ok { + err = fmt.Errorf("unknown client http") + l.Error(ctx, "failed to get client", err) + return nil, nil, err + } + + errmap := make(map[string]interface{}, 1) + errmap["default"] = &codecpb.Frame{} + opts := []client.CallOption{ + httpcli.ErrorMap(errmap), + httpcli.Method(task.HTTP.Method), + httpcli.Path(task.HTTP.Endpoint), + // client.WithContentType("application/json"), + } + rsp := &codecpb.Frame{} + + treq := c.NewRequest(task.Name, task.Name, &codecpb.Frame{Data: []byte(task.HTTP.Data)}) + + fn := func() { + labels := []string{"check", check, "task", task.Name, "service", task.Name, "endpoint", task.Name} + m.Counter(semconv.ClientRequestInflight, labels...).Inc() + ts := time.Now() + l.Info(ctx, fmt.Sprintf("try to call %s.%s via %s", task.Name, task.Name, task.HTTP.Addr)) + err = httpconn.Call(ctx, l, c, task.HTTP.Addr, time.Duration(task.Timeout), + treq, + rsp, + opts...) + te := time.Since(ts) + m.Summary(semconv.ClientRequestLatencyMicroseconds, labels...).Update(te.Seconds()) + m.Histogram(semconv.ClientRequestDurationSeconds, labels...).Update(te.Seconds()) + m.Counter(semconv.ClientRequestInflight, labels...).Dec() + if err != nil { + m.Counter(semconv.ClientRequestTotal, append(labels, "status", "failure")...).Inc() + } else { + m.Counter(semconv.ClientRequestTotal, append(labels, "status", "success")...).Inc() + } + } + + return fn, nil, nil +} + +func newGRPCTask(ctx context.Context, l logger.Logger, m meter.Meter, check string, task *config.Task) (any, []any, error) { + var err error + + protosetBuf, err := os.ReadFile(task.GRPC.Protoset) + if err != nil { + l.Error(ctx, "failed to unmarshal protoset file", err) + return nil, nil, err + } + + fdset := &descriptorpb.FileDescriptorSet{} + if err = protocodec.NewCodec().Unmarshal(protosetBuf, fdset); err != nil { + l.Error(ctx, "failed to unmarshal protoset file", err) + return nil, nil, err + } + + pfileoptions := protodesc.FileOptions{AllowUnresolvable: true} + pfiles, err := pfileoptions.NewFiles(fdset) + if err != nil { + l.Error(ctx, "failed to use protoset file", err) + return nil, nil, err + } + + c, ok := clients["grpc"] + if !ok { + err = fmt.Errorf("unknown client grpc") + l.Error(ctx, "failed to get client", err) + return nil, nil, err + } + + pkg, svc, mth := grpcconn.ServiceMethod(task.GRPC.Endpoint) + pdesc, err := pfiles.FindDescriptorByName(protoreflect.FullName(pkg + "." + svc)) + if err != nil { + l.Error(ctx, "failed to find service "+pkg+"."+svc) + return nil, nil, err + } + + sdesc, ok := pdesc.(protoreflect.ServiceDescriptor) + if !ok { + err = fmt.Errorf("failed to find service " + pkg + "." + svc) + l.Error(ctx, "unable to find service in protoset", err) + return nil, nil, err + } + + mdesc := sdesc.Methods().ByName(protoreflect.Name(mth)) + if mdesc == nil { + err = fmt.Errorf("unknown method " + mth) + l.Error(ctx, "failed to find method", err) + return nil, nil, err + } + + req := dynamicpb.NewMessageType(mdesc.Input()).New() + rsp := dynamicpb.NewMessageType(mdesc.Output()).New() + + if err = jsonpbcodec.NewCodec().Unmarshal([]byte(task.GRPC.Data), req); err != nil { + l.Error(ctx, "failed to unmarshal", err) + return nil, nil, err + } + + treq := c.NewRequest(pkg, svc+"."+mth, req) + + fn := func() { + labels := []string{"check", check, "task", task.Name, "service", svc, "endpoint", mth} + m.Counter(semconv.ClientRequestInflight, labels...).Inc() + ts := time.Now() + l.Info(ctx, fmt.Sprintf("try to call %s.%s via %s", svc, mth, task.GRPC.Addr)) + err = grpcconn.Call(ctx, l, c, task.GRPC.Addr, time.Duration(task.Timeout), + treq, + rsp) + te := time.Since(ts) + m.Summary(semconv.ClientRequestLatencyMicroseconds, labels...).Update(te.Seconds()) + m.Histogram(semconv.ClientRequestDurationSeconds, labels...).Update(te.Seconds()) + m.Counter(semconv.ClientRequestInflight, labels...).Dec() + if err != nil { + m.Counter(semconv.ClientRequestTotal, append(labels, "status", "failure")...).Inc() + } else { + m.Counter(semconv.ClientRequestTotal, append(labels, "status", "success")...).Inc() + } + } + + return fn, nil, nil +} diff --git a/go.mod b/go.mod index b816794..8f318bb 100644 --- a/go.mod +++ b/go.mod @@ -4,26 +4,28 @@ go 1.23.3 require ( github.com/go-co-op/gocron/v2 v2.12.3 + github.com/google/gnostic v0.7.0 github.com/google/uuid v1.6.0 go.unistack.org/micro-client-grpc/v3 v3.11.10 + go.unistack.org/micro-client-http/v3 v3.9.14 go.unistack.org/micro-codec-json/v3 v3.10.1 go.unistack.org/micro-codec-jsonpb/v3 v3.10.3 go.unistack.org/micro-codec-proto/v3 v3.10.2 go.unistack.org/micro-codec-yaml/v3 v3.10.2 go.unistack.org/micro-meter-victoriametrics/v3 v3.8.9 + go.unistack.org/micro-proto/v3 v3.4.1 go.unistack.org/micro-server-http/v3 v3.11.33 go.unistack.org/micro/v3 v3.10.100 google.golang.org/protobuf v1.35.2 ) require ( + github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect github.com/jonboulle/clockwork v0.4.0 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect github.com/valyala/fastrand v1.1.0 // indirect github.com/valyala/histogram v1.2.0 // indirect go.unistack.org/metrics v0.0.1 // indirect - go.unistack.org/micro-client-http/v3 v3.9.14 // indirect - go.unistack.org/micro-proto/v3 v3.4.1 // indirect golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect golang.org/x/net v0.30.0 // indirect golang.org/x/sys v0.27.0 // indirect diff --git a/go.sum b/go.sum index 865e444..25f5a47 100644 --- a/go.sum +++ b/go.sum @@ -710,12 +710,18 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= +github.com/google/gnostic v0.7.0 h1:d7EpuFp8vVdML+y0JJJYiKeOLjKTdH/GvVkLOBWqJpw= +github.com/google/gnostic v0.7.0/go.mod h1:IAcUyMl6vtC95f60EZ8oXyqTsOersP6HbwjeG7EyDPM= +github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 h1:0VpGH+cDhbDtdcweoyCVsF3fhN8kejK6rFe/2FFX2nU= +github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49/go.mod h1:BkkQ4L1KS1xMt2aWSPStnn55ChGC0DPOn2FQYj+f25M= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -892,8 +898,6 @@ go.unistack.org/metrics v0.0.1 h1:sCnGO059ZccGC/D34iRH121eSk+7ci5+OY9cl5K7GKY= go.unistack.org/metrics v0.0.1/go.mod h1:1FY4R7EKJa9Oz2D6wlGScNerpl6igRs9Cx/3et4Rgs4= go.unistack.org/micro-client-grpc/v3 v3.11.10 h1:hbqCL4JLbTtPN1ee16EK6LqTbeIr6HynJJjCRWAu2kk= go.unistack.org/micro-client-grpc/v3 v3.11.10/go.mod h1:S1AIA2n3GZVxKdjpMcLJSXwBpC/OzAX91D6KxFzqjbc= -go.unistack.org/micro-client-http/v3 v3.9.13 h1:KUWkDfA7p+dZEIgSsWuPjfj6yeX8rrnHYwrEjdAZvmU= -go.unistack.org/micro-client-http/v3 v3.9.13/go.mod h1:WmrmeWWKohGn5ODrCr53wUp4pe/ZE6UYdXh7ECgpOH4= go.unistack.org/micro-client-http/v3 v3.9.14 h1:26BiMcUlGpxpN+S84tpAeMetbd9rbBd+IILq1CkFP2U= go.unistack.org/micro-client-http/v3 v3.9.14/go.mod h1:KS6qxpxGDQmcszBaJpidc1KOr528QflEKoGopl0qYJ8= go.unistack.org/micro-codec-json/v3 v3.10.1 h1:FzmWTfoE2JlzU4EyNqQcsE2bbSOgUKEyNc+GE3aFl9E= @@ -1486,8 +1490,6 @@ google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go. google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234015-3fc162c6f38a/go.mod h1:xURIpW9ES5+/GZhnV6beoEtxQrnkRGIfP5VQG2tCBLc= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 h1:QCqS/PdaHTSWGvupk2F/ehwHtGc0/GYkT+3GAcR1CCc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= google.golang.org/genproto/googleapis/rpc v0.0.0-20241113202542-65e8d215514f h1:C1QccEa9kUwvMgEUORqQD9S17QesQijxjZ84sO82mfo= google.golang.org/genproto/googleapis/rpc v0.0.0-20241113202542-65e8d215514f/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -1531,8 +1533,6 @@ google.golang.org/grpc v1.52.3/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5v google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= -google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= -google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0= google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= @@ -1555,8 +1555,6 @@ google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= -google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= -google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1569,6 +1567,7 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/pkg/config/config.go b/pkg/config/config.go index 1f1708d..d42d9cf 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -22,6 +22,7 @@ type Check struct { Tasks []*Task `json:"tasks,omitempty" yaml:"tasks,omitempty"` Timeout mtime.Duration `json:"timeout,omitempty" yaml:"timeout,omitempty"` Interval mtime.Duration `json:"interval,omitempty" yaml:"interval,omitempty"` + Active bool `json:"active,omitempty" yaml:"active,omitempty"` } type HTTPConfig struct { @@ -52,6 +53,7 @@ type Task struct { TLSVerify *bool `json:"tls_verify,omitempty" yaml:"tls_verify,omitempty"` Name string `json:"name,omitempty" yaml:"name,omitempty"` Timeout mtime.Duration `json:"timeout,omitempty" yaml:"timeout,omitempty"` + Active bool `json:"active,omitempty" yaml:"active,omitempty"` } func (cfg *Config) Parse(r io.Reader) error { diff --git a/pkg/grpcconn/grpcconn.go b/pkg/grpcconn/grpcconn.go index 7865972..58b4eed 100644 --- a/pkg/grpcconn/grpcconn.go +++ b/pkg/grpcconn/grpcconn.go @@ -10,7 +10,7 @@ import ( "go.unistack.org/micro/v3/logger" ) -func Call(ctx context.Context, l logger.Logger, c client.Client, addr string, td time.Duration, req client.Request, rsp interface{}) error { +func Call(ctx context.Context, l logger.Logger, c client.Client, addr string, td time.Duration, req client.Request, rsp interface{}, opts ...client.CallOption) error { var err error uid, err := uuid.NewRandom() if err != nil { diff --git a/pkg/httpconn/httpconn.go b/pkg/httpconn/httpconn.go new file mode 100644 index 0000000..a53e9ce --- /dev/null +++ b/pkg/httpconn/httpconn.go @@ -0,0 +1,30 @@ +package httpconn + +import ( + "context" + "time" + + "github.com/google/uuid" + "go.unistack.org/micro/v3/client" + "go.unistack.org/micro/v3/logger" +) + +func Call(ctx context.Context, l logger.Logger, c client.Client, addr string, td time.Duration, req client.Request, rsp interface{}, opts ...client.CallOption) error { + var err error + uid, err := uuid.NewRandom() + if err != nil { + l.Error(ctx, "failed to generate x-request-id", err) + return err + } + + err = c.Call(ctx, req, rsp, + client.WithAddress(addr), + client.WithRequestTimeout(td), + // client.WithContentType("application/json"), + ) + if err != nil { + l.Error(ctx, "call failed", "x-request-id", uid.String(), err) + return err + } + return nil +}