diff --git a/cmd/spicedb/main.go b/cmd/spicedb/main.go index e46ad5c605..8f62e556f0 100644 --- a/cmd/spicedb/main.go +++ b/cmd/spicedb/main.go @@ -14,6 +14,7 @@ import ( "google.golang.org/grpc/balancer" consistentbalancer "github.com/authzed/spicedb/pkg/balancer" + "github.com/authzed/spicedb/pkg/cmd/devsvc" "github.com/authzed/spicedb/pkg/cmd/root" "github.com/authzed/spicedb/pkg/cmd/version" ) @@ -55,10 +56,13 @@ func main() { version.RegisterVersionFlags(versionCmd) rootCmd.AddCommand(versionCmd) + devSvcCmd := devsvc.NewCommand(rootCmd.Use) + devsvc.RegisterFlags(devSvcCmd) + rootCmd.AddCommand(devSvcCmd) + registerServeCmd(rootCmd) registerMigrateCmd(rootCmd) registerHeadCmd(rootCmd) - registerDeveloperServiceCmd(rootCmd) registerTestserverCmd(rootCmd) _ = rootCmd.Execute() diff --git a/pkg/cmd/defaults.go b/pkg/cmd/defaults.go new file mode 100644 index 0000000000..baf7ff3094 --- /dev/null +++ b/pkg/cmd/defaults.go @@ -0,0 +1,29 @@ +package cmd + +import ( + "net/http" + "net/http/pprof" + + "github.com/jzelinskie/cobrautil" + "github.com/prometheus/client_golang/prometheus/promhttp" + "github.com/rs/zerolog" +) + +func DefaultPreRunE(programName string) cobrautil.CobraRunFunc { + return cobrautil.CommandStack( + cobrautil.SyncViperPreRunE(programName), + cobrautil.ZeroLogPreRunE("log", zerolog.InfoLevel), + cobrautil.OpenTelemetryPreRunE("otel", zerolog.InfoLevel), + ) +} + +func MetricsHandler() http.Handler { + mux := http.NewServeMux() + mux.Handle("/metrics", promhttp.Handler()) + mux.HandleFunc("/debug/pprof/", pprof.Index) + mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline) + mux.HandleFunc("/debug/pprof/profile", pprof.Profile) + mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol) + mux.HandleFunc("/debug/pprof/trace", pprof.Trace) + return mux +} diff --git a/cmd/spicedb/developer.go b/pkg/cmd/devsvc/devsvc.go similarity index 79% rename from cmd/spicedb/developer.go rename to pkg/cmd/devsvc/devsvc.go index 1d834bd13d..2241392493 100644 --- a/cmd/spicedb/developer.go +++ b/pkg/cmd/devsvc/devsvc.go @@ -1,4 +1,4 @@ -package main +package devsvc import ( "context" @@ -9,6 +9,7 @@ import ( v0 "github.com/authzed/authzed-go/proto/authzed/api/v0" "github.com/authzed/grpcutil" + defaults "github.com/authzed/spicedb/pkg/cmd" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/credentials" grpczerolog "github.com/grpc-ecosystem/go-grpc-middleware/providers/zerolog/v2" @@ -27,32 +28,32 @@ import ( v0svc "github.com/authzed/spicedb/internal/services/v0" ) -func registerDeveloperServiceCmd(rootCmd *cobra.Command) { - developerServiceCmd := &cobra.Command{ +func RegisterFlags(cmd *cobra.Command) { + cobrautil.RegisterGrpcServerFlags(cmd.Flags(), "grpc", "gRPC", ":50051", true) + cobrautil.RegisterHttpServerFlags(cmd.Flags(), "metrics", "metrics", ":9090", true) + cobrautil.RegisterHttpServerFlags(cmd.Flags(), "http", "download", ":8443", false) + + cmd.Flags().String("share-store", "inmemory", "kind of share store to use") + cmd.Flags().String("share-store-salt", "", "salt for share store hashing") + cmd.Flags().String("s3-access-key", "", "s3 access key for s3 share store") + cmd.Flags().String("s3-secret-key", "", "s3 secret key for s3 share store") + cmd.Flags().String("s3-bucket", "", "s3 bucket name for s3 share store") + cmd.Flags().String("s3-endpoint", "", "s3 endpoint for s3 share store") + cmd.Flags().String("s3-region", "auto", "s3 region for s3 share store") +} + +func NewCommand(programName string) *cobra.Command { + return &cobra.Command{ Use: "serve-devtools", Short: "runs the developer tools service", Long: "Serves the authzed.api.v0.DeveloperService which is used for development tooling such as the Authzed Playground", - PreRunE: defaultPreRunE, - Run: developerServiceRun, + PreRunE: defaults.DefaultPreRunE(programName), + Run: runfunc, Args: cobra.ExactArgs(0), } - - cobrautil.RegisterGrpcServerFlags(developerServiceCmd.Flags(), "grpc", "gRPC", ":50051", true) - cobrautil.RegisterHttpServerFlags(developerServiceCmd.Flags(), "metrics", "metrics", ":9090", true) - cobrautil.RegisterHttpServerFlags(developerServiceCmd.Flags(), "http", "download", ":8443", false) - - developerServiceCmd.Flags().String("share-store", "inmemory", "kind of share store to use") - developerServiceCmd.Flags().String("share-store-salt", "", "salt for share store hashing") - developerServiceCmd.Flags().String("s3-access-key", "", "s3 access key for s3 share store") - developerServiceCmd.Flags().String("s3-secret-key", "", "s3 secret key for s3 share store") - developerServiceCmd.Flags().String("s3-bucket", "", "s3 bucket name for s3 share store") - developerServiceCmd.Flags().String("s3-endpoint", "", "s3 endpoint for s3 share store") - developerServiceCmd.Flags().String("s3-region", "auto", "s3 region for s3 share store") - - rootCmd.AddCommand(developerServiceCmd) } -func developerServiceRun(cmd *cobra.Command, args []string) { +func runfunc(cmd *cobra.Command, args []string) { grpcServer, err := cobrautil.GrpcServerFromFlags(cmd, "grpc", grpc.ChainUnaryInterceptor( grpclog.UnaryServerInterceptor(grpczerolog.InterceptorLogger(log.Logger)), otelgrpc.UnaryServerInterceptor(), @@ -77,7 +78,7 @@ func developerServiceRun(cmd *cobra.Command, args []string) { // Start the metrics endpoint. metricsSrv := cobrautil.HttpServerFromFlags(cmd, "metrics") - metricsSrv.Handler = metricsHandler() + metricsSrv.Handler = defaults.MetricsHandler() go func() { if err := cobrautil.HttpListenFromFlags(cmd, "metrics", metricsSrv, zerolog.InfoLevel); err != nil { log.Fatal().Err(err).Msg("failed while serving metrics")