-
Notifications
You must be signed in to change notification settings - Fork 349
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
fix: support configuration of HTTP server address #1365
Changes from 3 commits
a9c95e6
7361af4
9ae8c3c
d2b6d5f
5951407
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 |
---|---|---|
|
@@ -78,6 +78,8 @@ type Command struct { | |
telemetryPrefix string | ||
prometheus bool | ||
prometheusNamespace string | ||
prometheusAddress string | ||
prometheusPort string | ||
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. [minor] Since it’s prometheusPort, what about healthCheckPort instead of httpPort? |
||
healthCheck bool | ||
httpPort string | ||
} | ||
|
@@ -228,11 +230,15 @@ func NewCommand(opts ...Option) *Command { | |
cmd.PersistentFlags().StringVar(&c.telemetryPrefix, "telemetry-prefix", "", | ||
"Prefix for Cloud Monitoring metrics.") | ||
cmd.PersistentFlags().BoolVar(&c.prometheus, "prometheus", false, | ||
"Enable Prometheus HTTP endpoint /metrics on localhost") | ||
"Enable Prometheus HTTP endpoint /metrics") | ||
cmd.PersistentFlags().StringVar(&c.prometheusNamespace, "prometheus-namespace", "", | ||
"Use the provided Prometheus namespace for metrics") | ||
cmd.PersistentFlags().StringVar(&c.httpPort, "http-port", "9090", | ||
"Port for Prometheus and health check server") | ||
cmd.PersistentFlags().StringVar(&c.prometheusAddress, "prometheus-address", "localhost", | ||
"Address for Prometheus server") | ||
cmd.PersistentFlags().StringVar(&c.prometheusPort, "prometheus-port", "9090", | ||
"Port for the Prometheus server") | ||
cmd.PersistentFlags().StringVar(&c.httpPort, "http-port", "8090", | ||
"Port for the health check server") | ||
cmd.PersistentFlags().BoolVar(&c.healthCheck, "health-check", false, | ||
"Enables health check endpoints /startup, /liveness, and /readiness on localhost.") | ||
cmd.PersistentFlags().StringVar(&c.conf.APIEndpointURL, "sqladmin-api-endpoint", "", | ||
|
@@ -454,22 +460,26 @@ func runSignalWrapper(cmd *Command) error { | |
}() | ||
} | ||
|
||
var ( | ||
needsHTTPServer bool | ||
mux = http.NewServeMux() | ||
) | ||
// shutdownCh wil produce any available error from any goroutine started | ||
// below. | ||
shutdownCh := make(chan error) | ||
|
||
if cmd.prometheus { | ||
needsHTTPServer = true | ||
e, err := prometheus.NewExporter(prometheus.Options{ | ||
Namespace: cmd.prometheusNamespace, | ||
}) | ||
if err != nil { | ||
return err | ||
} | ||
mux := http.NewServeMux() | ||
mux.Handle("/metrics", e) | ||
srv := &http.Server{ | ||
Addr: fmt.Sprintf("%s:%s", cmd.prometheusAddress, cmd.prometheusPort), | ||
Handler: mux, | ||
} | ||
startHTTPServer(ctx, cmd.logger, srv, shutdownCh) | ||
} | ||
|
||
shutdownCh := make(chan error) | ||
// watch for sigterm / sigint signals | ||
signals := make(chan os.Signal, 1) | ||
signal.Notify(signals, syscall.SIGTERM, syscall.SIGINT) | ||
|
@@ -517,42 +527,17 @@ func runSignalWrapper(cmd *Command) error { | |
|
||
notify := func() {} | ||
if cmd.healthCheck { | ||
needsHTTPServer = true | ||
hc := healthcheck.NewCheck(p, cmd.logger) | ||
mux := http.NewServeMux() | ||
mux.HandleFunc("/startup", hc.HandleStartup) | ||
mux.HandleFunc("/readiness", hc.HandleReadiness) | ||
mux.HandleFunc("/liveness", hc.HandleLiveness) | ||
notify = hc.NotifyStarted | ||
} | ||
|
||
// Start the HTTP server if anything requiring HTTP is specified. | ||
if needsHTTPServer { | ||
server := &http.Server{ | ||
srv := &http.Server{ | ||
Addr: fmt.Sprintf("localhost:%s", cmd.httpPort), | ||
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. Should we be putting 0.0.0.0 here? |
||
Handler: mux, | ||
} | ||
// Start the HTTP server. | ||
go func() { | ||
err := server.ListenAndServe() | ||
if err == http.ErrServerClosed { | ||
return | ||
} | ||
if err != nil { | ||
shutdownCh <- fmt.Errorf("failed to start HTTP server: %v", err) | ||
} | ||
}() | ||
// Handle shutdown of the HTTP server gracefully. | ||
go func() { | ||
select { | ||
case <-ctx.Done(): | ||
// Give the HTTP server a second to shutdown cleanly. | ||
ctx2, cancel := context.WithTimeout(context.Background(), time.Second) | ||
defer cancel() | ||
if err := server.Shutdown(ctx2); err != nil { | ||
cmd.logger.Errorf("failed to shutdown Prometheus HTTP server: %v\n", err) | ||
} | ||
} | ||
}() | ||
startHTTPServer(ctx, cmd.logger, srv, shutdownCh) | ||
} | ||
|
||
go func() { shutdownCh <- p.Serve(ctx, notify) }() | ||
|
@@ -568,3 +553,26 @@ func runSignalWrapper(cmd *Command) error { | |
} | ||
return err | ||
} | ||
|
||
func startHTTPServer(ctx context.Context, logger cloudsql.Logger, srv *http.Server, shutdownCh chan<- error) { | ||
// Start the HTTP server. | ||
go func() { | ||
err := srv.ListenAndServe() | ||
if err == http.ErrServerClosed { | ||
return | ||
} | ||
if err != nil { | ||
shutdownCh <- fmt.Errorf("failed to start HTTP server: %v", err) | ||
} | ||
}() | ||
// Handle shutdown of the HTTP server gracefully. | ||
go func() { | ||
<-ctx.Done() | ||
// Give the HTTP server a second to shutdown cleanly. | ||
ctx2, cancel := context.WithTimeout(context.Background(), time.Second) | ||
defer cancel() | ||
if err := srv.Shutdown(ctx2); err != nil { | ||
logger.Errorf("failed to shutdown Prometheus HTTP server: %v\n", err) | ||
} | ||
}() | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -595,7 +595,12 @@ func TestPrometheusMetricsEndpoint(t *testing.T) { | |
// Keep the test output quiet | ||
c.SilenceUsage = true | ||
c.SilenceErrors = true | ||
c.SetArgs([]string{"--prometheus", "my-project:my-region:my-instance"}) | ||
c.SetArgs([]string{ | ||
"--prometheus", | ||
"--prometheus-address", "localhost", | ||
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. You need a test where this isn't localhost. That's the default value |
||
"--prometheus-port", "9090", | ||
"my-project:my-region:my-instance", | ||
}) | ||
|
||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) | ||
defer cancel() | ||
|
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.
We also need httpAddress, right? Otherwise, the probe will fail (am I missing something?).