예제 #1
0
파일: main.go 프로젝트: ryandotsmith/l2met
func main() {
	if cfg.PrintVersion {
		fmt.Println(conf.Version)
		os.Exit(0)
	}

	// Can be passed to other modules
	// as an internal metrics channel.
	mchan := metchan.New(cfg)
	mchan.Start()

	// The store will be used by receivers and outlets.
	var st store.Store
	if len(cfg.RedisHost) > 0 {
		redisStore := store.NewRedisStore(cfg)
		redisStore.Mchan = mchan
		st = redisStore
		fmt.Printf("at=initialized-redis-store\n")
	} else {
		st = store.NewMemStore()
		fmt.Printf("at=initialized-mem-store\n")
	}

	if cfg.UseOutlet {
		rdr := reader.New(cfg, st)
		rdr.Mchan = mchan
		outlet := outlet.NewLibratoOutlet(cfg, rdr)
		outlet.Mchan = mchan
		outlet.Start()
	}

	if cfg.UsingReciever {
		recv := receiver.NewReceiver(cfg, st)
		recv.Mchan = mchan
		recv.Start()
		http.Handle("/logs", recv)
	}

	http.Handle("/health", st)
	http.HandleFunc("/sign", auth.ServeHTTP)
	e := http.ListenAndServe(fmt.Sprintf(":%d", cfg.Port), nil)
	if e != nil {
		log.Fatal("Unable to start HTTP server.")
	}
	fmt.Printf("at=l2met-initialized port=%d\n", cfg.Port)
}
예제 #2
0
파일: main.go 프로젝트: Jwpe/l2met
func main() {
	cfg = conf.New()
	flag.Parse()

	// Can be passed to other modules
	// as an internal metrics channel.
	mchan := metchan.New(cfg.Verbose, cfg.MetchanUrl)
	mchan.Start()

	// The store will be used by receivers and outlets.
	var st store.Store
	if len(cfg.RedisHost) > 0 {
		redisStore := store.NewRedisStore(cfg)
		redisStore.Mchan = mchan
		st = redisStore
		fmt.Printf("at=initialized-redis-store\n")
	} else {
		st = store.NewMemStore()
		fmt.Printf("at=initialized-mem-store\n")
	}

	if cfg.UseOutlet {
		rdr := reader.New(cfg, st)
		rdr.Mchan = mchan
		outlet := outlet.NewLibratoOutlet(cfg, rdr)
		outlet.Mchan = mchan
		outlet.Start()
	}

	if cfg.UsingReciever {
		recv := receiver.NewReceiver(cfg, st)
		recv.Mchan = mchan
		recv.Start()
		if cfg.Verbose {
			go recv.Report()
		}
		http.HandleFunc("/logs",
			func(w http.ResponseWriter, r *http.Request) {
				startReceiveT := time.Now()
				if r.Method != "POST" {
					http.Error(w, "Invalid Request", 400)
					return
				}
				user, pass, err := auth.ParseAndDecrypt(r)
				if err != nil {
					http.Error(w, "Invalid Request", 400)
					return
				}
				b, err := ioutil.ReadAll(r.Body)
				r.Body.Close()
				if err != nil {
					http.Error(w, "Invalid Request", 400)
					return
				}
				v := r.URL.Query()
				v.Add("user", user)
				v.Add("password", pass)
				recv.Receive(b, v)
				mchan.Time("http.accept", startReceiveT)
			})
	}

	// The only thing that constitutes a healthy l2met
	// is the health of the store. In some cases, this might mean
	// a Redis health check.
	http.HandleFunc("/health",
		func(w http.ResponseWriter, r *http.Request) {
			ok := st.Health()
			if !ok {
				msg := "Store is unavailable."
				fmt.Printf("error=%q\n", msg)
				http.Error(w, msg, 500)
			}
		})

	http.HandleFunc("/sign",
		func(w http.ResponseWriter, r *http.Request) {
			if r.Method != "POST" {
				http.Error(w, "Method must be POST.", 400)
				return
			}
			l := r.Header.Get("Authorization")
			user, _, err := auth.ParseRaw(l)
			if err != nil {
				http.Error(w, "Unable to parse headers.", 400)
				return
			}
			matched := false
			for i := range cfg.Secrets {
				if user == cfg.Secrets[i] {
					matched = true
					break
				}
			}
			if !matched {
				http.Error(w, "Authentication failed.", 401)
				return
			}
			b, err := ioutil.ReadAll(r.Body)
			r.Body.Close()
			if err != nil {
				http.Error(w, "Unable to read body.", 400)
				return
			}
			signed, err := auth.EncryptAndSign(b)
			if err != nil {
				http.Error(w, "Unable to sign body.", 500)
				return
			}
			fmt.Fprint(w, string(signed))
		})

	// Start the HTTP server.
	e := http.ListenAndServe(fmt.Sprintf(":%d", cfg.Port), nil)
	if e != nil {
		log.Fatal("Unable to start HTTP server.")
	}
	fmt.Printf("at=l2met-initialized port=%d\n", cfg.Port)
}