2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Copyright 2015 The Prometheus Authors
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Licensed under the Apache License, Version 2.0 (the "License");
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// you may not use this file except in compliance with the License.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// You may obtain a copy of the License at
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// http://www.apache.org/licenses/LICENSE-2.0
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Unless required by applicable law or agreed to in writing, software
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// distributed under the License is distributed on an "AS IS" BASIS,
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// See the License for the specific language governing permissions and
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// limitations under the License.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-02-18 06:52:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// The main package for the Prometheus server executable.
  
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								package  main  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:23:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"fmt" 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-21 00:48:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"net" 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-06 18:22:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"net/http" 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									_  "net/http/pprof"  // Comment this line to disable pprof endpoint.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-21 00:48:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"net/url" 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"os" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"os/signal" 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-20 23:38:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"path/filepath" 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-04 19:10:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"runtime" 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-21 00:48:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"strings" 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"syscall" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"time" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-12 02:45:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/go-kit/kit/log" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/go-kit/kit/log/level" 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-21 00:48:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/pkg/errors" 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-24 00:04:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/prometheus/client_golang/prometheus" 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-21 00:48:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/prometheus/common/model" 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-05 19:46:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/prometheus/common/version" 
							 
						 
					
						
							
								
									
										
											 
										
											
												promql: Allow per-query contexts.
For Weaveworks' Frankenstein, we need to support multitenancy. In
Frankenstein, we initially solved this without modifying the promql
package at all: we constructed a new promql.Engine for every
query and injected a storage implementation into that engine which would
be primed to only collect data for a given user.
This is problematic to upstream, however. Prometheus assumes that there
is only one engine: the query concurrency gate is part of the engine,
and the engine contains one central cancellable context to shut down all
queries. Also, creating a new engine for every query seems like overkill.
Thus, we want to be able to pass per-query contexts into a single engine.
This change gets rid of the promql.Engine's built-in base context and
allows passing in a per-query context instead. Central cancellation of
all queries is still possible by deriving all passed-in contexts from
one central one, but this is now the responsibility of the caller. The
central query context is now created in main() and passed into the
relevant components (web handler / API, rule manager).
In a next step, the per-query context would have to be passed to the
storage implementation, so that the storage can implement multi-tenancy
or other features based on the contextual information.
											 
										 
										
											2016-09-15 19:52:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"golang.org/x/net/context" 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-20 23:38:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"gopkg.in/alecthomas/kingpin.v2" 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-09 00:34:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									k8s_runtime  "k8s.io/apimachinery/pkg/util/runtime" 
							 
						 
					
						
							
								
									
										
											 
										
											
												promql: Allow per-query contexts.
