main.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. package main
  2. import (
  3. "context"
  4. "flag"
  5. "fmt"
  6. "io/ioutil"
  7. "os"
  8. "os/signal"
  9. "path/filepath"
  10. "runtime"
  11. "strconv"
  12. "syscall"
  13. "time"
  14. "golang.org/x/sync/errgroup"
  15. "github.com/grafana/grafana/pkg/log"
  16. "github.com/grafana/grafana/pkg/login"
  17. "github.com/grafana/grafana/pkg/metrics"
  18. "github.com/grafana/grafana/pkg/plugins"
  19. "github.com/grafana/grafana/pkg/services/cleanup"
  20. "github.com/grafana/grafana/pkg/services/eventpublisher"
  21. "github.com/grafana/grafana/pkg/services/notifications"
  22. "github.com/grafana/grafana/pkg/services/search"
  23. "github.com/grafana/grafana/pkg/services/sqlstore"
  24. "github.com/grafana/grafana/pkg/setting"
  25. "github.com/grafana/grafana/pkg/social"
  26. "github.com/grafana/grafana/pkg/services/alerting"
  27. _ "github.com/grafana/grafana/pkg/services/alerting/conditions"
  28. _ "github.com/grafana/grafana/pkg/services/alerting/notifiers"
  29. _ "github.com/grafana/grafana/pkg/tsdb/graphite"
  30. _ "github.com/grafana/grafana/pkg/tsdb/prometheus"
  31. _ "github.com/grafana/grafana/pkg/tsdb/testdata"
  32. )
  33. var version = "3.1.0"
  34. var commit = "NA"
  35. var buildstamp string
  36. var build_date string
  37. var configFile = flag.String("config", "", "path to config file")
  38. var homePath = flag.String("homepath", "", "path to grafana install/home path, defaults to working directory")
  39. var pidFile = flag.String("pidfile", "", "path to pid file")
  40. var exitChan = make(chan int)
  41. func init() {
  42. runtime.GOMAXPROCS(runtime.NumCPU())
  43. }
  44. func main() {
  45. v := flag.Bool("v", false, "prints current version and exits")
  46. flag.Parse()
  47. if *v {
  48. fmt.Printf("Version %s (commit: %s)\n", version, commit)
  49. os.Exit(0)
  50. }
  51. buildstampInt64, _ := strconv.ParseInt(buildstamp, 10, 64)
  52. if buildstampInt64 == 0 {
  53. buildstampInt64 = time.Now().Unix()
  54. }
  55. setting.BuildVersion = version
  56. setting.BuildCommit = commit
  57. setting.BuildStamp = buildstampInt64
  58. appContext, shutdownFn := context.WithCancel(context.Background())
  59. grafanaGroup, appContext := errgroup.WithContext(appContext)
  60. go listenToSystemSignals(shutdownFn, grafanaGroup)
  61. flag.Parse()
  62. writePIDFile()
  63. initRuntime()
  64. initSql()
  65. metrics.Init()
  66. search.Init()
  67. login.Init()
  68. social.NewOAuthService()
  69. eventpublisher.Init()
  70. plugins.Init()
  71. // init alerting
  72. if setting.AlertingEnabled {
  73. engine := alerting.NewEngine()
  74. grafanaGroup.Go(func() error { return engine.Run(appContext) })
  75. }
  76. // cleanup service
  77. cleanUpService := cleanup.NewCleanUpService()
  78. grafanaGroup.Go(func() error { return cleanUpService.Run(appContext) })
  79. if err := notifications.Init(); err != nil {
  80. log.Fatal(3, "Notification service failed to initialize", err)
  81. }
  82. exitCode := StartServer()
  83. grafanaGroup.Wait()
  84. exitChan <- exitCode
  85. }
  86. func initRuntime() {
  87. err := setting.NewConfigContext(&setting.CommandLineArgs{
  88. Config: *configFile,
  89. HomePath: *homePath,
  90. Args: flag.Args(),
  91. })
  92. if err != nil {
  93. log.Fatal(3, err.Error())
  94. }
  95. logger := log.New("main")
  96. logger.Info("Starting Grafana", "version", version, "commit", commit, "compiled", time.Unix(setting.BuildStamp, 0))
  97. setting.LogConfigurationInfo()
  98. }
  99. func initSql() {
  100. sqlstore.NewEngine()
  101. sqlstore.EnsureAdminUser()
  102. }
  103. func writePIDFile() {
  104. if *pidFile == "" {
  105. return
  106. }
  107. // Ensure the required directory structure exists.
  108. err := os.MkdirAll(filepath.Dir(*pidFile), 0700)
  109. if err != nil {
  110. log.Fatal(3, "Failed to verify pid directory", err)
  111. }
  112. // Retrieve the PID and write it.
  113. pid := strconv.Itoa(os.Getpid())
  114. if err := ioutil.WriteFile(*pidFile, []byte(pid), 0644); err != nil {
  115. log.Fatal(3, "Failed to write pidfile", err)
  116. }
  117. }
  118. func listenToSystemSignals(cancel context.CancelFunc, grafanaGroup *errgroup.Group) {
  119. signalChan := make(chan os.Signal, 1)
  120. code := 0
  121. signal.Notify(signalChan, os.Interrupt, os.Kill, syscall.SIGTERM)
  122. select {
  123. case sig := <-signalChan:
  124. log.Info2("Received system signal. Shutting down", "signal", sig)
  125. case code = <-exitChan:
  126. switch code {
  127. case 0:
  128. log.Info("Shutting down")
  129. default:
  130. log.Warn("Shutting down")
  131. }
  132. }
  133. cancel()
  134. grafanaGroup.Wait()
  135. log.Close()
  136. os.Exit(code)
  137. }