From c5e43bd0a933ba8080cb8904c64f8780264b219f Mon Sep 17 00:00:00 2001 From: Joakim Olsson Date: Fri, 16 Dec 2022 13:33:29 +0000 Subject: [PATCH 1/2] chore(deps): bump github.com/getsentry/sentry-go from 0.14.0 to 0.16.0 Bumps [github.com/getsentry/sentry-go](https://github.com/getsentry/sentry-go) from 0.14.0 to 0.16.0. - [Release notes](https://github.com/getsentry/sentry-go/releases) - [Changelog](https://github.com/getsentry/sentry-go/blob/master/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-go/compare/v0.14.0...v0.16.0) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index b62c521..db1b282 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/Khan/genqlient v0.5.0 github.com/alecthomas/kong v0.7.1 github.com/apex/log v1.9.0 - github.com/getsentry/sentry-go v0.14.0 + github.com/getsentry/sentry-go v0.16.0 github.com/jmoiron/sqlx v1.3.5 github.com/rs/cors v1.8.2 github.com/sparetimecoders/goamqp v0.1.1 diff --git a/go.sum b/go.sum index 707c4b2..2695c21 100644 --- a/go.sum +++ b/go.sum @@ -49,8 +49,8 @@ github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8 github.com/evanphx/json-patch/v5 v5.1.0 h1:B0aXl1o/1cP8NbviYiBMkcHBtUjIJ1/Ccg6b+SwCLQg= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/getsentry/sentry-go v0.14.0 h1:rlOBkuFZRKKdUnKO+0U3JclRDQKlRu5vVQtkWSQvC70= -github.com/getsentry/sentry-go v0.14.0/go.mod h1:RZPJKSw+adu8PBNygiri/A98FqVr2HtRckJk9XVxJ9I= +github.com/getsentry/sentry-go v0.16.0 h1:owk+S+5XcgJLlGR/3+3s6N4d+uKwqYvh/eS0AIMjPWo= +github.com/getsentry/sentry-go v0.16.0/go.mod h1:ZXCloQLj0pG7mja5NK6NPf2V4A88YJ4pNlc2mOHwh6Y= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= -- 2.52.0 From 577ad601ca7840b53531af2bdd7cd2a93f8b79f6 Mon Sep 17 00:00:00 2001 From: Joakim Olsson Date: Fri, 16 Dec 2022 16:02:16 +0100 Subject: [PATCH 2/2] feat: add Sentry setup --- cmd/service/service.go | 69 ++++++++++++++++++++++++++++++++++++------ k8s/secrets.yaml | 2 ++ 2 files changed, 61 insertions(+), 10 deletions(-) diff --git a/cmd/service/service.go b/cmd/service/service.go index 1990798..37963aa 100644 --- a/cmd/service/service.go +++ b/cmd/service/service.go @@ -9,12 +9,14 @@ import ( "reflect" "sync" "syscall" + "time" "github.com/99designs/gqlgen/graphql/handler" "github.com/99designs/gqlgen/graphql/playground" "github.com/alecthomas/kong" "github.com/apex/log" "github.com/apex/log/handlers/json" + "github.com/getsentry/sentry-go" sentryhttp "github.com/getsentry/sentry-go/http" "github.com/rs/cors" "github.com/sparetimecoders/goamqp" @@ -30,21 +32,30 @@ import ( "gitlab.com/unboundsoftware/schemas/store" ) -var CLI struct { +type CLI struct { AmqpURL string `name:"amqp-url" env:"AMQP_URL" help:"URL to use to connect to RabbitMQ" default:"amqp://user:password@localhost:5672/"` Port int `name:"port" env:"PORT" help:"Listen-port for GraphQL API" default:"8080"` APIKey string `name:"api-key" env:"API_KEY" help:"The API-key that is required"` LogLevel string `name:"log-level" env:"LOG_LEVEL" help:"The level of logging to use (debug, info, warn, error, fatal)" default:"info"` DatabaseURL string `name:"postgres-url" env:"POSTGRES_URL" help:"URL to use to connect to Postgres" default:"postgres://postgres:postgres@:5432/schemas?sslmode=disable"` DatabaseDriverName string `name:"db-driver" env:"DB_DRIVER" help:"Driver to use to connect to db" default:"postgres"` + SentryConfig } +type SentryConfig struct { + DSN string `name:"sentry-dsn" env:"SENTRY_DSN" help:"Sentry dsn" default:""` + Environment string `name:"sentry-environment" env:"SENTRY_ENVIRONMENT" help:"Sentry environment" default:"development"` +} + +var buildVersion = "none" + const serviceName = "schemas" func main() { - _ = kong.Parse(&CLI) + var cli CLI + _ = kong.Parse(&cli) log.SetHandler(json.New(os.Stdout)) - log.SetLevelFromString(CLI.LogLevel) + log.SetLevelFromString(cli.LogLevel) logger := log.WithField("service", serviceName) closeEvents := make(chan error) @@ -52,16 +63,22 @@ func main() { closeEvents, logger, ConnectAMQP, + cli, ); err != nil { logger.WithError(err).Error("process error") } } -func start(closeEvents chan error, logger *log.Entry, connectToAmqpFunc func(url string) (Connection, error)) error { +func start(closeEvents chan error, logger *log.Entry, connectToAmqpFunc func(url string) (Connection, error), cli CLI) error { + if err := setupSentry(logger, cli.SentryConfig); err != nil { + return err + } + defer sentry.Flush(2 * time.Second) + rootCtx, rootCancel := context.WithCancel(context.Background()) defer rootCancel() - db, err := store.SetupDB(CLI.DatabaseDriverName, CLI.DatabaseURL) + db, err := store.SetupDB(cli.DatabaseDriverName, cli.DatabaseURL) if err != nil { return fmt.Errorf("failed to setup DB: %v", err) } @@ -85,7 +102,7 @@ func start(closeEvents chan error, logger *log.Entry, connectToAmqpFunc func(url return fmt.Errorf("failed to create event publisher: %v", err) } amqp.New(eventPublisher) - conn, err := connectToAmqpFunc(CLI.AmqpURL) + conn, err := connectToAmqpFunc(cli.AmqpURL) if err != nil { return fmt.Errorf("failed to connect to AMQP: %v", err) } @@ -121,7 +138,7 @@ func start(closeEvents chan error, logger *log.Entry, connectToAmqpFunc func(url logger.Info("Started") mux := http.NewServeMux() - httpSrv := &http.Server{Addr: fmt.Sprintf(":%d", CLI.Port), Handler: mux} + httpSrv := &http.Server{Addr: fmt.Sprintf(":%d", cli.Port), Handler: mux} wg := sync.WaitGroup{} @@ -179,7 +196,7 @@ func start(closeEvents chan error, logger *log.Entry, connectToAmqpFunc func(url Resolvers: resolver, Complexity: generated.ComplexityRoot{}, } - apiKeyMiddleware := middleware.NewApiKey(CLI.APIKey, logger) + apiKeyMiddleware := middleware.NewApiKey(cli.APIKey, logger) config.Directives.HasApiKey = apiKeyMiddleware.Directive srv := handler.NewDefaultServer(generated.NewExecutableSchema( config, @@ -187,10 +204,10 @@ func start(closeEvents chan error, logger *log.Entry, connectToAmqpFunc func(url sentryHandler := sentryhttp.New(sentryhttp.Options{Repanic: true}) mux.Handle("/", sentryHandler.HandleFunc(playground.Handler("GraphQL playground", "/query"))) - mux.Handle("/health", sentryHandler.HandleFunc(healthFunc)) + mux.Handle("/health", http.HandlerFunc(healthFunc)) mux.Handle("/query", cors.AllowAll().Handler(sentryHandler.Handle(apiKeyMiddleware.Handler(srv)))) - logger.Infof("connect to http://localhost:%d/ for GraphQL playground", CLI.Port) + logger.Infof("connect to http://localhost:%d/ for GraphQL playground", cli.Port) if err := httpSrv.ListenAndServe(); err != nil { logger.WithError(err).Error("listen http") @@ -206,6 +223,38 @@ func healthFunc(w http.ResponseWriter, _ *http.Request) { _, _ = w.Write([]byte("OK")) } +func setupSentry(logger log.Interface, args SentryConfig) error { + if args.Environment == "" { + return fmt.Errorf("no Sentry environment supplied, exiting") + } + cfg := sentry.ClientOptions{ + Dsn: args.DSN, + Environment: args.Environment, + Release: fmt.Sprintf("%s-%s", serviceName, buildVersion), + } + switch args.Environment { + case "development": + cfg.Debug = true + cfg.EnableTracing = false + cfg.TracesSampleRate = 0.0 + case "production": + if args.DSN == "" { + return fmt.Errorf("no DSN supplied for non-dev environment, exiting") + } + cfg.Debug = false + cfg.EnableTracing = true + cfg.TracesSampleRate = 1.0 + default: + return fmt.Errorf("illegal environment %s", args.Environment) + } + + if err := sentry.Init(cfg); err != nil { + return fmt.Errorf("sentry setup: %w", err) + } + logger.Infof("configured Sentry for env: %s", args.Environment) + return nil +} + func ConnectAMQP(url string) (Connection, error) { return goamqp.NewFromURL(serviceName, url) } diff --git a/k8s/secrets.yaml b/k8s/secrets.yaml index 92f2ab5..1b8fb66 100644 --- a/k8s/secrets.yaml +++ b/k8s/secrets.yaml @@ -14,6 +14,8 @@ spec: data: POSTGRES_URL: "postgres://{{ .DB_USERNAME }}:{{ .DB_PASSWORD }}@{{ .DB_HOST }}:{{ .DB_PORT }}/schemas?sslmode=disable" API_KEY: "{{ .API_KEY }}" + SENTRY_DSN: "{{ .SENTRY_DSN }}" + SENTRY_ENVIRONMENT: "{{ .SENTRY_ENVIRONMENT }}" dataFrom: - extract: key: services/schemas -- 2.52.0