web.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // Copyright 2014 Unknwon
  2. // Copyright 2014 Torkel Ödegaard
  3. package cmd
  4. import (
  5. "fmt"
  6. "io/ioutil"
  7. "net/http"
  8. "os"
  9. "path"
  10. "path/filepath"
  11. "strconv"
  12. "github.com/Unknwon/macaron"
  13. "github.com/codegangsta/cli"
  14. "github.com/macaron-contrib/session"
  15. "github.com/grafana/grafana/pkg/api"
  16. "github.com/grafana/grafana/pkg/log"
  17. "github.com/grafana/grafana/pkg/middleware"
  18. "github.com/grafana/grafana/pkg/plugins"
  19. "github.com/grafana/grafana/pkg/services/eventpublisher"
  20. "github.com/grafana/grafana/pkg/setting"
  21. "github.com/grafana/grafana/pkg/social"
  22. )
  23. var Web = cli.Command{
  24. Name: "web",
  25. Usage: "Starts Grafana backend & web server",
  26. Description: "Starts Grafana backend & web server",
  27. Action: runWeb,
  28. }
  29. func newMacaron() *macaron.Macaron {
  30. macaron.Env = setting.Env
  31. m := macaron.New()
  32. m.Use(middleware.Logger())
  33. m.Use(macaron.Recovery())
  34. if setting.EnableGzip {
  35. m.Use(macaron.Gziper())
  36. }
  37. mapStatic(m, "", "public")
  38. mapStatic(m, "app", "app")
  39. mapStatic(m, "css", "css")
  40. mapStatic(m, "img", "img")
  41. mapStatic(m, "fonts", "fonts")
  42. m.Use(session.Sessioner(setting.SessionOptions))
  43. m.Use(macaron.Renderer(macaron.RenderOptions{
  44. Directory: path.Join(setting.StaticRootPath, "views"),
  45. IndentJSON: macaron.Env != macaron.PROD,
  46. Delims: macaron.Delims{Left: "[[", Right: "]]"},
  47. }))
  48. m.Use(middleware.GetContextHandler())
  49. return m
  50. }
  51. func mapStatic(m *macaron.Macaron, dir string, prefix string) {
  52. m.Use(macaron.Static(
  53. path.Join(setting.StaticRootPath, dir),
  54. macaron.StaticOptions{
  55. SkipLogging: true,
  56. Prefix: prefix,
  57. },
  58. ))
  59. }
  60. func runWeb(c *cli.Context) {
  61. initRuntime(c)
  62. writePIDFile(c)
  63. social.NewOAuthService()
  64. eventpublisher.Init()
  65. plugins.Init()
  66. var err error
  67. m := newMacaron()
  68. api.Register(m)
  69. listenAddr := fmt.Sprintf("%s:%s", setting.HttpAddr, setting.HttpPort)
  70. log.Info("Listen: %v://%s%s", setting.Protocol, listenAddr, setting.AppSubUrl)
  71. switch setting.Protocol {
  72. case setting.HTTP:
  73. err = http.ListenAndServe(listenAddr, m)
  74. case setting.HTTPS:
  75. err = http.ListenAndServeTLS(listenAddr, setting.CertFile, setting.KeyFile, m)
  76. default:
  77. log.Fatal(4, "Invalid protocol: %s", setting.Protocol)
  78. }
  79. if err != nil {
  80. log.Fatal(4, "Fail to start server: %v", err)
  81. }
  82. }
  83. func writePIDFile(c *cli.Context) {
  84. path := c.GlobalString("pidfile")
  85. if path == "" {
  86. return
  87. }
  88. // Ensure the required directory structure exists.
  89. err := os.MkdirAll(filepath.Dir(path), 0700)
  90. if err != nil {
  91. log.Fatal(3, "Failed to verify pid directory", err)
  92. }
  93. // Retrieve the PID and write it.
  94. pid := strconv.Itoa(os.Getpid())
  95. if err := ioutil.WriteFile(path, []byte(pid), 0644); err != nil {
  96. log.Fatal(3, "Failed to write pidfile", err)
  97. }
  98. }