Example #1
0
func loggerAndStats() (log.Modular, metrics.Aggregator) {
	logConf := log.NewLoggerConfig()
	logConf.LogLevel = "OFF"

	logger := log.NewLogger(os.Stdout, logConf)
	stats := metrics.DudType{}

	return logger, stats
}
Example #2
0
func loggerAndStats() (*log.Logger, *log.Stats) {
	logConf := log.DefaultLoggerConfig()
	logConf.LogLevel = "OFF"

	logger := log.NewLogger(os.Stdout, logConf)
	stats := log.NewStats(log.DefaultStatsConfig())

	return logger, stats
}
Example #3
0
func main() {
	var (
		err       error
		closeChan = make(chan bool)
	)

	leapsConfig := LeapsConfig{
		NumProcesses:         runtime.NumCPU(),
		LoggerConfig:         log.DefaultLoggerConfig(),
		StatsConfig:          log.DefaultStatsConfig(),
		RiemannConfig:        log.NewRiemannClientConfig(),
		StoreConfig:          store.NewConfig(),
		AuthenticatorConfig:  auth.NewConfig(),
		CuratorConfig:        lib.DefaultCuratorConfig(),
		HTTPServerConfig:     net.DefaultHTTPServerConfig(),
		InternalServerConfig: net.NewInternalServerConfig(),
		StatsServerConfig:    log.DefaultStatsServerConfig(),
	}

	// A list of default config paths to check for if not explicitly defined
	defaultPaths := []string{}

	/* If we manage to get the path of our executable then we want to try and find config files
	 * relative to that path, we always check from the parent folder since we assume leaps is
	 * stored within the bin folder.
	 */
	if executablePath, err := path.BinaryPath(); err == nil {
		defaultPaths = append(defaultPaths, filepath.Join(executablePath, "..", "config.yaml"))
		defaultPaths = append(defaultPaths, filepath.Join(executablePath, "..", "config", "leaps.yaml"))
		defaultPaths = append(defaultPaths, filepath.Join(executablePath, "..", "config.json"))
		defaultPaths = append(defaultPaths, filepath.Join(executablePath, "..", "config", "leaps.json"))
	}

	defaultPaths = append(defaultPaths, []string{
		filepath.Join(".", "leaps.yaml"),
		filepath.Join(".", "leaps.json"),
		"/etc/leaps.yaml",
		"/etc/leaps.json",
		"/etc/leaps/config.yaml",
		"/etc/leaps/config.json",
	}...)

	// Load configuration etc
	if !util.Bootstrap(&leapsConfig, defaultPaths...) {
		return
	}

	if len(*sharePathOverride) > 0 {
		leapsConfig.AuthenticatorConfig.FileConfig.SharePath = *sharePathOverride
		leapsConfig.StoreConfig.StoreDirectory = *sharePathOverride
	}

	runtime.GOMAXPROCS(leapsConfig.NumProcesses)

	// Logging and stats aggregation
	logger := log.NewLogger(os.Stdout, leapsConfig.LoggerConfig)
	stats := log.NewStats(leapsConfig.StatsConfig)

	if riemannClient, err := log.NewRiemannClient(leapsConfig.RiemannConfig); err == nil {
		logger.UseRiemann(riemannClient)
		stats.UseRiemann(riemannClient)

		defer riemannClient.Close()
	} else if err != log.ErrEmptyConfigAddress {
		fmt.Fprintln(os.Stderr, fmt.Sprintf("Riemann client error: %v\n", err))
		return
	}
	defer stats.Close()

	fmt.Printf("Launching a leaps instance, use CTRL+C to close.\n\n")

	// Document storage engine
	documentStore, err := store.Factory(leapsConfig.StoreConfig)
	if err != nil {
		fmt.Fprintln(os.Stderr, fmt.Sprintf("Document store error: %v\n", err))
		return
	}

	// Authenticator
	authenticator, err := auth.Factory(leapsConfig.AuthenticatorConfig, logger, stats)
	if err != nil {
		fmt.Fprintln(os.Stderr, fmt.Sprintf("Authenticator error: %v\n", err))
		return
	}

	// Curator of documents
	curator, err := lib.NewCurator(leapsConfig.CuratorConfig, logger, stats, authenticator, documentStore)
	if err != nil {
		fmt.Fprintln(os.Stderr, fmt.Sprintf("Curator error: %v\n", err))
		return
	}
	defer curator.Close()

	// HTTP API
	leapHTTP, err := net.CreateHTTPServer(curator, leapsConfig.HTTPServerConfig, logger, stats)
	if err != nil {
		fmt.Fprintln(os.Stderr, fmt.Sprintf("HTTP error: %v\n", err))
		return
	}
	defer leapHTTP.Stop()

	go func() {
		if httperr := leapHTTP.Listen(); httperr != nil {
			fmt.Fprintln(os.Stderr, fmt.Sprintf("Http listen error: %v\n", httperr))
		}
		closeChan <- true
	}()

	var adminRegister register.EndpointRegister

	// Internal admin HTTP API
	if 0 < len(leapsConfig.InternalServerConfig.Address) {
		adminHTTP, err := net.NewInternalServer(curator, leapsConfig.InternalServerConfig, logger, stats)
		if err != nil {
			fmt.Fprintln(os.Stderr, fmt.Sprintf("Admin HTTP error: %v\n", err))
			return
		}
		adminRegister = adminHTTP

		go func() {
			if httperr := adminHTTP.Listen(); httperr != nil {
				fmt.Fprintln(os.Stderr, fmt.Sprintf("Admin HTTP listen error: %v\n", httperr))
			}
			closeChan <- true
		}()
	}

	// Register for allowing other components to set API endpoints.
	register := newEndpointsRegister(leapHTTP, adminRegister)
	if err = authenticator.RegisterHandlers(register); err != nil {
		fmt.Fprintln(os.Stderr, fmt.Sprintf("Register authentication endpoints failed: %v\n", err))
		return
	}

	// Internal Statistics HTTP API
	statsServer, err := log.NewStatsServer(leapsConfig.StatsServerConfig, logger, stats)
	if err != nil {
		fmt.Fprintln(os.Stderr, fmt.Sprintf("Stats error: %v\n", err))
		return
	}

	go func() {
		if statserr := statsServer.Listen(); statserr != nil {
			fmt.Fprintln(os.Stderr, fmt.Sprintf("Stats server listen error: %v\n", statserr))
		}
	}()

	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)

	// Wait for termination signal
	select {
	case <-sigChan:
	case <-closeChan:
	}
}
Example #4
0
func logger() log.Modular {
	logConf := log.NewLoggerConfig()
	logConf.LogLevel = "OFF"
	return log.NewLogger(os.Stdout, logConf)
}
Example #5
0
func main() {
	var (
		err       error
		closeChan = make(chan bool)
	)

	flag.Usage = func() {
		fmt.Println(`Usage: leaps [flags...] [path/to/share]

If a path is not specified the current directory is shared instead.
`)
		flag.PrintDefaults()
	}

	flag.Parse()

	targetPath := "."
	if flag.NArg() == 1 {
		targetPath = flag.Arg(0)
	}

	// Logging and metrics aggregation
	logConf := log.NewLoggerConfig()
	logConf.Prefix = "leaps"
	logConf.LogLevel = *logLevel

	logger := log.NewLogger(os.Stdout, logConf)

	statConf := metrics.NewConfig()
	statConf.Prefix = "leaps"

	stats, err := metrics.New(statConf)
	if err != nil {
		fmt.Fprintln(os.Stderr, fmt.Sprintf("Metrics init error: %v\n", err))
		return
	}
	defer stats.Close()

	logger.Infoln("Launching a leaps instance, use CTRL+C to close.")

	// Document storage engine
	docStore, err := store.NewFile(".")
	if err != nil {
		fmt.Fprintln(os.Stderr, fmt.Sprintf("Document store error: %v\n", err))
		return
	}

	// Authenticator
	storeConf := acl.NewFileExistsConfig()
	storeConf.Path = targetPath
	storeConf.ShowHidden = *showHidden

	authenticator := acl.NewFileExists(storeConf, logger)

	// Curator of documents
	curatorConf := curator.NewConfig()
	curator, err := curator.New(curatorConf, logger, stats, authenticator, docStore)
	if err != nil {
		fmt.Fprintln(os.Stderr, fmt.Sprintf("Curator error: %v\n", err))
		return
	}
	defer curator.Close()

	handle("/endpoints", "Lists all available endpoints (including this one).",
		func(w http.ResponseWriter, r *http.Request) {
			data, reqErr := json.Marshal(endpoints)
			if reqErr != nil {
				logger.Errorf("Failed to serve endpoints: %v\n", reqErr)
				http.Error(w, reqErr.Error(), http.StatusInternalServerError)
				return
			}
			w.Header().Add("Content-Type", "application/json")
			w.Write(data)
		})

	handle("/files", "Returns a list of available files and a map of users per document.",
		func(w http.ResponseWriter, r *http.Request) {
			var reqErr error
			var users map[string][]string
			if users, reqErr = curator.GetUsers(time.Second); reqErr == nil {
				var data []byte
				data, reqErr = json.Marshal(struct {
					Paths []string            `json:"paths"`
					Users map[string][]string `json:"users"`
				}{
					Paths: authenticator.GetPaths(),
					Users: users,
				})
				if reqErr == nil {
					w.Write(data)
				}
			}
			if reqErr != nil {
				http.Error(w, reqErr.Error(), http.StatusInternalServerError)
				logger.Errorf("Failed to serve users: %v\n", reqErr)
				return
			}
			w.Header().Add("Content-Type", "application/json")
		})

	handle("/stats", "Lists all aggregated metrics as a json blob.", stats.JSONHandler())

	wwwPath := gopath.Join("/", *subdirPath)
	stripPath := ""
	if wwwPath != "/" {
		wwwPath = wwwPath + "/"
		stripPath = wwwPath
	}
	if len(*debugWWWDir) > 0 {
		logger.Warnf("Serving web files from alternative www dir: %v\n", *debugWWWDir)
		http.Handle(wwwPath, http.StripPrefix(stripPath, http.FileServer(http.Dir(*debugWWWDir))))
	} else {
		http.Handle(wwwPath, http.StripPrefix(stripPath, http.FileServer(assetFS())))
	}
	http.Handle(gopath.Join("/", *subdirPath, "/leaps/ws"),
		websocket.Handler(leaphttp.WebsocketHandler(curator, time.Second, logger, stats)))

	go func() {
		logger.Infof("Serving HTTP requests at: %v%v\n", *httpAddress, *subdirPath)
		if httperr := http.ListenAndServe(*httpAddress, nil); httperr != nil {
			fmt.Fprintln(os.Stderr, fmt.Sprintf("HTTP listen error: %v\n", httperr))
		}
		closeChan <- true
	}()

	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)

	// Wait for termination signal
	select {
	case <-sigChan:
	case <-closeChan:
	}
}