Exemple #1
0
func main() {
	// Flag domain.
	fs := pflag.NewFlagSet("default", pflag.ExitOnError)
	fs.Usage = func() {
		fmt.Fprintf(os.Stderr, "DESCRIPTION\n")
		fmt.Fprintf(os.Stderr, "  fluxd is the agent of flux.\n")
		fmt.Fprintf(os.Stderr, "\n")
		fmt.Fprintf(os.Stderr, "FLAGS\n")
		fs.PrintDefaults()
	}
	// This mirrors how kubectl extracts information from the environment.
	var (
		listenAddr        = fs.StringP("listen", "l", ":3031", "Listen address where /metrics will be served")
		fluxsvcAddress    = fs.String("fluxsvc-address", "wss://cloud.weave.works/api/flux", "Address of the fluxsvc to connect to.")
		token             = fs.String("token", "", "Token to use to authenticate with flux service")
		kubernetesKubectl = fs.String("kubernetes-kubectl", "", "Optional, explicit path to kubectl tool")
	)
	fs.Parse(os.Args)

	// Logger component.
	var logger log.Logger
	{
		logger = log.NewLogfmtLogger(os.Stderr)
		logger = log.NewContext(logger).With("ts", log.DefaultTimestampUTC)
		logger = log.NewContext(logger).With("caller", log.DefaultCaller)
	}

	// Platform component.
	var k8s platform.Platform
	{
		restClientConfig, err := restclient.InClusterConfig()
		if err != nil {
			logger.Log("err", err)
			os.Exit(1)
		}

		// When adding a new platform, don't just bash it in. Create a Platform
		// or Cluster interface in package platform, and have kubernetes.Cluster
		// and your new platform implement that interface.
		logger := log.NewContext(logger).With("component", "platform")
		logger.Log("host", restClientConfig.Host)

		cluster, err := kubernetes.NewCluster(restClientConfig, *kubernetesKubectl, logger)
		if err != nil {
			logger.Log("err", err)
			os.Exit(1)
		}

		if services, err := cluster.AllServices("", nil); err != nil {
			logger.Log("services", err)
		} else {
			logger.Log("services", len(services))
		}

		k8s = cluster
	}

	// Instrumentation
	var (
		daemonMetrics transport.DaemonMetrics
	)
	{
		k8s = platform.Instrument(k8s, platform.NewMetrics())
		daemonMetrics.ConnectionDuration = prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
			Namespace: "flux",
			Subsystem: "fluxd",
			Name:      "connection_duration_seconds",
			Help:      "Duration in seconds of the current connection to fluxsvc. Zero means unconnected.",
		}, []string{"target"})
	}

	// Connect to fluxsvc
	daemonLogger := log.NewContext(logger).With("component", "client")
	daemon, err := transport.NewDaemon(
		http.DefaultClient,
		flux.Token(*token),
		transport.NewRouter(),
		*fluxsvcAddress,
		k8s,
		daemonLogger,
		daemonMetrics,
	)
	if err != nil {
		logger.Log("err", err)
		os.Exit(1)
	}
	defer daemon.Close()

	// Mechanical components.
	errc := make(chan error)
	go func() {
		c := make(chan os.Signal)
		signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
		errc <- fmt.Errorf("%s", <-c)
	}()

	// HTTP transport component, for metrics
	go func() {
		logger.Log("addr", *listenAddr)
		mux := http.NewServeMux()
		mux.Handle("/metrics", promhttp.Handler())
		errc <- http.ListenAndServe(*listenAddr, mux)
	}()

	// Go!
	logger.Log("exiting", <-errc)
}
Exemple #2
0
func (s *Server) instrumentPlatform(instID flux.InstanceID, p platform.Platform) platform.Platform {
	return &loggingPlatform{
		platform.Instrument(p, s.metrics.PlatformMetrics),
		log.NewContext(s.logger).With("instanceID", instID),
	}
}