diff --git a/cmd/servicechecker/main.go b/cmd/servicechecker/main.go index 670873d..4be58c7 100644 --- a/cmd/servicechecker/main.go +++ b/cmd/servicechecker/main.go @@ -40,14 +40,18 @@ func main() { l.Fatal(ctx, "failed to open config", err) } + l.Info(ctx, "scheduler: create") s, err := scheduler.NewScheduler() if err != nil { l.Fatal(ctx, "failed to create scheduler", err) } + l.Info(ctx, "scheduler: created") + l.Info(ctx, "scheduler: try to start") if err = s.Start(); err != nil { l.Fatal(ctx, "failed to start scheduler", err) } + l.Info(ctx, "scheduler: starting") clients := make(map[string]client.Client) gcli := grpccli.NewClient( @@ -74,43 +78,48 @@ func main() { gcli.Init() clients["grpc"] = gcli - for _, svc := range cfg.Services { - c, ok := clients[svc.Type] - if !ok { - l.Error(ctx, fmt.Sprintf("unknown client %s", svc.Type)) - continue - } - pdesc, err := pfiles.FindDescriptorByName("card_proto.CardService") - if err != nil { - l.Error(ctx, "failed to find service "+svc.Name) - continue - } + for _, check := range cfg.Checks { + l.Info(ctx, fmt.Sprintf("check %#+v", check)) + for _, task := range check.Tasks { + l.Info(ctx, fmt.Sprintf("task %#+v", task)) + c, ok := clients[task.Type] + if !ok { + l.Error(ctx, fmt.Sprintf("unknown client %s", task.Type)) + continue + } - sdesc, ok := pdesc.(protoreflect.ServiceDescriptor) - if !ok { - l.Error(ctx, "failed to find service "+svc.Name) - continue - } + pkg, svc, mth := grpcconn.ServiceMethod(task.Endpoint) + pdesc, err := pfiles.FindDescriptorByName(protoreflect.FullName(pkg + "." + svc)) + if err != nil { + l.Error(ctx, "failed to find service "+pkg+"."+svc) + continue + } - for _, check := range svc.Checks { - mdesc := sdesc.Methods().ByName(protoreflect.Name(check.Name)) + 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 "+check.Name) + 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(check.Data), req); err != nil { + if err = jsonpbcodec.NewCodec().Unmarshal([]byte(task.Data), req); err != nil { l.Error(ctx, "failed to unmarshal", err) continue } - labels := []string{"service", svc.Name, "endpoint", check.Name} + labels := []string{"check", check.Name, "task", task.Name, "service", svc, "endpoint", mth} m.Counter(semconv.ClientRequestInflight, labels...).Inc() ts := time.Now() - err = grpcconn.Call(ctx, l, c, svc.Addr, time.Duration(check.Timeout), - c.NewRequest("card_proto", "CardService."+check.Name, req), + l.Info(ctx, fmt.Sprintf("try to call %s.%s via %s", svc, mth, task.Addr)) + err = grpcconn.Call(ctx, l, c, task.Addr, time.Duration(task.Timeout), + c.NewRequest(pkg, svc+"."+mth, req), rsp) te := time.Since(ts) m.Summary(semconv.ClientRequestLatencyMicroseconds, labels...).Update(te.Seconds()) @@ -121,6 +130,7 @@ func main() { } else { m.Counter(semconv.ClientRequestTotal, append(labels, "status", "success")...).Inc() } + } } diff --git a/pkg/config/config.go b/pkg/config/config.go index 6375259..681c6f7 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -8,26 +8,27 @@ import ( ) type Config struct { - Services []*Service `json:"services,omitempty" yaml:"services,omitempty"` -} - -type Service struct { - Name string `json:"name,omitempty" yaml:"name,omitempty"` - Addr string `json:"addr,omitempty" yaml:"addr,omitempty"` - Type string `json:"type,omitempty" yaml:"type,omitempty"` - Reflection bool `json:"reflection,omitempty" yaml:"reflection,omitempty"` - Protoset string `json:"protoset,omitempty" yaml:"protoset,omitempty"` - Checks []*Check `json:"checks,omitempty" yaml:"checks,omitempty"` - TLSVerify *bool `json:"tls_verify,omitempty" yaml:"tls_verify,omitempty"` + Checks []*Check `json:"checks,omitempty" yaml:"checks,omitempty"` } type Check struct { Name string `json:"name,omitempty" yaml:"name,omitempty"` - Data string `json:"data,omitempty" yaml:"data,omitempty"` + 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"` } +type Task struct { + TLSVerify *bool `json:"tls_verify,omitempty" yaml:"tls_verify,omitempty"` + Endpoint string `json:"endpoint,omitempty" yaml:"endpoint,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Data string `json:"data,omitempty" yaml:"data,omitempty"` + Addr string `json:"addr,omitempty" yaml:"addr,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + Protoset string `json:"protoset,omitempty" yaml:"protoset,omitempty"` + Timeout mtime.Duration `json:"timeout,omitempty" yaml:"timeout,omitempty"` +} + func (cfg *Config) Parse(r io.Reader) error { buf, err := io.ReadAll(r) if err != nil { diff --git a/pkg/grpcconn/grpcconn.go b/pkg/grpcconn/grpcconn.go index 2071a57..7865972 100644 --- a/pkg/grpcconn/grpcconn.go +++ b/pkg/grpcconn/grpcconn.go @@ -2,6 +2,7 @@ package grpcconn import ( "context" + "strings" "time" "github.com/google/uuid" @@ -28,3 +29,9 @@ func Call(ctx context.Context, l logger.Logger, c client.Client, addr string, td } return nil } + +func ServiceMethod(method string) (string, string, string) { + idx1 := strings.LastIndex(method, ".") + idx2 := strings.Index(method[:idx1], ".") + return method[:idx2], method[idx2+1 : idx1], method[idx1+1:] +}