func createAndInitSinksOrDie(sinkAddresses flags.Uris, historicalSource string) (core.DataSink, *metricsink.MetricSink, core.HistoricalSource) { sinksFactory := sinks.NewSinkFactory() metricSink, sinkList, histSource := sinksFactory.BuildAll(sinkAddresses, historicalSource) if metricSink == nil { glog.Fatal("Failed to create metric sink") } if histSource == nil && len(historicalSource) > 0 { glog.Fatal("Failed to use a sink as a historical metrics source") } for _, sink := range sinkList { glog.Infof("Starting with %s", sink.Name()) } sinkManager, err := sinks.NewDataSinkManager(sinkList, sinks.DefaultSinkExportDataTimeout, sinks.DefaultSinkStopTimeout) if err != nil { glog.Fatalf("Failed to created sink manager: %v", err) } return sinkManager, metricSink, histSource }
func main() { defer glog.Flush() flag.Var(&argSources, "source", "source(s) to watch") flag.Var(&argSinks, "sink", "external sink(s) that receive data") flag.Parse() setMaxProcs() glog.Infof(strings.Join(os.Args, " ")) glog.Infof("Heapster version %v", version.HeapsterVersion) if err := validateFlags(); err != nil { glog.Fatal(err) } // sources if len(argSources) != 1 { glog.Fatal("Wrong number of sources specified") } sourceFactory := sources.NewSourceFactory() sourceProvider, err := sourceFactory.BuildAll(argSources) if err != nil { glog.Fatalf("Failed to create source provide: %v", err) } sourceManager, err := sources.NewSourceManager(sourceProvider, sources.DefaultMetricsScrapeTimeout) if err != nil { glog.Fatalf("Failed to create source manager: %v", err) } // sinks sinksFactory := sinks.NewSinkFactory() metricSink, sinkList, historicalSource := sinksFactory.BuildAll(argSinks, *argHistoricalSource) if metricSink == nil { glog.Fatal("Failed to create metric sink") } if historicalSource == nil && len(*argHistoricalSource) > 0 { glog.Fatal("Failed to use a sink as a historical metrics source") } for _, sink := range sinkList { glog.Infof("Starting with %s", sink.Name()) } sinkManager, err := sinks.NewDataSinkManager(sinkList, sinks.DefaultSinkExportDataTimeout, sinks.DefaultSinkStopTimeout) if err != nil { glog.Fatalf("Failed to created sink manager: %v", err) } // data processors metricsToAggregate := []string{ core.MetricCpuUsageRate.Name, core.MetricMemoryUsage.Name, core.MetricCpuRequest.Name, core.MetricCpuLimit.Name, core.MetricMemoryRequest.Name, core.MetricMemoryLimit.Name, } metricsToAggregateForNode := []string{ core.MetricCpuRequest.Name, core.MetricCpuLimit.Name, core.MetricMemoryRequest.Name, core.MetricMemoryLimit.Name, } dataProcessors := []core.DataProcessor{ // Convert cumulaties to rate processors.NewRateCalculator(core.RateMetricsMapping), } kubernetesUrl, err := getKubernetesAddress(argSources) if err != nil { glog.Fatalf("Failed to get kubernetes address: %v", err) } podLister, err := getPodLister(kubernetesUrl) if err != nil { glog.Fatalf("Failed to create podLister: %v", err) } podBasedEnricher, err := processors.NewPodBasedEnricher(podLister) if err != nil { glog.Fatalf("Failed to create PodBasedEnricher: %v", err) } dataProcessors = append(dataProcessors, podBasedEnricher) namespaceBasedEnricher, err := processors.NewNamespaceBasedEnricher(kubernetesUrl) if err != nil { glog.Fatalf("Failed to create NamespaceBasedEnricher: %v", err) } dataProcessors = append(dataProcessors, namespaceBasedEnricher) // then aggregators dataProcessors = append(dataProcessors, processors.NewPodAggregator(), &processors.NamespaceAggregator{ MetricsToAggregate: metricsToAggregate, }, &processors.NodeAggregator{ MetricsToAggregate: metricsToAggregateForNode, }, &processors.ClusterAggregator{ MetricsToAggregate: metricsToAggregate, }) nodeAutoscalingEnricher, err := processors.NewNodeAutoscalingEnricher(kubernetesUrl) if err != nil { glog.Fatalf("Failed to create NodeAutoscalingEnricher: %v", err) } dataProcessors = append(dataProcessors, nodeAutoscalingEnricher) // main manager manager, err := manager.NewManager(sourceManager, dataProcessors, sinkManager, *argMetricResolution, manager.DefaultScrapeOffset, manager.DefaultMaxParallelism) if err != nil { glog.Fatalf("Failed to create main manager: %v", err) } manager.Start() handler := setupHandlers(metricSink, podLister, historicalSource) addr := fmt.Sprintf("%s:%d", *argIp, *argPort) glog.Infof("Starting heapster on port %d", *argPort) mux := http.NewServeMux() promHandler := prometheus.Handler() if len(*argTLSCertFile) > 0 && len(*argTLSKeyFile) > 0 { if len(*argTLSClientCAFile) > 0 { authPprofHandler, err := newAuthHandler(handler) if err != nil { glog.Fatalf("Failed to create authorized pprof handler: %v", err) } handler = authPprofHandler authPromHandler, err := newAuthHandler(promHandler) if err != nil { glog.Fatalf("Failed to create authorized prometheus handler: %v", err) } promHandler = authPromHandler } mux.Handle("/", handler) mux.Handle("/metrics", promHandler) // If allowed users is set, then we need to enable Client Authentication if len(*argAllowedUsers) > 0 { server := &http.Server{ Addr: addr, Handler: mux, TLSConfig: &tls.Config{ClientAuth: tls.RequestClientCert}, } glog.Fatal(server.ListenAndServeTLS(*argTLSCertFile, *argTLSKeyFile)) } else { glog.Fatal(http.ListenAndServeTLS(addr, *argTLSCertFile, *argTLSKeyFile, mux)) } } else { mux.Handle("/", handler) mux.Handle("/metrics", promHandler) glog.Fatal(http.ListenAndServe(addr, mux)) } }