mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
all: add support for specifying multiple -httpListenAddr options
This commit is contained in:
parent
b161e889b5
commit
ae8a867924
14 changed files with 141 additions and 80 deletions
|
@ -21,8 +21,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
httpListenAddr = flag.String("httpListenAddr", ":9428", "TCP address to listen for http connections. See also -httpListenAddr.useProxyProtocol")
|
httpListenAddrs = flagutil.NewArrayString("httpListenAddr", "TCP address to listen for incoming http requests. See also -httpListenAddr.useProxyProtocol")
|
||||||
useProxyProtocol = flag.Bool("httpListenAddr.useProxyProtocol", false, "Whether to use proxy protocol for connections accepted at -httpListenAddr . "+
|
useProxyProtocol = flagutil.NewArrayBool("httpListenAddr.useProxyProtocol", "Whether to use proxy protocol for connections accepted at the given -httpListenAddr . "+
|
||||||
"See https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt . "+
|
"See https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt . "+
|
||||||
"With enabled proxy protocol http server cannot serve regular /metrics endpoint. Use -pushmetrics.url for metrics pushing")
|
"With enabled proxy protocol http server cannot serve regular /metrics endpoint. Use -pushmetrics.url for metrics pushing")
|
||||||
)
|
)
|
||||||
|
@ -35,14 +35,18 @@ func main() {
|
||||||
buildinfo.Init()
|
buildinfo.Init()
|
||||||
logger.Init()
|
logger.Init()
|
||||||
|
|
||||||
logger.Infof("starting VictoriaLogs at %q...", *httpListenAddr)
|
listenAddrs := *httpListenAddrs
|
||||||
|
if len(listenAddrs) == 0 {
|
||||||
|
listenAddrs = []string{":9428"}
|
||||||
|
}
|
||||||
|
logger.Infof("starting VictoriaLogs at %q...", listenAddrs)
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
|
|
||||||
vlstorage.Init()
|
vlstorage.Init()
|
||||||
vlselect.Init()
|
vlselect.Init()
|
||||||
vlinsert.Init()
|
vlinsert.Init()
|
||||||
|
|
||||||
go httpserver.Serve(*httpListenAddr, *useProxyProtocol, requestHandler)
|
go httpserver.Serve(listenAddrs, useProxyProtocol, requestHandler)
|
||||||
logger.Infof("started VictoriaLogs in %.3f seconds; see https://docs.victoriametrics.com/VictoriaLogs/", time.Since(startTime).Seconds())
|
logger.Infof("started VictoriaLogs in %.3f seconds; see https://docs.victoriametrics.com/VictoriaLogs/", time.Since(startTime).Seconds())
|
||||||
|
|
||||||
pushmetrics.Init()
|
pushmetrics.Init()
|
||||||
|
@ -50,9 +54,9 @@ func main() {
|
||||||
logger.Infof("received signal %s", sig)
|
logger.Infof("received signal %s", sig)
|
||||||
pushmetrics.Stop()
|
pushmetrics.Stop()
|
||||||
|
|
||||||
logger.Infof("gracefully shutting down webservice at %q", *httpListenAddr)
|
logger.Infof("gracefully shutting down webservice at %q", listenAddrs)
|
||||||
startTime = time.Now()
|
startTime = time.Now()
|
||||||
if err := httpserver.Stop(*httpListenAddr); err != nil {
|
if err := httpserver.Stop(listenAddrs); err != nil {
|
||||||
logger.Fatalf("cannot stop the webservice: %s", err)
|
logger.Fatalf("cannot stop the webservice: %s", err)
|
||||||
}
|
}
|
||||||
logger.Infof("successfully shut down the webservice in %.3f seconds", time.Since(startTime).Seconds())
|
logger.Infof("successfully shut down the webservice in %.3f seconds", time.Since(startTime).Seconds())
|
||||||
|
|
|
@ -26,8 +26,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
httpListenAddr = flag.String("httpListenAddr", ":8428", "TCP address to listen for http connections. See also -tls and -httpListenAddr.useProxyProtocol")
|
httpListenAddrs = flagutil.NewArrayString("httpListenAddr", "TCP addresses to listen for incoming http requests. See also -tls and -httpListenAddr.useProxyProtocol")
|
||||||
useProxyProtocol = flag.Bool("httpListenAddr.useProxyProtocol", false, "Whether to use proxy protocol for connections accepted at -httpListenAddr . "+
|
useProxyProtocol = flagutil.NewArrayBool("httpListenAddr.useProxyProtocol", "Whether to use proxy protocol for connections accepted at the corresponding -httpListenAddr . "+
|
||||||
"See https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt . "+
|
"See https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt . "+
|
||||||
"With enabled proxy protocol http server cannot serve regular /metrics endpoint. Use -pushmetrics.url for metrics pushing")
|
"With enabled proxy protocol http server cannot serve regular /metrics endpoint. Use -pushmetrics.url for metrics pushing")
|
||||||
minScrapeInterval = flag.Duration("dedup.minScrapeInterval", 0, "Leave only the last sample in every time series per each discrete interval "+
|
minScrapeInterval = flag.Duration("dedup.minScrapeInterval", 0, "Leave only the last sample in every time series per each discrete interval "+
|
||||||
|
@ -66,7 +66,11 @@ func main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Infof("starting VictoriaMetrics at %q...", *httpListenAddr)
|
listenAddrs := *httpListenAddrs
|
||||||
|
if len(listenAddrs) == 0 {
|
||||||
|
listenAddrs = []string{":8428"}
|
||||||
|
}
|
||||||
|
logger.Infof("starting VictoriaMetrics at %q...", listenAddrs)
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
storage.SetDedupInterval(*minScrapeInterval)
|
storage.SetDedupInterval(*minScrapeInterval)
|
||||||
storage.SetDataFlushInterval(*inmemoryDataFlushInterval)
|
storage.SetDataFlushInterval(*inmemoryDataFlushInterval)
|
||||||
|
@ -76,7 +80,7 @@ func main() {
|
||||||
|
|
||||||
startSelfScraper()
|
startSelfScraper()
|
||||||
|
|
||||||
go httpserver.Serve(*httpListenAddr, *useProxyProtocol, requestHandler)
|
go httpserver.Serve(listenAddrs, useProxyProtocol, requestHandler)
|
||||||
logger.Infof("started VictoriaMetrics in %.3f seconds", time.Since(startTime).Seconds())
|
logger.Infof("started VictoriaMetrics in %.3f seconds", time.Since(startTime).Seconds())
|
||||||
|
|
||||||
pushmetrics.Init()
|
pushmetrics.Init()
|
||||||
|
@ -86,9 +90,9 @@ func main() {
|
||||||
|
|
||||||
stopSelfScraper()
|
stopSelfScraper()
|
||||||
|
|
||||||
logger.Infof("gracefully shutting down webservice at %q", *httpListenAddr)
|
logger.Infof("gracefully shutting down webservice at %q", listenAddrs)
|
||||||
startTime = time.Now()
|
startTime = time.Now()
|
||||||
if err := httpserver.Stop(*httpListenAddr); err != nil {
|
if err := httpserver.Stop(listenAddrs); err != nil {
|
||||||
logger.Fatalf("cannot stop the webservice: %s", err)
|
logger.Fatalf("cannot stop the webservice: %s", err)
|
||||||
}
|
}
|
||||||
logger.Infof("successfully shut down the webservice in %.3f seconds", time.Since(startTime).Seconds())
|
logger.Infof("successfully shut down the webservice in %.3f seconds", time.Since(startTime).Seconds())
|
||||||
|
|
|
@ -180,7 +180,7 @@ func setUp() {
|
||||||
vmstorage.Init(promql.ResetRollupResultCacheIfNeeded)
|
vmstorage.Init(promql.ResetRollupResultCacheIfNeeded)
|
||||||
vmselect.Init()
|
vmselect.Init()
|
||||||
vminsert.Init()
|
vminsert.Init()
|
||||||
go httpserver.Serve(*httpListenAddr, false, requestHandler)
|
go httpserver.Serve(*httpListenAddrs, useProxyProtocol, requestHandler)
|
||||||
readyStorageCheckFunc := func() bool {
|
readyStorageCheckFunc := func() bool {
|
||||||
resp, err := http.Get(testHealthHTTPPath)
|
resp, err := http.Get(testHealthHTTPPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -226,7 +226,7 @@ func waitFor(timeout time.Duration, f func() bool) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func tearDown() {
|
func tearDown() {
|
||||||
if err := httpserver.Stop(*httpListenAddr); err != nil {
|
if err := httpserver.Stop(*httpListenAddrs); err != nil {
|
||||||
log.Printf("cannot stop the webservice: %s", err)
|
log.Printf("cannot stop the webservice: %s", err)
|
||||||
}
|
}
|
||||||
vminsert.Stop()
|
vminsert.Stop()
|
||||||
|
|
|
@ -46,10 +46,10 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
httpListenAddr = flag.String("httpListenAddr", ":8429", "TCP address to listen for http connections. "+
|
httpListenAddrs = flagutil.NewArrayString("httpListenAddr", "TCP address to listen for incoming http requests. "+
|
||||||
"Set this flag to empty value in order to disable listening on any port. This mode may be useful for running multiple vmagent instances on the same server. "+
|
"Set this flag to empty value in order to disable listening on any port. This mode may be useful for running multiple vmagent instances on the same server. "+
|
||||||
"Note that /targets and /metrics pages aren't available if -httpListenAddr=''. See also -tls and -httpListenAddr.useProxyProtocol")
|
"Note that /targets and /metrics pages aren't available if -httpListenAddr=''. See also -tls and -httpListenAddr.useProxyProtocol")
|
||||||
useProxyProtocol = flag.Bool("httpListenAddr.useProxyProtocol", false, "Whether to use proxy protocol for connections accepted at -httpListenAddr . "+
|
useProxyProtocol = flagutil.NewArrayBool("httpListenAddr.useProxyProtocol", "Whether to use proxy protocol for connections accepted at the corresponding -httpListenAddr . "+
|
||||||
"See https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt . "+
|
"See https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt . "+
|
||||||
"With enabled proxy protocol http server cannot serve regular /metrics endpoint. Use -pushmetrics.url for metrics pushing")
|
"With enabled proxy protocol http server cannot serve regular /metrics endpoint. Use -pushmetrics.url for metrics pushing")
|
||||||
influxListenAddr = flag.String("influxListenAddr", "", "TCP and UDP address to listen for InfluxDB line protocol data. Usually :8089 must be set. Doesn't work if empty. "+
|
influxListenAddr = flag.String("influxListenAddr", "", "TCP and UDP address to listen for InfluxDB line protocol data. Usually :8089 must be set. Doesn't work if empty. "+
|
||||||
|
@ -120,7 +120,11 @@ func main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Infof("starting vmagent at %q...", *httpListenAddr)
|
listenAddrs := *httpListenAddrs
|
||||||
|
if len(listenAddrs) == 0 {
|
||||||
|
listenAddrs = []string{":8429"}
|
||||||
|
}
|
||||||
|
logger.Infof("starting vmagent at %q...", listenAddrs)
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
remotewrite.Init()
|
remotewrite.Init()
|
||||||
common.StartUnmarshalWorkers()
|
common.StartUnmarshalWorkers()
|
||||||
|
@ -143,9 +147,7 @@ func main() {
|
||||||
|
|
||||||
promscrape.Init(remotewrite.PushDropSamplesOnFailure)
|
promscrape.Init(remotewrite.PushDropSamplesOnFailure)
|
||||||
|
|
||||||
if len(*httpListenAddr) > 0 {
|
go httpserver.Serve(listenAddrs, useProxyProtocol, requestHandler)
|
||||||
go httpserver.Serve(*httpListenAddr, *useProxyProtocol, requestHandler)
|
|
||||||
}
|
|
||||||
logger.Infof("started vmagent in %.3f seconds", time.Since(startTime).Seconds())
|
logger.Infof("started vmagent in %.3f seconds", time.Since(startTime).Seconds())
|
||||||
|
|
||||||
pushmetrics.Init()
|
pushmetrics.Init()
|
||||||
|
@ -154,13 +156,11 @@ func main() {
|
||||||
pushmetrics.Stop()
|
pushmetrics.Stop()
|
||||||
|
|
||||||
startTime = time.Now()
|
startTime = time.Now()
|
||||||
if len(*httpListenAddr) > 0 {
|
logger.Infof("gracefully shutting down webservice at %q", listenAddrs)
|
||||||
logger.Infof("gracefully shutting down webservice at %q", *httpListenAddr)
|
if err := httpserver.Stop(listenAddrs); err != nil {
|
||||||
if err := httpserver.Stop(*httpListenAddr); err != nil {
|
logger.Fatalf("cannot stop the webservice: %s", err)
|
||||||
logger.Fatalf("cannot stop the webservice: %s", err)
|
|
||||||
}
|
|
||||||
logger.Infof("successfully shut down the webservice in %.3f seconds", time.Since(startTime).Seconds())
|
|
||||||
}
|
}
|
||||||
|
logger.Infof("successfully shut down the webservice in %.3f seconds", time.Since(startTime).Seconds())
|
||||||
|
|
||||||
promscrape.Stop()
|
promscrape.Stop()
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import (
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmselect/prometheus"
|
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmselect/prometheus"
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmselect/promql"
|
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmselect/promql"
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmstorage"
|
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmstorage"
|
||||||
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/flagutil"
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/fs"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/fs"
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/httpserver"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/httpserver"
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
|
||||||
|
@ -184,7 +185,8 @@ func processFlags() {
|
||||||
|
|
||||||
func setUp() {
|
func setUp() {
|
||||||
vmstorage.Init(promql.ResetRollupResultCacheIfNeeded)
|
vmstorage.Init(promql.ResetRollupResultCacheIfNeeded)
|
||||||
go httpserver.Serve(httpListenAddr, false, func(w http.ResponseWriter, r *http.Request) bool {
|
var ab flagutil.ArrayBool
|
||||||
|
go httpserver.Serve([]string{httpListenAddr}, &ab, func(w http.ResponseWriter, r *http.Request) bool {
|
||||||
switch r.URL.Path {
|
switch r.URL.Path {
|
||||||
case "/prometheus/api/v1/query":
|
case "/prometheus/api/v1/query":
|
||||||
if err := prometheus.QueryHandler(nil, time.Now(), w, r); err != nil {
|
if err := prometheus.QueryHandler(nil, time.Now(), w, r); err != nil {
|
||||||
|
@ -225,7 +227,7 @@ checkCheck:
|
||||||
}
|
}
|
||||||
|
|
||||||
func tearDown() {
|
func tearDown() {
|
||||||
if err := httpserver.Stop(httpListenAddr); err != nil {
|
if err := httpserver.Stop([]string{httpListenAddr}); err != nil {
|
||||||
logger.Errorf("cannot stop the webservice: %s", err)
|
logger.Errorf("cannot stop the webservice: %s", err)
|
||||||
}
|
}
|
||||||
vmstorage.Stop()
|
vmstorage.Stop()
|
||||||
|
|
|
@ -59,8 +59,8 @@ absolute path to all .tpl files in root.
|
||||||
configCheckInterval = flag.Duration("configCheckInterval", 0, "Interval for checking for changes in '-rule' or '-notifier.config' files. "+
|
configCheckInterval = flag.Duration("configCheckInterval", 0, "Interval for checking for changes in '-rule' or '-notifier.config' files. "+
|
||||||
"By default, the checking is disabled. Send SIGHUP signal in order to force config check for changes.")
|
"By default, the checking is disabled. Send SIGHUP signal in order to force config check for changes.")
|
||||||
|
|
||||||
httpListenAddr = flag.String("httpListenAddr", ":8880", "Address to listen for http connections. See also -tls and -httpListenAddr.useProxyProtocol")
|
httpListenAddrs = flagutil.NewArrayString("httpListenAddr", "Address to listen for incoming http requests. See also -tls and -httpListenAddr.useProxyProtocol")
|
||||||
useProxyProtocol = flag.Bool("httpListenAddr.useProxyProtocol", false, "Whether to use proxy protocol for connections accepted at -httpListenAddr . "+
|
useProxyProtocol = flagutil.NewArrayBool("httpListenAddr.useProxyProtocol", "Whether to use proxy protocol for connections accepted at the corresponding -httpListenAddr . "+
|
||||||
"See https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt . "+
|
"See https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt . "+
|
||||||
"With enabled proxy protocol http server cannot serve regular /metrics endpoint. Use -pushmetrics.url for metrics pushing")
|
"With enabled proxy protocol http server cannot serve regular /metrics endpoint. Use -pushmetrics.url for metrics pushing")
|
||||||
evaluationInterval = flag.Duration("evaluationInterval", time.Minute, "How often to evaluate the rules")
|
evaluationInterval = flag.Duration("evaluationInterval", time.Minute, "How often to evaluate the rules")
|
||||||
|
@ -178,15 +178,19 @@ func main() {
|
||||||
|
|
||||||
go configReload(ctx, manager, groupsCfg, sighupCh)
|
go configReload(ctx, manager, groupsCfg, sighupCh)
|
||||||
|
|
||||||
|
listenAddrs := *httpListenAddrs
|
||||||
|
if len(listenAddrs) == 0 {
|
||||||
|
listenAddrs = []string{":8880"}
|
||||||
|
}
|
||||||
rh := &requestHandler{m: manager}
|
rh := &requestHandler{m: manager}
|
||||||
go httpserver.Serve(*httpListenAddr, *useProxyProtocol, rh.handler)
|
go httpserver.Serve(listenAddrs, useProxyProtocol, rh.handler)
|
||||||
|
|
||||||
pushmetrics.Init()
|
pushmetrics.Init()
|
||||||
sig := procutil.WaitForSigterm()
|
sig := procutil.WaitForSigterm()
|
||||||
logger.Infof("service received signal %s", sig)
|
logger.Infof("service received signal %s", sig)
|
||||||
pushmetrics.Stop()
|
pushmetrics.Stop()
|
||||||
|
|
||||||
if err := httpserver.Stop(*httpListenAddr); err != nil {
|
if err := httpserver.Stop(listenAddrs); err != nil {
|
||||||
logger.Fatalf("cannot stop the webservice: %s", err)
|
logger.Fatalf("cannot stop the webservice: %s", err)
|
||||||
}
|
}
|
||||||
cancel()
|
cancel()
|
||||||
|
@ -248,7 +252,13 @@ func newManager(ctx context.Context) (*manager, error) {
|
||||||
func getExternalURL(customURL string) (*url.URL, error) {
|
func getExternalURL(customURL string) (*url.URL, error) {
|
||||||
if customURL == "" {
|
if customURL == "" {
|
||||||
// use local hostname as external URL
|
// use local hostname as external URL
|
||||||
return getHostnameAsExternalURL(*httpListenAddr, httpserver.IsTLS())
|
listenAddr := ":8880"
|
||||||
|
if len(*httpListenAddrs) > 0 {
|
||||||
|
listenAddr = (*httpListenAddrs)[0]
|
||||||
|
}
|
||||||
|
isTLS := httpserver.IsTLS(0)
|
||||||
|
|
||||||
|
return getHostnameAsExternalURL(listenAddr, isTLS)
|
||||||
}
|
}
|
||||||
u, err := url.Parse(customURL)
|
u, err := url.Parse(customURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -260,13 +270,13 @@ func getExternalURL(customURL string) (*url.URL, error) {
|
||||||
return u, nil
|
return u, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getHostnameAsExternalURL(httpListenAddr string, isSecure bool) (*url.URL, error) {
|
func getHostnameAsExternalURL(addr string, isSecure bool) (*url.URL, error) {
|
||||||
hname, err := os.Hostname()
|
hname, err := os.Hostname()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to get hostname: %w", err)
|
return nil, fmt.Errorf("failed to get hostname: %w", err)
|
||||||
}
|
}
|
||||||
port := ""
|
port := ""
|
||||||
if ipport := strings.Split(httpListenAddr, ":"); len(ipport) > 1 {
|
if ipport := strings.Split(addr, ":"); len(ipport) > 1 {
|
||||||
port = ":" + ipport[1]
|
port = ":" + ipport[1]
|
||||||
}
|
}
|
||||||
schema := "http://"
|
schema := "http://"
|
||||||
|
|
|
@ -33,8 +33,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
httpListenAddr = flag.String("httpListenAddr", ":8427", "TCP address to listen for http connections. See also -tls and -httpListenAddr.useProxyProtocol")
|
httpListenAddrs = flagutil.NewArrayString("httpListenAddr", "TCP address to listen for incoming http requests. See also -tls and -httpListenAddr.useProxyProtocol")
|
||||||
useProxyProtocol = flag.Bool("httpListenAddr.useProxyProtocol", false, "Whether to use proxy protocol for connections accepted at -httpListenAddr . "+
|
useProxyProtocol = flagutil.NewArrayBool("httpListenAddr.useProxyProtocol", "Whether to use proxy protocol for connections accepted at the corresponding -httpListenAddr . "+
|
||||||
"See https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt . "+
|
"See https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt . "+
|
||||||
"With enabled proxy protocol http server cannot serve regular /metrics endpoint. Use -pushmetrics.url for metrics pushing")
|
"With enabled proxy protocol http server cannot serve regular /metrics endpoint. Use -pushmetrics.url for metrics pushing")
|
||||||
maxIdleConnsPerBackend = flag.Int("maxIdleConnsPerBackend", 100, "The maximum number of idle connections vmauth can open per each backend host. "+
|
maxIdleConnsPerBackend = flag.Int("maxIdleConnsPerBackend", 100, "The maximum number of idle connections vmauth can open per each backend host. "+
|
||||||
|
@ -65,10 +65,14 @@ func main() {
|
||||||
buildinfo.Init()
|
buildinfo.Init()
|
||||||
logger.Init()
|
logger.Init()
|
||||||
|
|
||||||
logger.Infof("starting vmauth at %q...", *httpListenAddr)
|
listenAddrs := *httpListenAddrs
|
||||||
|
if len(listenAddrs) == 0 {
|
||||||
|
listenAddrs = []string{":8427"}
|
||||||
|
}
|
||||||
|
logger.Infof("starting vmauth at %q...", listenAddrs)
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
initAuthConfig()
|
initAuthConfig()
|
||||||
go httpserver.Serve(*httpListenAddr, *useProxyProtocol, requestHandler)
|
go httpserver.Serve(listenAddrs, useProxyProtocol, requestHandler)
|
||||||
logger.Infof("started vmauth in %.3f seconds", time.Since(startTime).Seconds())
|
logger.Infof("started vmauth in %.3f seconds", time.Since(startTime).Seconds())
|
||||||
|
|
||||||
pushmetrics.Init()
|
pushmetrics.Init()
|
||||||
|
@ -77,8 +81,8 @@ func main() {
|
||||||
pushmetrics.Stop()
|
pushmetrics.Stop()
|
||||||
|
|
||||||
startTime = time.Now()
|
startTime = time.Now()
|
||||||
logger.Infof("gracefully shutting down webservice at %q", *httpListenAddr)
|
logger.Infof("gracefully shutting down webservice at %q", listenAddrs)
|
||||||
if err := httpserver.Stop(*httpListenAddr); err != nil {
|
if err := httpserver.Stop(listenAddrs); err != nil {
|
||||||
logger.Fatalf("cannot stop the webservice: %s", err)
|
logger.Fatalf("cannot stop the webservice: %s", err)
|
||||||
}
|
}
|
||||||
logger.Infof("successfully shut down the webservice in %.3f seconds", time.Since(startTime).Seconds())
|
logger.Infof("successfully shut down the webservice in %.3f seconds", time.Since(startTime).Seconds())
|
||||||
|
|
|
@ -93,7 +93,8 @@ func main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
go httpserver.Serve(*httpListenAddr, false, nil)
|
listenAddrs := []string{*httpListenAddr}
|
||||||
|
go httpserver.Serve(listenAddrs, nil, nil)
|
||||||
|
|
||||||
pushmetrics.Init()
|
pushmetrics.Init()
|
||||||
err := makeBackup()
|
err := makeBackup()
|
||||||
|
@ -104,8 +105,8 @@ func main() {
|
||||||
pushmetrics.Stop()
|
pushmetrics.Stop()
|
||||||
|
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
logger.Infof("gracefully shutting down http server for metrics at %q", *httpListenAddr)
|
logger.Infof("gracefully shutting down http server for metrics at %q", listenAddrs)
|
||||||
if err := httpserver.Stop(*httpListenAddr); err != nil {
|
if err := httpserver.Stop(listenAddrs); err != nil {
|
||||||
logger.Fatalf("cannot stop http server for metrics: %s", err)
|
logger.Fatalf("cannot stop http server for metrics: %s", err)
|
||||||
}
|
}
|
||||||
logger.Infof("successfully shut down http server for metrics in %.3f seconds", time.Since(startTime).Seconds())
|
logger.Infof("successfully shut down http server for metrics in %.3f seconds", time.Since(startTime).Seconds())
|
||||||
|
|
|
@ -37,7 +37,8 @@ func main() {
|
||||||
buildinfo.Init()
|
buildinfo.Init()
|
||||||
logger.Init()
|
logger.Init()
|
||||||
|
|
||||||
go httpserver.Serve(*httpListenAddr, false, nil)
|
listenAddrs := []string{*httpListenAddr}
|
||||||
|
go httpserver.Serve(listenAddrs, nil, nil)
|
||||||
|
|
||||||
srcFS, err := newSrcFS()
|
srcFS, err := newSrcFS()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -62,8 +63,8 @@ func main() {
|
||||||
dstFS.MustStop()
|
dstFS.MustStop()
|
||||||
|
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
logger.Infof("gracefully shutting down http server for metrics at %q", *httpListenAddr)
|
logger.Infof("gracefully shutting down http server for metrics at %q", listenAddrs)
|
||||||
if err := httpserver.Stop(*httpListenAddr); err != nil {
|
if err := httpserver.Stop(listenAddrs); err != nil {
|
||||||
logger.Fatalf("cannot stop http server for metrics: %s", err)
|
logger.Fatalf("cannot stop http server for metrics: %s", err)
|
||||||
}
|
}
|
||||||
logger.Infof("successfully shut down http server for metrics in %.3f seconds", time.Since(startTime).Seconds())
|
logger.Infof("successfully shut down http server for metrics in %.3f seconds", time.Since(startTime).Seconds())
|
||||||
|
|
|
@ -31,6 +31,7 @@ The sandbox cluster installation is running under the constant load generated by
|
||||||
* SECURITY: upgrade Go builder from Go1.21.6 to Go1.21.7. See [the list of issues addressed in Go1.21.7](https://github.com/golang/go/issues?q=milestone%3AGo1.21.7+label%3ACherryPickApproved).
|
* SECURITY: upgrade Go builder from Go1.21.6 to Go1.21.7. See [the list of issues addressed in Go1.21.7](https://github.com/golang/go/issues?q=milestone%3AGo1.21.7+label%3ACherryPickApproved).
|
||||||
|
|
||||||
* FEATURE: all VictoriaMetrics components: add support for TLS client certificate verification at `-httpListenAddr` (aka [mTLS](https://en.wikipedia.org/wiki/Mutual_authentication)). See [these docs](https://docs.victoriametrics.com/#mtls-protection). See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5458).
|
* FEATURE: all VictoriaMetrics components: add support for TLS client certificate verification at `-httpListenAddr` (aka [mTLS](https://en.wikipedia.org/wiki/Mutual_authentication)). See [these docs](https://docs.victoriametrics.com/#mtls-protection). See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5458).
|
||||||
|
* FEATURE: all VictoriaMetrics components: add support for accepting http requests over multiple distinct TCP addresses by starting VictoriaMetrics component with multiple `-httpListenAddr` command-line flags. For example, `./victoria-metrics -httpListenAddr=some-host:12345 -httpListenAddr=localhost:8428` starts VictoriaMetrics, which accepts incoming http requests at both `some-host:12345` and `localhost:8428`. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1470).
|
||||||
* FEATURE: all VictoriaMetrics components: add support for empty command flag values in short array notation. For example, `-remoteWrite.sendTimeout=',20s,'` specifies three `-remoteWrite.sendTimeout` values - the first and the last ones are default values (`30s` in this case), while the second one is `20s`.
|
* FEATURE: all VictoriaMetrics components: add support for empty command flag values in short array notation. For example, `-remoteWrite.sendTimeout=',20s,'` specifies three `-remoteWrite.sendTimeout` values - the first and the last ones are default values (`30s` in this case), while the second one is `20s`.
|
||||||
* FEATURE: all VictoriaMetrics components: do not close connections to `-httpListenAddr` every 2 minutes. This behavior didn't help spreading load among multiple backend servers behind load-balancing TCP proxy. Instead, it could lead to hard-to-debug issues like [this one](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1304#issuecomment-1636997037). If you still need periodically closing client connections because of some reason, then pass the desired timeout to `-http.connTimeout` command-line flag.
|
* FEATURE: all VictoriaMetrics components: do not close connections to `-httpListenAddr` every 2 minutes. This behavior didn't help spreading load among multiple backend servers behind load-balancing TCP proxy. Instead, it could lead to hard-to-debug issues like [this one](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1304#issuecomment-1636997037). If you still need periodically closing client connections because of some reason, then pass the desired timeout to `-http.connTimeout` command-line flag.
|
||||||
* FEATURE: [vmagent](https://docs.victoriametrics.com/vmagent.html) and [single-node VictoriaMetrics](https://docs.victoriametrics.com): add support for data ingestion via [DataDog lambda extension](https://docs.datadoghq.com/serverless/libraries_integrations/extension/) aka `/api/beta/sketches` endpoint. See [these docs](https://docs.victoriametrics.com/#how-to-send-data-from-datadog-agent) and [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3091). Thanks to @AndrewChubatiuk for [the pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5584).
|
* FEATURE: [vmagent](https://docs.victoriametrics.com/vmagent.html) and [single-node VictoriaMetrics](https://docs.victoriametrics.com): add support for data ingestion via [DataDog lambda extension](https://docs.datadoghq.com/serverless/libraries_integrations/extension/) aka `/api/beta/sketches` endpoint. See [these docs](https://docs.victoriametrics.com/#how-to-send-data-from-datadog-agent) and [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3091). Thanks to @AndrewChubatiuk for [the pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5584).
|
||||||
|
|
|
@ -101,8 +101,8 @@ func (a *ArrayString) Set(value string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseArrayValues(s string) []string {
|
func parseArrayValues(s string) []string {
|
||||||
if len(s) == 0 {
|
if s == "" {
|
||||||
return nil
|
return []string{""}
|
||||||
}
|
}
|
||||||
var values []string
|
var values []string
|
||||||
for {
|
for {
|
||||||
|
|
|
@ -174,7 +174,7 @@ func TestArrayDuration_Set(t *testing.T) {
|
||||||
t.Fatalf("unexpected values parsed;\ngot\n%q\nwant\n%q", result, expectedResult)
|
t.Fatalf("unexpected values parsed;\ngot\n%q\nwant\n%q", result, expectedResult)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f("", "")
|
f("", "42s")
|
||||||
f(`1m`, `1m0s`)
|
f(`1m`, `1m0s`)
|
||||||
f(`5m,1s,1h`, `5m0s,1s,1h0m0s`)
|
f(`5m,1s,1h`, `5m0s,1s,1h0m0s`)
|
||||||
f(`5m,,1h`, `5m0s,42s,1h0m0s`)
|
f(`5m,,1h`, `5m0s,42s,1h0m0s`)
|
||||||
|
@ -211,7 +211,6 @@ func TestArrayDuration_String(t *testing.T) {
|
||||||
t.Fatalf("unexpected string;\ngot\n%s\nwant\n%s", result, s)
|
t.Fatalf("unexpected string;\ngot\n%s\nwant\n%s", result, s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f("")
|
|
||||||
f("10s,1m0s")
|
f("10s,1m0s")
|
||||||
f("5m0s,1s")
|
f("5m0s,1s")
|
||||||
}
|
}
|
||||||
|
@ -237,7 +236,7 @@ func TestArrayBool_Set(t *testing.T) {
|
||||||
t.Fatalf("unexpected values parsed;\ngot\n%v\nwant\n%v", result, expectedResult)
|
t.Fatalf("unexpected values parsed;\ngot\n%v\nwant\n%v", result, expectedResult)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f("", "")
|
f("", "false")
|
||||||
f(`true`, `true`)
|
f(`true`, `true`)
|
||||||
f(`false,True,False`, `false,true,false`)
|
f(`false,True,False`, `false,true,false`)
|
||||||
f(`1,,False`, `true,false,false`)
|
f(`1,,False`, `true,false,false`)
|
||||||
|
@ -273,7 +272,6 @@ func TestArrayBool_String(t *testing.T) {
|
||||||
t.Fatalf("unexpected string;\ngot\n%s\nwant\n%s", result, s)
|
t.Fatalf("unexpected string;\ngot\n%s\nwant\n%s", result, s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f("")
|
|
||||||
f("true")
|
f("true")
|
||||||
f("true,false")
|
f("true,false")
|
||||||
f("false,true")
|
f("false,true")
|
||||||
|
@ -305,7 +303,7 @@ func TestArrayInt_Set(t *testing.T) {
|
||||||
t.Fatalf("unexpected values;\ngot\n%d\nwant\n%d", values, expectedValues)
|
t.Fatalf("unexpected values;\ngot\n%d\nwant\n%d", values, expectedValues)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f("", "", nil)
|
f("", "42", []int{42})
|
||||||
f(`1`, `1`, []int{1})
|
f(`1`, `1`, []int{1})
|
||||||
f(`-2,3,-64`, `-2,3,-64`, []int{-2, 3, -64})
|
f(`-2,3,-64`, `-2,3,-64`, []int{-2, 3, -64})
|
||||||
f(`,,-64,`, `42,42,-64,42`, []int{42, 42, -64, 42})
|
f(`,,-64,`, `42,42,-64,42`, []int{42, 42, -64, 42})
|
||||||
|
@ -342,7 +340,6 @@ func TestArrayInt_String(t *testing.T) {
|
||||||
t.Fatalf("unexpected string;\ngot\n%s\nwant\n%s", result, s)
|
t.Fatalf("unexpected string;\ngot\n%s\nwant\n%s", result, s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f("")
|
|
||||||
f("10,1")
|
f("10,1")
|
||||||
f("-5,1,123")
|
f("-5,1,123")
|
||||||
}
|
}
|
||||||
|
@ -371,7 +368,7 @@ func TestArrayBytes_Set(t *testing.T) {
|
||||||
t.Fatalf("unexpected values parsed;\ngot\n%s\nwant\n%s", result, expectedResult)
|
t.Fatalf("unexpected values parsed;\ngot\n%s\nwant\n%s", result, expectedResult)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f("", "")
|
f("", "42")
|
||||||
f(`1`, `1`)
|
f(`1`, `1`)
|
||||||
f(`-2,3,10kb`, `-2,3,10KB`)
|
f(`-2,3,10kb`, `-2,3,10KB`)
|
||||||
f(`,,10kb`, `42,42,10KB`)
|
f(`,,10kb`, `42,42,10KB`)
|
||||||
|
@ -409,7 +406,6 @@ func TestArrayBytes_String(t *testing.T) {
|
||||||
t.Fatalf("unexpected string;\ngot\n%s\nwant\n%s", result, s)
|
t.Fatalf("unexpected string;\ngot\n%s\nwant\n%s", result, s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f("")
|
|
||||||
f("10.5KiB,1")
|
f("10.5KiB,1")
|
||||||
f("-5,1,123MB")
|
f("-5,1,123MB")
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,6 @@ func TestDictIntSetSuccess(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
f("")
|
|
||||||
f("123")
|
f("123")
|
||||||
f("-234")
|
f("-234")
|
||||||
f("foo:123")
|
f("foo:123")
|
||||||
|
@ -107,8 +106,6 @@ func TestDictIntGet(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
f("", "", 123, 123)
|
|
||||||
f("", "foo", 123, 123)
|
|
||||||
f("foo:42", "", 123, 123)
|
f("foo:42", "", 123, 123)
|
||||||
f("foo:42", "foo", 123, 42)
|
f("foo:42", "foo", 123, 42)
|
||||||
f("532", "", 123, 532)
|
f("532", "", 123, 532)
|
||||||
|
|
|
@ -31,12 +31,14 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
tlsEnable = flag.Bool("tls", false, "Whether to enable TLS for incoming HTTP requests at -httpListenAddr (aka https). -tlsCertFile and -tlsKeyFile must be set if -tls is set. "+
|
tlsEnable = flagutil.NewArrayBool("tls", "Whether to enable TLS for incoming HTTP requests at the given -httpListenAddr (aka https). -tlsCertFile and -tlsKeyFile must be set if -tls is set. "+
|
||||||
"See also -mtls")
|
"See also -mtls")
|
||||||
tlsCertFile = flag.String("tlsCertFile", "", "Path to file with TLS certificate if -tls is set. Prefer ECDSA certs instead of RSA certs as RSA certs are slower. The provided certificate file is automatically re-read every second, so it can be dynamically updated")
|
tlsCertFile = flagutil.NewArrayString("tlsCertFile", "Path to file with TLS certificate for the corresponding -httpListenAddr if -tls is set. "+
|
||||||
tlsKeyFile = flag.String("tlsKeyFile", "", "Path to file with TLS key if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated")
|
"Prefer ECDSA certs instead of RSA certs as RSA certs are slower. The provided certificate file is automatically re-read every second, so it can be dynamically updated")
|
||||||
|
tlsKeyFile = flagutil.NewArrayString("tlsKeyFile", "Path to file with TLS key for the corresponding -httpListenAddr if -tls is set. "+
|
||||||
|
"The provided key file is automatically re-read every second, so it can be dynamically updated")
|
||||||
tlsCipherSuites = flagutil.NewArrayString("tlsCipherSuites", "Optional list of TLS cipher suites for incoming requests over HTTPS if -tls is set. See the list of supported cipher suites at https://pkg.go.dev/crypto/tls#pkg-constants")
|
tlsCipherSuites = flagutil.NewArrayString("tlsCipherSuites", "Optional list of TLS cipher suites for incoming requests over HTTPS if -tls is set. See the list of supported cipher suites at https://pkg.go.dev/crypto/tls#pkg-constants")
|
||||||
tlsMinVersion = flag.String("tlsMinVersion", "", "Optional minimum TLS version to use for incoming requests over HTTPS if -tls is set. "+
|
tlsMinVersion = flagutil.NewArrayString("tlsMinVersion", "Optional minimum TLS version to use for the corresponding -httpListenAddr if -tls is set. "+
|
||||||
"Supported values: TLS10, TLS11, TLS12, TLS13")
|
"Supported values: TLS10, TLS11, TLS12, TLS13")
|
||||||
|
|
||||||
pathPrefix = flag.String("http.pathPrefix", "", "An optional prefix to add to all the paths handled by http server. For example, if '-http.pathPrefix=/foo/bar' is set, "+
|
pathPrefix = flag.String("http.pathPrefix", "", "An optional prefix to add to all the paths handled by http server. For example, if '-http.pathPrefix=/foo/bar' is set, "+
|
||||||
|
@ -77,35 +79,51 @@ type server struct {
|
||||||
// In such cases the caller must serve the request.
|
// In such cases the caller must serve the request.
|
||||||
type RequestHandler func(w http.ResponseWriter, r *http.Request) bool
|
type RequestHandler func(w http.ResponseWriter, r *http.Request) bool
|
||||||
|
|
||||||
// Serve starts an http server on the given addr with the given optional rh.
|
// Serve starts an http server on the given addrs with the given optional rh.
|
||||||
//
|
//
|
||||||
// By default all the responses are transparently compressed, since egress traffic is usually expensive.
|
// By default all the responses are transparently compressed, since egress traffic is usually expensive.
|
||||||
//
|
//
|
||||||
// The compression is also disabled if -http.disableResponseCompression flag is set.
|
// The compression can be disabled by specifying -http.disableResponseCompression command-line flag.
|
||||||
//
|
//
|
||||||
// If useProxyProtocol is set to true, then the incoming connections are accepted via proxy protocol.
|
// If useProxyProtocol is set to true for the corresponding addr, then the incoming connections are accepted via proxy protocol.
|
||||||
// See https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt
|
// See https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt
|
||||||
func Serve(addr string, useProxyProtocol bool, rh RequestHandler) {
|
func Serve(addrs []string, useProxyProtocol *flagutil.ArrayBool, rh RequestHandler) {
|
||||||
if rh == nil {
|
if rh == nil {
|
||||||
rh = func(w http.ResponseWriter, r *http.Request) bool {
|
rh = func(w http.ResponseWriter, r *http.Request) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for idx, addr := range addrs {
|
||||||
|
if addr == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
useProxyProto := false
|
||||||
|
if useProxyProtocol != nil {
|
||||||
|
useProxyProto = useProxyProtocol.GetOptionalArg(idx)
|
||||||
|
}
|
||||||
|
go serve(addr, useProxyProto, rh, idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func serve(addr string, useProxyProtocol bool, rh RequestHandler, idx int) {
|
||||||
scheme := "http"
|
scheme := "http"
|
||||||
if *tlsEnable {
|
if tlsEnable.GetOptionalArg(idx) {
|
||||||
scheme = "https"
|
scheme = "https"
|
||||||
}
|
}
|
||||||
hostAddr := addr
|
hostAddr := addr
|
||||||
if strings.HasPrefix(hostAddr, ":") {
|
if strings.HasPrefix(hostAddr, ":") {
|
||||||
hostAddr = "127.0.0.1" + hostAddr
|
hostAddr = "127.0.0.1" + hostAddr
|
||||||
}
|
}
|
||||||
logger.Infof("starting http server at %s://%s/", scheme, hostAddr)
|
logger.Infof("starting server at %s://%s/", scheme, hostAddr)
|
||||||
logger.Infof("pprof handlers are exposed at %s://%s/debug/pprof/", scheme, hostAddr)
|
logger.Infof("pprof handlers are exposed at %s://%s/debug/pprof/", scheme, hostAddr)
|
||||||
var tlsConfig *tls.Config
|
var tlsConfig *tls.Config
|
||||||
if *tlsEnable {
|
if tlsEnable.GetOptionalArg(idx) {
|
||||||
tc, err := netutil.GetServerTLSConfig(*tlsCertFile, *tlsKeyFile, *tlsMinVersion, *tlsCipherSuites)
|
certFile := tlsCertFile.GetOptionalArg(idx)
|
||||||
|
keyFile := tlsKeyFile.GetOptionalArg(idx)
|
||||||
|
minVersion := tlsMinVersion.GetOptionalArg(idx)
|
||||||
|
tc, err := netutil.GetServerTLSConfig(certFile, keyFile, minVersion, *tlsCipherSuites)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatalf("cannot load TLS cert from -tlsCertFile=%q, -tlsKeyFile=%q, -tlsMinVersion=%q: %s", *tlsCertFile, *tlsKeyFile, *tlsMinVersion, err)
|
logger.Fatalf("cannot load TLS cert from -tlsCertFile=%q, -tlsKeyFile=%q, -tlsMinVersion=%q, -tlsCipherSuites=%q: %s", certFile, keyFile, minVersion, *tlsCipherSuites, err)
|
||||||
}
|
}
|
||||||
tlsConfig = tc
|
tlsConfig = tc
|
||||||
}
|
}
|
||||||
|
@ -168,15 +186,38 @@ func whetherToCloseConn(r *http.Request) bool {
|
||||||
|
|
||||||
var connDeadlineTimeKey = interface{}("connDeadlineSecs")
|
var connDeadlineTimeKey = interface{}("connDeadlineSecs")
|
||||||
|
|
||||||
// Stop stops the http server on the given addr, which has been started
|
// Stop stops the http server on the given addrs, which has been started via Serve func.
|
||||||
// via Serve func.
|
func Stop(addrs []string) error {
|
||||||
func Stop(addr string) error {
|
var errGlobalLock sync.Mutex
|
||||||
|
var errGlobal error
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
for _, addr := range addrs {
|
||||||
|
if addr == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
wg.Add(1)
|
||||||
|
go func(addr string) {
|
||||||
|
if err := stop(addr); err != nil {
|
||||||
|
errGlobalLock.Lock()
|
||||||
|
errGlobal = err
|
||||||
|
errGlobalLock.Unlock()
|
||||||
|
}
|
||||||
|
wg.Done()
|
||||||
|
}(addr)
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
return errGlobal
|
||||||
|
}
|
||||||
|
|
||||||
|
func stop(addr string) error {
|
||||||
serversLock.Lock()
|
serversLock.Lock()
|
||||||
s := servers[addr]
|
s := servers[addr]
|
||||||
delete(servers, addr)
|
delete(servers, addr)
|
||||||
serversLock.Unlock()
|
serversLock.Unlock()
|
||||||
if s == nil {
|
if s == nil {
|
||||||
err := fmt.Errorf("BUG: there is no http server at %q", addr)
|
err := fmt.Errorf("BUG: there is no server at %q", addr)
|
||||||
logger.Panicf("%s", err)
|
logger.Panicf("%s", err)
|
||||||
// The return is needed for golangci-lint: SA5011(related information): this check suggests that the pointer can be nil
|
// The return is needed for golangci-lint: SA5011(related information): this check suggests that the pointer can be nil
|
||||||
return err
|
return err
|
||||||
|
@ -593,9 +634,9 @@ func (e *ErrorWithStatusCode) Error() string {
|
||||||
return e.Err.Error()
|
return e.Err.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsTLS indicates is tls enabled or not
|
// IsTLS indicates is tls enabled or not for -httpListenAddr at the given idx.
|
||||||
func IsTLS() bool {
|
func IsTLS(idx int) bool {
|
||||||
return *tlsEnable
|
return tlsEnable.GetOptionalArg(idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPathPrefix - returns http server path prefix.
|
// GetPathPrefix - returns http server path prefix.
|
||||||
|
|
Loading…
Reference in a new issue