diff --git a/changelog/unreleased/add-debug-to-postprocessing.md b/changelog/unreleased/add-debug-to-postprocessing.md new file mode 100644 index 0000000000..08c2bc9e03 --- /dev/null +++ b/changelog/unreleased/add-debug-to-postprocessing.md @@ -0,0 +1,6 @@ +Enhancement: Add debug server to postprocessing + +We added a debug server to postprocessing. + +https://github.com/owncloud/ocis/pull/6203 +https://github.com/owncloud/ocis/issues/5002 \ No newline at end of file diff --git a/docs/services/general-info/port-ranges.md b/docs/services/general-info/port-ranges.md index d017a2e4a1..a79ce24fc6 100644 --- a/docs/services/general-info/port-ranges.md +++ b/docs/services/general-info/port-ranges.md @@ -61,7 +61,7 @@ We also suggest to use the last port in your extensions' range as a debug/metric | 9240-9244 | [app-registry]({{< ref "../app-registry/_index.md" >}}) | | 9245-9249 | FREE | | 9250-9254 | [ocis server (runtime)](https://github.com/owncloud/ocis/tree/master/ocis/pkg/runtime) | -| 9255-9259 | FREE | +| 9255-9259 | [postprocessing]({{ ref "../postprocessing/_index.md" >}}) | | 9260-9264 | FREE | | 9265-9269 | FREE | | 9270-9274 | FREE | diff --git a/services/postprocessing/pkg/command/server.go b/services/postprocessing/pkg/command/server.go index 94feca2013..04c551ec64 100644 --- a/services/postprocessing/pkg/command/server.go +++ b/services/postprocessing/pkg/command/server.go @@ -1,6 +1,7 @@ package command import ( + "context" "crypto/tls" "crypto/x509" "fmt" @@ -8,7 +9,11 @@ import ( "github.com/cs3org/reva/v2/pkg/events/stream" "github.com/go-micro/plugins/v4/events/natsjs" + "github.com/oklog/run" ociscrypto "github.com/owncloud/ocis/v2/ocis-pkg/crypto" + "github.com/owncloud/ocis/v2/ocis-pkg/handlers" + "github.com/owncloud/ocis/v2/ocis-pkg/service/debug" + "github.com/owncloud/ocis/v2/ocis-pkg/version" "github.com/owncloud/ocis/v2/services/postprocessing/pkg/config" "github.com/owncloud/ocis/v2/services/postprocessing/pkg/config/parser" "github.com/owncloud/ocis/v2/services/postprocessing/pkg/logging" @@ -31,45 +36,92 @@ func Server(cfg *config.Config) *cli.Command { return err }, Action: func(c *cli.Context) error { - logger := logging.Configure(cfg.Service.Name, cfg.Log) + var ( + gr = run.Group{} + logger = logging.Configure(cfg.Service.Name, cfg.Log) - evtsCfg := cfg.Postprocessing.Events - var tlsConf *tls.Config + evtsCfg = cfg.Postprocessing.Events + tlsConf *tls.Config - if evtsCfg.EnableTLS { - var rootCAPool *x509.CertPool - if evtsCfg.TLSRootCACertificate != "" { - rootCrtFile, err := os.Open(evtsCfg.TLSRootCACertificate) - if err != nil { - return err + ctx, cancel = func() (context.Context, context.CancelFunc) { + if cfg.Context == nil { + return context.WithCancel(context.Background()) } - - rootCAPool, err = ociscrypto.NewCertPoolFromPEM(rootCrtFile) - if err != nil { - return err - } - evtsCfg.TLSInsecure = false - } - - tlsConf = &tls.Config{ - RootCAs: rootCAPool, - } - } - - bus, err := stream.Nats( - natsjs.TLSConfig(tlsConf), - natsjs.Address(evtsCfg.Endpoint), - natsjs.ClusterID(evtsCfg.Cluster), + return context.WithCancel(cfg.Context) + }() ) - if err != nil { - return err + defer cancel() + + { + if evtsCfg.EnableTLS { + var rootCAPool *x509.CertPool + if evtsCfg.TLSRootCACertificate != "" { + rootCrtFile, err := os.Open(evtsCfg.TLSRootCACertificate) + if err != nil { + return err + } + + rootCAPool, err = ociscrypto.NewCertPoolFromPEM(rootCrtFile) + if err != nil { + return err + } + evtsCfg.TLSInsecure = false + } + + tlsConf = &tls.Config{ + RootCAs: rootCAPool, + } + } + + bus, err := stream.Nats( + natsjs.TLSConfig(tlsConf), + natsjs.Address(evtsCfg.Endpoint), + natsjs.ClusterID(evtsCfg.Cluster), + ) + if err != nil { + return err + } + + svc, err := service.NewPostprocessingService(bus, logger, cfg.Postprocessing) + if err != nil { + return err + } + gr.Add(func() error { + err := make(chan error) + select { + case <-ctx.Done(): + return nil + + case err <- svc.Run(): + return <-err + } + }, func(err error) { + logger.Error(). + Err(err). + Msg("Shutting down server") + cancel() + }) } - svc, err := service.NewPostprocessingService(bus, logger, cfg.Postprocessing) - if err != nil { - return err + { + server := debug.NewService( + debug.Logger(logger), + debug.Name(cfg.Service.Name), + debug.Version(version.GetString()), + debug.Address(cfg.Debug.Addr), + debug.Token(cfg.Debug.Token), + debug.Pprof(cfg.Debug.Pprof), + debug.Zpages(cfg.Debug.Zpages), + debug.Health(handlers.Health), + debug.Ready(handlers.Ready), + ) + + gr.Add(server.ListenAndServe, func(_ error) { + _ = server.Shutdown(ctx) + cancel() + }) } - return svc.Run() + return gr.Run() }, } } diff --git a/services/postprocessing/pkg/config/config.go b/services/postprocessing/pkg/config/config.go index 850d348908..e77cf663fd 100644 --- a/services/postprocessing/pkg/config/config.go +++ b/services/postprocessing/pkg/config/config.go @@ -13,7 +13,9 @@ type Config struct { Service Service `yaml:"-"` - Log *Log `yaml:"log"` + Tracing *Tracing `yaml:"tracing"` + Log *Log `yaml:"log"` + Debug Debug `yaml:"debug"` Postprocessing Postprocessing `yaml:"postprocessing"` @@ -37,3 +39,19 @@ type Events struct { TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"POSTPROCESSING_EVENTS_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided POSTPROCESSING_EVENTS_TLS_INSECURE will be seen as false."` EnableTLS bool `yaml:"enable_tls" env:"OCIS_EVENTS_ENABLE_TLS;POSTPROCESSING_EVENTS_ENABLE_TLS" desc:"Enable TLS for the connection to the events broker. The events broker is the ocis service which receives and delivers events between the services."` } + +// Debug defines the available debug configuration. +type Debug struct { + Addr string `yaml:"addr" env:"POSTPROCESSING_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."` + Token string `yaml:"token" env:"POSTPROCESSING_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."` + Pprof bool `yaml:"pprof" env:"POSTPROCESSING_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."` + Zpages bool `yaml:"zpages" env:"POSTPROCESSING_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."` +} + +// Tracing defines the available tracing configuration. +type Tracing struct { + Enabled bool `yaml:"enabled" env:"OCIS_TRACING_ENABLED;POSTPROCESSING_TRACING_ENABLED" desc:"Activates tracing."` + Type string `yaml:"type" env:"OCIS_TRACING_TYPE;POSTPROCESSING_TRACING_TYPE" desc:"The type of tracing. Defaults to \"\", which is the same as \"jaeger\". Allowed tracing types are \"jaeger\" and \"\" as of now."` + Endpoint string `yaml:"endpoint" env:"OCIS_TRACING_ENDPOINT;POSTPROCESSING_TRACING_ENDPOINT" desc:"The endpoint of the tracing agent."` + Collector string `yaml:"collector" env:"OCIS_TRACING_COLLECTOR;POSTPROCESSING_TRACING_COLLECTOR" desc:"The HTTP endpoint for sending spans directly to a collector, i.e. http://jaeger-collector:14268/api/traces. Only used if the tracing endpoint is unset."` +} diff --git a/services/postprocessing/pkg/config/defaults/defaultconfig.go b/services/postprocessing/pkg/config/defaults/defaultconfig.go index 70dd45ac11..18baf3acc1 100644 --- a/services/postprocessing/pkg/config/defaults/defaultconfig.go +++ b/services/postprocessing/pkg/config/defaults/defaultconfig.go @@ -15,6 +15,12 @@ func FullDefaultConfig() *config.Config { // DefaultConfig is the default configuration func DefaultConfig() *config.Config { return &config.Config{ + Debug: config.Debug{ + Addr: "127.0.0.1:9255", + Token: "", + Pprof: false, + Zpages: false, + }, Service: config.Service{ Name: "postprocessing", }, @@ -40,6 +46,18 @@ func EnsureDefaults(cfg *config.Config) { } else if cfg.Log == nil { cfg.Log = &config.Log{} } + + // provide with defaults for shared tracing, since we need a valid destination address for "envdecode". + if cfg.Tracing == nil && cfg.Commons != nil && cfg.Commons.Tracing != nil { + cfg.Tracing = &config.Tracing{ + Enabled: cfg.Commons.Tracing.Enabled, + Type: cfg.Commons.Tracing.Type, + Endpoint: cfg.Commons.Tracing.Endpoint, + Collector: cfg.Commons.Tracing.Collector, + } + } else if cfg.Tracing == nil { + cfg.Tracing = &config.Tracing{} + } } // Sanitize does nothing atm