For Weaveworks' Frankenstein, we need to support multitenancy. In
Frankenstein, we initially solved this without modifying the promql
package at all: we constructed a new promql.Engine for every
query and injected a storage implementation into that engine which would
be primed to only collect data for a given user.
This is problematic to upstream, however. Prometheus assumes that there
is only one engine: the query concurrency gate is part of the engine,
and the engine contains one central cancellable context to shut down all
queries. Also, creating a new engine for every query seems like overkill.
Thus, we want to be able to pass per-query contexts into a single engine.
This change gets rid of the promql.Engine's built-in base context and
allows passing in a per-query context instead. Central cancellation of
all queries is still possible by deriving all passed-in contexts from
one central one, but this is now the responsibility of the caller. The
central query context is now created in main() and passed into the
relevant components (web handler / API, rule manager).
In a next step, the per-query context would have to be passed to the
storage implementation, so that the storage can implement multi-tenancy
or other features based on the contextual information.
											 
										 
										
											2016-09-15 19:52:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-06 18:22:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/mwitkow/go-conntrack" 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-09 00:34:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/prometheus/common/promlog" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									promlogflag  "github.com/prometheus/common/promlog/flag" 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"github.com/prometheus/prometheus/config" 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-01 19:37:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/prometheus/prometheus/notifier" 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"github.com/prometheus/prometheus/promql" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/prometheus/prometheus/retrieval" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/prometheus/prometheus/rules" 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/prometheus/prometheus/storage" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/prometheus/prometheus/storage/remote" 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 16:27:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/prometheus/prometheus/storage/tsdb" 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"github.com/prometheus/prometheus/web" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-21 00:48:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									configSuccess  =  prometheus . NewGauge ( prometheus . GaugeOpts { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Namespace :  "prometheus" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Name :       "config_last_reload_successful" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Help :       "Whether the last configuration reload attempt was successful." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									configSuccessTime  =  prometheus . NewGauge ( prometheus . GaugeOpts { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Namespace :  "prometheus" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Name :       "config_last_reload_success_timestamp_seconds" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Help :       "Timestamp of the last successful configuration reload." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  init ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									prometheus . MustRegister ( version . NewCollector ( "prometheus" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  main ( )  {  
						 
					
						
							
								
									
										
										
										
											2017-09-04 19:10:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  os . Getenv ( "DEBUG" )  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										runtime . SetBlockProfileRate ( 20 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										runtime . SetMutexProfileFraction ( 20 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-21 00:48:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cfg  :=  struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										printVersion  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										configFile    string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										localStoragePath  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										notifier          notifier . Options 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										notifierTimeout   model . Duration 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										queryEngine       promql . EngineOptions 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										web               web . Options 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tsdb              tsdb . Options 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										lookbackDelta     model . Duration 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										webTimeout        model . Duration 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										queryTimeout      model . Duration 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										prometheusURL  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-12 02:45:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										logLevel  promlog . AllowedLevel 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-21 00:48:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										notifier :  notifier . Options { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Registerer :  prometheus . DefaultRegisterer , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-20 23:38:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									a  :=  kingpin . New ( filepath . Base ( os . Args [ 0 ] ) ,  "The Prometheus monitoring server" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a . Version ( version . Print ( "prometheus" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a . HelpFlag . Short ( 'h' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a . Flag ( "config.file" ,  "Prometheus configuration file path." ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Default ( "prometheus.yml" ) . StringVar ( & cfg . configFile ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-17 06:00:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									a . Flag ( "web.listen-address" ,  "Address to listen on for UI, API, and telemetry." ) . 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-20 23:38:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Default ( "0.0.0.0:9090" ) . StringVar ( & cfg . web . ListenAddress ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a . Flag ( "web.read-timeout" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"Maximum duration before timing out read of the request, and closing idle connections." ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Default ( "5m" ) . SetValue ( & cfg . webTimeout ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a . Flag ( "web.max-connections" ,  "Maximum number of simultaneous connections." ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Default ( "512" ) . IntVar ( & cfg . web . MaxConnections ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a . Flag ( "web.external-url" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"The URL under which Prometheus is externally reachable (for example, if Prometheus is served via a reverse proxy). Used for generating relative and absolute links back to Prometheus itself. If the URL has a path portion, it will be used to prefix all HTTP endpoints served by Prometheus. If omitted, relevant URL components will be derived automatically." ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										PlaceHolder ( "<URL>" ) . StringVar ( & cfg . prometheusURL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a . Flag ( "web.route-prefix" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"Prefix for the internal routes of web endpoints. Defaults to path of --web.external-url." ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										PlaceHolder ( "<path>" ) . StringVar ( & cfg . web . RoutePrefix ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a . Flag ( "web.user-assets" ,  "Path to static asset directory, available at /user." ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										PlaceHolder ( "<path>" ) . StringVar ( & cfg . web . UserAssetsPath ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-07-10 21:44:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									a . Flag ( "web.enable-lifecycle" ,  "Enable shutdown and reload via HTTP request." ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Default ( "false" ) . BoolVar ( & cfg . web . EnableLifecycle ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-20 23:38:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-07-21 05:48:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									a . Flag ( "web.enable-admin-api" ,  "Enables API endpoints for admin control actions." ) . 
							 
						 
					
						
							
								
									
										
										
										
											2017-07-10 15:29:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Default ( "false" ) . BoolVar ( & cfg . web . EnableAdminAPI ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-20 23:38:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									a . Flag ( "web.console.templates" ,  "Path to the console template directory, available at /consoles." ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Default ( "consoles" ) . StringVar ( & cfg . web . ConsoleTemplatesPath ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a . Flag ( "web.console.libraries" ,  "Path to the console library directory." ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Default ( "console_libraries" ) . StringVar ( & cfg . web . ConsoleLibrariesPath ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a . Flag ( "storage.tsdb.path" ,  "Base path for metrics storage." ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Default ( "data/" ) . StringVar ( & cfg . localStoragePath ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a . Flag ( "storage.tsdb.min-block-duration" ,  "Minimum duration of a data block before being persisted." ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Default ( "2h" ) . SetValue ( & cfg . tsdb . MinBlockDuration ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a . Flag ( "storage.tsdb.max-block-duration" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"Maximum duration compacted blocks may span. (Defaults to 10% of the retention period)" ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										PlaceHolder ( "<duration>" ) . SetValue ( & cfg . tsdb . MaxBlockDuration ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a . Flag ( "storage.tsdb.retention" ,  "How long to retain samples in the storage." ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Default ( "15d" ) . SetValue ( & cfg . tsdb . Retention ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-22 21:02:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									a . Flag ( "storage.tsdb.no-lockfile" ,  "Do not create lockfile in data directory." ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Default ( "false" ) . BoolVar ( & cfg . tsdb . NoLockfile ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-20 23:38:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									a . Flag ( "alertmanager.notification-queue-capacity" ,  "The capacity of the queue for pending alert manager notifications." ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Default ( "10000" ) . IntVar ( & cfg . notifier . QueueCapacity ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-07-21 05:48:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									a . Flag ( "alertmanager.timeout" ,  "Timeout for sending alerts to Alertmanager." ) . 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-21 00:48:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Default ( "10s" ) . SetValue ( & cfg . notifierTimeout ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-20 23:38:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a . Flag ( "query.lookback-delta" ,  "The delta difference allowed for retrieving metrics during expression evaluations." ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Default ( "5m" ) . SetValue ( & cfg . lookbackDelta ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a . Flag ( "query.timeout" ,  "Maximum time a query may take before being aborted." ) . 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-21 00:48:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Default ( "2m" ) . SetValue ( & cfg . queryTimeout ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-20 23:38:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a . Flag ( "query.max-concurrency" ,  "Maximum number of queries executed concurrently." ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Default ( "20" ) . IntVar ( & cfg . queryEngine . MaxConcurrentQueries ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-09-09 00:34:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									promlogflag . AddFlags ( a ,  & cfg . logLevel ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-21 00:48:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_ ,  err  :=  a . Parse ( os . Args [ 1 : ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-09 22:25:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										fmt . Fprintln ( os . Stderr ,  errors . Wrapf ( err ,  "Error parsing commandline arguments" ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-20 23:38:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										a . Usage ( os . Args [ 1 : ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										os . Exit ( 2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-21 00:48:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cfg . web . ExternalURL ,  err  =  computeExternalURL ( cfg . prometheusURL ,  cfg . web . ListenAddress ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fmt . Fprintln ( os . Stderr ,  errors . Wrapf ( err ,  "parse external URL %q" ,  cfg . prometheusURL ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-20 23:38:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										os . Exit ( 2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-21 00:48:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cfg . web . ReadTimeout  =  time . Duration ( cfg . webTimeout ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Default -web.route-prefix to path of -web.external-url.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  cfg . web . RoutePrefix  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cfg . web . RoutePrefix  =  cfg . web . ExternalURL . Path 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// RoutePrefix must always be at least '/'.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cfg . web . RoutePrefix  =  "/"  +  strings . Trim ( cfg . web . RoutePrefix ,  "/" ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-21 00:48:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  cfg . tsdb . MaxBlockDuration  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cfg . tsdb . MaxBlockDuration  =  cfg . tsdb . Retention  /  10 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2015-09-02 01:18:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-21 00:48:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									promql . LookbackDelta  =  time . Duration ( cfg . lookbackDelta ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cfg . queryEngine . Timeout  =  time . Duration ( cfg . queryTimeout ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-05 19:46:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-12 02:45:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									logger  :=  promlog . New ( cfg . logLevel ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-09-09 00:34:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// XXX(fabxc): Kubernetes does background logging which we can only customize by modifying
 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-12 02:45:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// a global variable.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Ultimately, here is the best place to set it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									k8s_runtime . ErrorHandlers  =  [ ] func ( error ) { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										func ( err  error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											level . Error ( log . With ( logger ,  "component" ,  "k8s_client_runtime" ) ) . Log ( "err" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-16 18:22:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-23 15:49:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									level . Info ( logger ) . Log ( "msg" ,  "Starting Prometheus" ,  "version" ,  version . Info ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-12 02:45:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									level . Info ( logger ) . Log ( "build_context" ,  version . BuildContext ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									level . Info ( logger ) . Log ( "host_details" ,  Uname ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-05 19:46:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 00:00:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Make sure that sighup handler is registered with a redirect to the channel before the potentially
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// long and synchronous tsdb init.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hup  :=  make ( chan  os . Signal ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hupReady  :=  make ( chan  bool ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									signal . Notify ( hup ,  syscall . SIGHUP ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-12 02:45:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-09-18 18:32:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										localStorage   =  & tsdb . ReadyStorage { } 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-18 19:08:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										remoteStorage  =  remote . NewStorage ( log . With ( logger ,  "component" ,  "remote" ) ,  localStorage . StartTime ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-18 18:32:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										fanoutStorage  =  storage . NewFanout ( logger ,  localStorage ,  remoteStorage ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-12 02:45:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-20 04:47:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-12 02:45:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cfg . queryEngine . Logger  =  log . With ( logger ,  "component" ,  "query engine" ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-26 07:32:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-12 02:45:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										notifier        =  notifier . New ( & cfg . notifier ,  log . With ( logger ,  "component" ,  "notifier" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										targetManager   =  retrieval . NewTargetManager ( fanoutStorage ,  log . With ( logger ,  "component" ,  "target manager" ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										queryEngine     =  promql . NewEngine ( fanoutStorage ,  & cfg . queryEngine ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 06:58:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ctx ,  cancelCtx  =  context . WithCancel ( context . Background ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-26 07:32:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									ruleManager  :=  rules . NewManager ( & rules . ManagerOptions { 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Appendable :   fanoutStorage , 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-13 21:48:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Notifier :     notifier , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										QueryEngine :  queryEngine , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Context :      ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ExternalURL :  cfg . web . ExternalURL , 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-12 02:45:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Logger :       log . With ( logger ,  "component" ,  "rule manager" ) , 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 06:58:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cfg . web . Context  =  ctx 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-18 18:32:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cfg . web . TSDB  =  localStorage . Get 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cfg . web . Storage  =  fanoutStorage 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 06:58:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cfg . web . QueryEngine  =  queryEngine 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cfg . web . TargetManager  =  targetManager 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cfg . web . RuleManager  =  ruleManager 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-24 01:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cfg . web . Notifier  =  notifier 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 06:58:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cfg . web . Version  =  & web . PrometheusVersion { 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-05 19:46:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Version :    version . Version , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Revision :   version . Revision , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Branch :     version . Branch , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										BuildUser :  version . BuildUser , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										BuildDate :  version . BuildDate , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										GoVersion :  version . GoVersion , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 06:58:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cfg . web . Flags  =  map [ string ] string { } 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-20 23:38:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  f  :=  range  a . Model ( ) . Flags  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 06:58:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										cfg . web . Flags [ f . Name ]  =  f . Value . String ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-20 23:38:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 06:58:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-09-09 00:34:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									webHandler  :=  web . New ( log . With ( logger ,  "component" ,  "web" ) ,  & cfg . web ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-06 18:22:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Monitor outgoing connections on default transport with conntrack.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									http . DefaultTransport . ( * http . Transport ) . DialContext  =  conntrack . NewDialContextFunc ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										conntrack . DialWithTracing ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-09-18 18:32:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reloadables  :=  [ ] Reloadable { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										remoteStorage , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										targetManager , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ruleManager , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										webHandler , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										notifier , 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Wait for reload or termination signals. Start the handler for SIGHUP as
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// early as possible, but ignore it until we are ready to handle reloading
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// our config.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									go  func ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										<- hupReady 
							 
						 
					
						
							
								
									
										
										
										
											2015-08-11 15:08:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											select  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  <- hup : 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-16 18:22:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  err  :=  reloadConfig ( cfg . configFile ,  logger ,  reloadables ... ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-12 02:45:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													level . Error ( logger ) . Log ( "msg" ,  "Error reloading config" ,  "err" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 22:24:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  rc  :=  <- webHandler . Reload ( ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-16 18:22:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  err  :=  reloadConfig ( cfg . configFile ,  logger ,  reloadables ... ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-12 02:45:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													level . Error ( logger ) . Log ( "msg" ,  "Error reloading config" ,  "err" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 22:24:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													rc  <-  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													rc  <-  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2015-08-11 15:08:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-09-18 18:32:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Start all components while we wait for TSDB to open but only load
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// initial config and mark ourselves as ready after it completed.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dbOpen  :=  make ( chan  struct { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									go  func ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										defer  close ( dbOpen ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										level . Info ( logger ) . Log ( "msg" ,  "Starting TSDB" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										db ,  err  :=  tsdb . Open ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											cfg . localStoragePath , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											log . With ( logger ,  "component" ,  "tsdb" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											prometheus . DefaultRegisterer , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											& cfg . tsdb , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											level . Error ( logger ) . Log ( "msg" ,  "Opening storage failed" ,  "err" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											os . Exit ( 1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-18 18:32:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										level . Info ( logger ) . Log ( "msg" ,  "TSDB started" ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-18 19:08:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										startTimeMargin  :=  int64 ( time . Duration ( cfg . tsdb . MinBlockDuration ) . Seconds ( )  *  1000 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										localStorage . Set ( db ,  startTimeMargin ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-18 18:32:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-20 04:47:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-09-02 01:18:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									prometheus . MustRegister ( configSuccess ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									prometheus . MustRegister ( configSuccessTime ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 04:59:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// The notifier is a dependency of the rule manager. It has to be
 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-18 23:47:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// started before and torn down afterwards.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-01 19:37:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									go  notifier . Run ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  notifier . Stop ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-01-18 23:47:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									go  ruleManager . Run ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  ruleManager . Stop ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									go  targetManager . Run ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  targetManager . Stop ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-01-18 23:47:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Shutting down the query engine before the rule manager will cause pending queries
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// to be canceled and ensures a quick shutdown of the rule manager.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 06:58:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  cancelCtx ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-07-06 20:38:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									errc  :=  make ( chan  error ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									go  func ( )  {  errc  <-  webHandler . Run ( ctx )  } ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-09-18 18:32:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									<- dbOpen 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  reloadConfig ( cfg . configFile ,  logger ,  reloadables ... ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										level . Error ( logger ) . Log ( "msg" ,  "Error loading config" ,  "err" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										os . Exit ( 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  func ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  fanoutStorage . Close ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											level . Error ( logger ) . Log ( "msg" ,  "Error stopping storage" ,  "err" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Wait for reload or termination signals.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									close ( hupReady )  // Unblock SIGHUP handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-07-26 08:47:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Set web server to ready.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									webHandler . Ready ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-12 02:45:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									level . Info ( logger ) . Log ( "msg" ,  "Server is ready to receive requests." ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-07-26 08:47:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-28 20:35:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									term  :=  make ( chan  os . Signal ,  1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									signal . Notify ( term ,  os . Interrupt ,  syscall . SIGTERM ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									select  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  <- term : 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-12 02:45:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										level . Warn ( logger ) . Log ( "msg" ,  "Received SIGTERM, exiting gracefully..." ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									case  <- webHandler . Quit ( ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-12 02:45:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										level . Warn ( logger ) . Log ( "msg" ,  "Received termination request via web service, exiting gracefully..." ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-07-06 20:38:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  err  :=  <- errc : 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-12 02:45:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										level . Error ( logger ) . Log ( "msg" ,  "Error starting web server, exiting gracefully" ,  "err" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-12 02:45:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									level . Info ( logger ) . Log ( "msg" ,  "See you next time!" ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Reloadable things can change their internal state to match a new config
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// and handle failure gracefully.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  Reloadable  interface  {  
						 
					
						
							
								
									
										
										
										
											2016-07-11 22:24:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ApplyConfig ( * config . Config )  error 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-16 18:22:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  reloadConfig ( filename  string ,  logger  log . Logger ,  rls  ... Reloadable )  ( err  error )  {  
						 
					
						
							
								
									
										
										
										
											2017-08-12 02:45:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									level . Info ( logger ) . Log ( "msg" ,  "Loading configuration file" ,  "filename" ,  filename ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-09-02 01:18:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  func ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 22:24:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-09-02 01:18:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											configSuccess . Set ( 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											configSuccessTime . Set ( float64 ( time . Now ( ) . Unix ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											configSuccess . Set ( 0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-08-06 00:30:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									conf ,  err  :=  config . LoadFile ( filename ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-08 15:19:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  fmt . Errorf ( "couldn't load configuration (--config.file=%s): %v" ,  filename ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 09:23:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									failed  :=  false 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									for  _ ,  rl  :=  range  rls  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 09:23:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  :=  rl . ApplyConfig ( conf ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-12 02:45:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											level . Error ( logger ) . Log ( "msg" ,  "Failed to apply configuration" ,  "err" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 09:23:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											failed  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 22:24:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 09:23:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  failed  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-08 15:19:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  fmt . Errorf ( "one or more errors occurred while applying the new configuration (--config.file=%s)" ,  filename ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 09:23:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-15 18:36:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2017-06-21 00:48:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-05 18:16:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  startsOrEndsWithQuote ( s  string )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  strings . HasPrefix ( s ,  "\"" )  ||  strings . HasPrefix ( s ,  "'" )  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										strings . HasSuffix ( s ,  "\"" )  ||  strings . HasSuffix ( s ,  "'" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-21 00:48:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// computeExternalURL computes a sanitized external URL from a raw input. It infers unset
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// URL parts from the OS and the given listen address.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  computeExternalURL ( u ,  listenAddr  string )  ( * url . URL ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  u  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hostname ,  err  :=  os . Hostname ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_ ,  port ,  err  :=  net . SplitHostPort ( listenAddr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										u  =  fmt . Sprintf ( "http://%s:%s/" ,  hostname ,  port ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-05 18:16:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  startsOrEndsWithQuote ( u )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "URL must not begin or end with quotes" ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-21 00:48:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									eu ,  err  :=  url . Parse ( u ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ppref  :=  strings . TrimRight ( eu . Path ,  "/" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ppref  !=  ""  &&  ! strings . HasPrefix ( ppref ,  "/" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ppref  =  "/"  +  ppref 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									eu . Path  =  ppref 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  eu ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}