func init() { // create pid file pidfile.SetPidfilePath("/run/eirka/eirka-admin.pid") err := pidfile.Write() if err != nil { panic("Could not write pid file") } // Database connection settings dbase := db.Database{ User: local.Settings.Database.User, Password: local.Settings.Database.Password, Proto: local.Settings.Database.Protocol, Host: local.Settings.Database.Host, Database: local.Settings.Database.Database, MaxIdle: local.Settings.Admin.DatabaseMaxIdle, MaxConnections: local.Settings.Admin.DatabaseMaxConnections, } // Set up DB connection dbase.NewDb() // Get limits and stuff from database config.GetDatabaseSettings() // redis settings r := redis.Redis{ // Redis address and max pool connections Protocol: local.Settings.Redis.Protocol, Address: local.Settings.Redis.Host, MaxIdle: local.Settings.Admin.RedisMaxIdle, MaxConnections: local.Settings.Admin.RedisMaxConnections, } // Set up Redis connection r.NewRedisCache() // set auth middleware secret user.Secret = local.Settings.Session.Secret // set cors domains cors.SetDomains(local.Settings.CORS.Sites, strings.Split("GET,POST,DELETE", ",")) }
func TestSimple(t *testing.T) { p := tempfilename(t) defer os.Remove(p) pidfile.SetPidfilePath(p) if err := pidfile.Write(); err != nil { t.Fatal(err) } pid, err := pidfile.Read() if err != nil { t.Fatal(err) } if os.Getpid() != pid { t.Fatalf("was expecting %d but got %d", os.Getpid(), pid) } }
func TestMakesDirectories(t *testing.T) { dir := tempfilename(t) defer os.RemoveAll(dir) p := filepath.Join(dir, "pidfile") pidfile.SetPidfilePath(p) if err := pidfile.Write(); err != nil { t.Fatal(err) } pid, err := pidfile.Read() if err != nil { t.Fatal(err) } if os.Getpid() != pid { t.Fatalf("was expecting %d but got %d", os.Getpid(), pid) } }
func TestPidfileNotConfigured(t *testing.T) { pidfile.SetPidfilePath("") err := pidfile.Write() if err == nil { t.Fatal("was expecting an error") } if !pidfile.IsNotConfigured(err) { t.Fatalf("was expecting IsNotConfigured error but got: %s", err) } _, err = pidfile.Read() if err == nil { t.Fatal("was expecting an error") } if !pidfile.IsNotConfigured(err) { t.Fatalf("was expecting IsNotConfigured error but got: %s", err) } }
// start will initialize the gin server func start(name, address string, port int) { // init store u.Initialize(name) // create pid file pidfile.SetPidfilePath(fmt.Sprintf("/run/fluorescences/%s.pid", name)) err := pidfile.Write() if err != nil { panic("Could not write pid file") } // load the site templates t := template.Must(template.New("public").Funcs(u.TemplateFuncs).ParseGlob("templates/*.tmpl")) r := gin.Default() // load template into gin r.SetHTMLTemplate(t) // serve our static files r.Static("/css", "./css") r.Static("/images", "./images") r.StaticFile("/logo.png", "./logo.png") // if nothing matches r.NoRoute(c.ErrorController) // routing group for public handlers public := r.Group("/") public.GET("/", blog.ViewController) public.GET("/blog/:page", blog.ViewController) public.GET("/categories", category.IndexController) public.GET("/comics/:id/:page", gallery.IndexController) public.GET("/comic/:id/:page", m.Private(), gallery.ViewController) public.GET("/image/:id/:page", m.Private(), image.ViewController) public.GET("/gallery/key/:id", keys.InputController) public.GET("/commission", com.ViewController) // routing group for admin handlers authed := r.Group("/admin") // add a CSRF cookie and session token to requests authed.Use(csrf.Cookie()) authed.GET("/login", admin.LoginController) authed.POST("/login", admin.AuthController) authed.GET("/logout", admin.LogoutController) // ensure the user is authenticated authed.Use(m.Auth()) authed.GET("/panel", admin.PanelController) authed.GET("/blog", blog.NewController) authed.GET("/blog/edit/:id", blog.EditController) authed.GET("/link/edit/:id", link.EditController) authed.GET("/category", category.NewController) authed.GET("/category/edit/:id", category.EditController) authed.GET("/gallery", gallery.NewController) authed.GET("/gallery/edit/:id", gallery.EditController) authed.GET("/image/edit/:gallery/:image", image.EditController) // authenticates the CSRF session token authed.Use(csrf.Verify()) authed.POST("/settings/update", admin.UpdateController) authed.POST("/blog/new", blog.PostController) authed.POST("/blog/delete", blog.DeleteController) authed.POST("/blog/update", blog.UpdateController) authed.POST("/link/new", link.NewController) authed.POST("/link/delete", link.DeleteController) authed.POST("/link/update", link.UpdateController) authed.POST("/category/new", category.PostController) authed.POST("/category/delete", category.DeleteController) authed.POST("/category/update", category.UpdateController) authed.POST("/gallery/new", gallery.PostController) authed.POST("/gallery/delete", gallery.DeleteController) authed.POST("/gallery/update", gallery.UpdateController) authed.POST("/gallery/private", gallery.PrivateController) authed.POST("/gallery/image/new", image.NewController) authed.POST("/gallery/image/delete", image.DeleteController) authed.POST("/gallery/image/update", image.UpdateController) authed.POST("/gallery/key/new", keys.NewController) authed.POST("/gallery/key/delete", keys.DeleteController) authed.POST("/commission/update", com.UpdateController) authed.POST("/password/update", admin.PasswordController) s := &http.Server{ Addr: fmt.Sprintf("%s:%d", address, port), Handler: r, } gracehttp.Serve(s) }
func main() { z := flag.String("z", "", "zipper") port := flag.Int("p", 8080, "port") l := flag.Int("l", 20, "concurrency limit") cacheType := flag.String("cache", "mem", "cache type to use") mc := flag.String("mc", "", "comma separated memcached server list") memsize := flag.Int("memsize", 0, "in-memory cache size in MB (0 is unlimited)") cpus := flag.Int("cpus", 0, "number of CPUs to use") tz := flag.String("tz", "", "timezone,offset to use for dates with no timezone") graphiteHost := flag.String("graphite", "", "graphite destination host") logdir := flag.String("logdir", "/var/log/carbonapi/", "logging directory") logtostdout := flag.Bool("stdout", false, "log also to stdout") interval := flag.Duration("i", 60*time.Second, "interval to report internal statistics to graphite") idleconns := flag.Int("idleconns", 10, "max idle connections") pidFile := flag.String("pid", "", "pidfile (default: empty, don't create pidfile)") flag.Parse() if *logdir == "" { mlog.SetRawStream(os.Stdout) } else { mlog.SetOutput(*logdir, "carbonapi", *logtostdout) } expvar.NewString("BuildVersion").Set(BuildVersion) logger.Logln("starting carbonapi", BuildVersion) if p := os.Getenv("PORT"); p != "" { *port, _ = strconv.Atoi(p) } Limiter = newLimiter(*l) if *z == "" { logger.Fatalln("no zipper provided") } if _, err := url.Parse(*z); err != nil { logger.Fatalln("unable to parze zipper:", err) } logger.Logln("using zipper", *z) Zipper = zipper{ z: *z, client: &http.Client{ Transport: &http.Transport{ MaxIdleConnsPerHost: *idleconns, }, }, } switch *cacheType { case "memcache": if *mc == "" { logger.Fatalln("memcache cache requested but no memcache servers provided") } servers := strings.Split(*mc, ",") logger.Logln("using memcache servers:", servers) queryCache = &memcachedCache{client: memcache.New(servers...)} findCache = &memcachedCache{client: memcache.New(servers...)} case "mem": qcache := &expireCache{ec: ecache.New(uint64(*memsize * 1024 * 1024))} queryCache = qcache go queryCache.(*expireCache).ec.ApproximateCleaner(10 * time.Second) findCache = &expireCache{ec: ecache.New(0)} go findCache.(*expireCache).ec.ApproximateCleaner(10 * time.Second) Metrics.CacheSize = expvar.Func(func() interface{} { return qcache.ec.Size() }) expvar.Publish("cache_size", Metrics.CacheSize) Metrics.CacheItems = expvar.Func(func() interface{} { return qcache.ec.Items() }) expvar.Publish("cache_items", Metrics.CacheItems) case "null": queryCache = &nullCache{} findCache = &nullCache{} } if *tz != "" { fields := strings.Split(*tz, ",") if len(fields) != 2 { logger.Fatalf("expected two fields for tz,seconds, got %d", len(fields)) } var err error offs, err := strconv.Atoi(fields[1]) if err != nil { logger.Fatalf("unable to parse seconds: %s: %s", fields[1], err) } defaultTimeZone = time.FixedZone(fields[0], offs) logger.Logf("using fixed timezone %s, offset %d ", defaultTimeZone.String(), offs) } if *cpus != 0 { logger.Logln("using GOMAXPROCS", *cpus) runtime.GOMAXPROCS(*cpus) } if envhost := os.Getenv("GRAPHITEHOST") + ":" + os.Getenv("GRAPHITEPORT"); envhost != ":" || *graphiteHost != "" { var host string switch { case envhost != ":" && *graphiteHost != "": host = *graphiteHost case envhost != ":": host = envhost case *graphiteHost != "": host = *graphiteHost } logger.Logln("Using graphite host", host) logger.Logln("setting stats interval to", *interval) // register our metrics with graphite graphite := g2g.NewGraphite(host, *interval, 10*time.Second) hostname, _ := os.Hostname() hostname = strings.Replace(hostname, ".", "_", -1) graphite.Register(fmt.Sprintf("carbon.api.%s.requests", hostname), Metrics.Requests) graphite.Register(fmt.Sprintf("carbon.api.%s.request_cache_hits", hostname), Metrics.RequestCacheHits) graphite.Register(fmt.Sprintf("carbon.api.%s.find_requests", hostname), Metrics.FindRequests) graphite.Register(fmt.Sprintf("carbon.api.%s.find_cache_hits", hostname), Metrics.FindCacheHits) graphite.Register(fmt.Sprintf("carbon.api.%s.render_requests", hostname), Metrics.RenderRequests) graphite.Register(fmt.Sprintf("carbon.api.%s.memcache_timeouts", hostname), Metrics.MemcacheTimeouts) if Metrics.CacheSize != nil { graphite.Register(fmt.Sprintf("carbon.api.%s.cache_size", hostname), Metrics.CacheSize) graphite.Register(fmt.Sprintf("carbon.api.%s.cache_items", hostname), Metrics.CacheItems) } go mstats.Start(*interval) graphite.Register(fmt.Sprintf("carbon.api.%s.alloc", hostname), &mstats.Alloc) graphite.Register(fmt.Sprintf("carbon.api.%s.total_alloc", hostname), &mstats.TotalAlloc) graphite.Register(fmt.Sprintf("carbon.api.%s.num_gc", hostname), &mstats.NumGC) graphite.Register(fmt.Sprintf("carbon.api.%s.pause_ns", hostname), &mstats.PauseNS) } render := func(w http.ResponseWriter, r *http.Request) { var stats renderStats t0 := time.Now() renderHandler(w, r, &stats) since := time.Since(t0) logger.Logln(r.RequestURI, since.Nanoseconds()/int64(time.Millisecond), stats.zipperRequests) } if *pidFile != "" { pidfile.SetPidfilePath(*pidFile) err := pidfile.Write() if err != nil { logger.Fatalln("error during pidfile.Write():", err) } } r := http.DefaultServeMux r.HandleFunc("/render/", render) r.HandleFunc("/render", render) r.HandleFunc("/metrics/find/", findHandler) r.HandleFunc("/metrics/find", findHandler) r.HandleFunc("/info/", passthroughHandler) r.HandleFunc("/info", passthroughHandler) r.HandleFunc("/lb_check", lbcheckHandler) r.HandleFunc("/", usageHandler) logger.Logln("listening on port", *port) handler := handlers.CompressHandler(r) handler = handlers.CORS()(handler) handler = handlers.CombinedLoggingHandler(mlog.GetOutput(), handler) err := gracehttp.Serve(&http.Server{ Addr: ":" + strconv.Itoa(*port), Handler: handler, }) if err != nil { logger.Fatalln(err) } }
func initialiseSystem(arguments map[string]interface{}) { // Enable command mode for k := range CommandModeOptions { v := arguments[k] if v == true { HandleCommandModeArgs(arguments) os.Exit(0) } if v != nil && v != false { HandleCommandModeArgs(arguments) os.Exit(0) } } filename := "/etc/tyk/tyk.conf" value, _ := arguments["--conf"] if value != nil { log.WithFields(logrus.Fields{ "prefix": "main", }).Debug(fmt.Sprintf("Using %s for configuration", value.(string))) filename = arguments["--conf"].(string) } else { log.WithFields(logrus.Fields{ "prefix": "main", }).Debug("No configuration file defined, will try to use default (./tyk.conf)") } loadConfig(filename, &config) if config.Storage.Type != "redis" { log.WithFields(logrus.Fields{ "prefix": "main", }).Fatal("Redis connection details not set, please ensure that the storage type is set to Redis and that the connection parameters are correct.") } setupGlobals() port, _ := arguments["--port"] if port != nil { portNum, err := strconv.Atoi(port.(string)) if err != nil { log.WithFields(logrus.Fields{ "prefix": "main", }).Error("Port specified in flags must be a number!") log.WithFields(logrus.Fields{ "prefix": "main", }).Error(err) } else { config.ListenPort = portNum } } doMemoryProfile, _ = arguments["--memprofile"].(bool) doCpuProfile, _ = arguments["--cpuprofile"].(bool) doDebug, _ := arguments["--debug"] log.Level = logrus.InfoLevel if doDebug == true { log.Level = logrus.DebugLevel log.WithFields(logrus.Fields{ "prefix": "main", }).Debug("Enabling debug-level output") } // Enable all the loggers setupLogger() if config.PIDFileLocation == "" { config.PIDFileLocation = "/var/run/tyk-gateway.pid" } log.WithFields(logrus.Fields{ "prefix": "main", }).Info("PIDFile location set to: ", config.PIDFileLocation) pidfile.SetPidfilePath(config.PIDFileLocation) pfErr := pidfile.Write() if pfErr != nil { log.WithFields(logrus.Fields{ "prefix": "main", }).Error("Failed to write PIDFile: ", pfErr) } GetHostDetails() //doInstrumentation, _ := arguments["--log-instrumentation"].(bool) //SetupInstrumentation(doInstrumentation) SetupInstrumentation(true) go StartPeriodicStateBackup(&LE_MANAGER) }