diff --git a/cmd/servicechecker/main.go b/cmd/servicechecker/main.go index 26470b1..30a991e 100644 --- a/cmd/servicechecker/main.go +++ b/cmd/servicechecker/main.go @@ -117,60 +117,61 @@ func main() { 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 - } - - 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 - } - - 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.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.Addr)) - err = grpcconn.Call(ctx, l, c, task.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.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() + } + }) + } } } diff --git a/pkg/config/config.go b/pkg/config/config.go index 81ef84e..1f1708d 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -24,14 +24,33 @@ type Check struct { Interval mtime.Duration `json:"interval,omitempty" yaml:"interval,omitempty"` } +type HTTPConfig struct { + Endpoint string `json:"endpoint,omitempty" yaml:"endpoint,omitempty"` + Data string `json:"data,omitempty" yaml:"data,omitempty"` + Addr string `json:"addr,omitempty" yaml:"addr,omitempty"` + OpenAPI string `json:"openapi,omitempty" yaml:"openapi,omitempty"` + Method string `json:"method,omitempty" yaml:"method,omitempty"` +} + +type GRPCConfig struct { + Endpoint string `json:"endpoint,omitempty" yaml:"endpoint,omitempty"` + Data string `json:"data,omitempty" yaml:"data,omitempty"` + Addr string `json:"addr,omitempty" yaml:"addr,omitempty"` + Protoset string `json:"protoset,omitempty" yaml:"protoset,omitempty"` +} + +type GraphQLConfig struct { + Endpoint string `json:"endpoint,omitempty" yaml:"endpoint,omitempty"` + Data string `json:"data,omitempty" yaml:"data,omitempty"` + Addr string `json:"addr,omitempty" yaml:"addr,omitempty"` +} + type Task struct { + HTTP *HTTPConfig `json:"http,omitempty" yaml:"http,omitempty"` + GRPC *GRPCConfig `json:"grpc,omitempty" yaml:"grpc,omitempty"` + GraphQL *GraphQLConfig `json:"graphql,omitempty" yaml:"graphql"` 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"` }