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) }
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), } }