-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Add healthcheck to standalone #784
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
5673f8b
111c618
fa7acd8
fe389b7
1e41f84
0a9e445
31cac87
466f7b7
af74207
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,6 +15,7 @@ | |
| package main | ||
|
|
||
| import ( | ||
| "flag" | ||
| "fmt" | ||
| "log" | ||
| "net" | ||
|
|
@@ -44,6 +45,7 @@ import ( | |
| "github.com/jaegertracing/jaeger/cmd/flags" | ||
| queryApp "github.com/jaegertracing/jaeger/cmd/query/app" | ||
| "github.com/jaegertracing/jaeger/pkg/config" | ||
| "github.com/jaegertracing/jaeger/pkg/healthcheck" | ||
| pMetrics "github.com/jaegertracing/jaeger/pkg/metrics" | ||
| "github.com/jaegertracing/jaeger/pkg/recoveryhandler" | ||
| "github.com/jaegertracing/jaeger/pkg/version" | ||
|
|
@@ -56,6 +58,11 @@ import ( | |
| zc "github.com/jaegertracing/jaeger/thrift-gen/zipkincore" | ||
| ) | ||
|
|
||
| const ( | ||
| healthCheckHTTPPort = "standalone.health-check-http-port" | ||
| defaultHealthCheckPort = collector.DefaultHealthCheckHTTPPort | ||
| ) | ||
|
|
||
| // standalone/main is a standalone full-stack jaeger backend, backed by a memory store | ||
| func main() { | ||
| var signalsChannel = make(chan os.Signal, 0) | ||
|
|
@@ -90,6 +97,13 @@ func main() { | |
| return err | ||
| } | ||
|
|
||
| hc, err := healthcheck. | ||
| New(healthcheck.Unavailable, healthcheck.Logger(logger)). | ||
| Serve(v.GetInt(healthCheckHTTPPort)) | ||
| if err != nil { | ||
| logger.Fatal("Could not start the health check server.", zap.Error(err)) | ||
| } | ||
|
|
||
| mBldr := new(pMetrics.Builder).InitFromViper(v) | ||
| metricsFactory, err := mBldr.CreateMetricsFactory("jaeger-standalone") | ||
| if err != nil { | ||
|
|
@@ -119,8 +133,9 @@ func main() { | |
| qOpts := new(queryApp.QueryOptions).InitFromViper(v) | ||
|
|
||
| startAgent(aOpts, cOpts, logger, metricsFactory) | ||
| startCollector(cOpts, spanWriter, logger, metricsFactory, samplingHandler) | ||
| startQuery(qOpts, spanReader, dependencyReader, logger, metricsFactory, mBldr) | ||
| startCollector(cOpts, spanWriter, logger, metricsFactory, samplingHandler, hc) | ||
| startQuery(qOpts, spanReader, dependencyReader, logger, metricsFactory, mBldr, hc) | ||
| hc.Ready() | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't necessarily know how to fix it, but there is a race condition here where collector or query background goroutines can fail to start the server and set HC to Unavailable, but this statement will override it.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Move goroutines to main from each start function, and start them in main then set Ready. For 100% guarantees, can we move hc.Ready before goroutines like this? hc.Ready()
go collectorServer()
go queryServer()
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think returning functions like this provides any additional guarantees. I think it's fine to leave it as it was, i.e. call Sorry I led you on the wrong path with the last comment. The fact that the goroutines call log.Fatal on error sort of take care of things.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wanted hc.Ready() to be called before collector/query goroutine call hc.Set(healthcheck.Unavailable) in ListenAndServe error. Anyway, if the issue in all-in-one is not critical and fatal log on error is enough, I'll revert.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I don't think it's critical sice even if the override happens the process will exit anyway. |
||
|
|
||
| select { | ||
| case <-signalsChannel: | ||
|
|
@@ -144,14 +159,28 @@ func main() { | |
| queryApp.AddFlags, | ||
| pMetrics.AddFlags, | ||
| strategyStoreFactory.AddFlags, | ||
| func(flagSet *flag.FlagSet) { | ||
| flagSet.Int(healthCheckHTTPPort, defaultHealthCheckPort, | ||
| "The http port for the health check services") | ||
| }, | ||
|
||
| ) | ||
| hideQueryCollectorFlags(command) | ||
|
|
||
| if err := command.Execute(); err != nil { | ||
| fmt.Println(err.Error()) | ||
| os.Exit(1) | ||
| } | ||
| } | ||
|
|
||
| func hideQueryCollectorFlags(command *cobra.Command) { | ||
|
||
| if err := command.Flags().MarkHidden(queryApp.QueryHealthCheckHTTPPort); err != nil { | ||
| fmt.Println(err.Error()) | ||
| } | ||
| if err := command.Flags().MarkHidden(collector.CollectorHealthCheckHTTPPort); err != nil { | ||
| fmt.Println(err.Error()) | ||
| } | ||
| } | ||
|
|
||
| func startAgent( | ||
| b *agentApp.Builder, | ||
| cOpts *collector.CollectorOptions, | ||
|
|
@@ -180,6 +209,7 @@ func startCollector( | |
| logger *zap.Logger, | ||
| baseFactory metrics.Factory, | ||
| samplingHandler sampling.Handler, | ||
| hc *healthcheck.HealthCheck, | ||
| ) { | ||
| metricsFactory := baseFactory.Namespace("jaeger-collector", nil) | ||
|
|
||
|
|
@@ -222,6 +252,7 @@ func startCollector( | |
| if err := http.ListenAndServe(httpPortStr, recoveryHandler(r)); err != nil { | ||
| logger.Fatal("Could not launch jaeger-collector HTTP server", zap.Error(err)) | ||
| } | ||
| hc.Set(healthcheck.Unavailable) | ||
| }() | ||
| } | ||
|
|
||
|
|
@@ -251,8 +282,8 @@ func startQuery( | |
| logger *zap.Logger, | ||
| baseFactory metrics.Factory, | ||
| metricsBuilder *pMetrics.Builder, | ||
| hc *healthcheck.HealthCheck, | ||
| ) { | ||
|
|
||
| tracer, closer, err := jaegerClientConfig.Configuration{ | ||
| Sampler: &jaegerClientConfig.SamplerConfig{ | ||
| Type: "const", | ||
|
|
@@ -289,6 +320,7 @@ func startQuery( | |
| if err := http.ListenAndServe(portStr, recoveryHandler(r)); err != nil { | ||
| logger.Fatal("Could not launch jaeger-query service", zap.Error(err)) | ||
| } | ||
| hc.Set(healthcheck.Unavailable) | ||
| }() | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think a better approach would be to have a single global flag for all binaries, similar to how we do log levels or metrics.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Questions,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1 - yes
2 - I meant shared flags, the BasicOption is independent of cli flags