func loggerAndStats() (log.Modular, metrics.Aggregator) { logConf := log.NewLoggerConfig() logConf.LogLevel = "OFF" logger := log.NewLogger(os.Stdout, logConf) stats := metrics.DudType{} return logger, stats }
func logger() log.Modular { logConf := log.NewLoggerConfig() logConf.LogLevel = "OFF" return log.NewLogger(os.Stdout, logConf) }
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: } }