setting.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  1. // Copyright 2014 Unknwon
  2. // Copyright 2014 Torkel Ödegaard
  3. package setting
  4. import (
  5. "bytes"
  6. "fmt"
  7. "net/url"
  8. "os"
  9. "path"
  10. "path/filepath"
  11. "regexp"
  12. "runtime"
  13. "strings"
  14. "gopkg.in/ini.v1"
  15. "github.com/go-macaron/session"
  16. "github.com/grafana/grafana/pkg/log"
  17. "github.com/grafana/grafana/pkg/util"
  18. )
  19. type Scheme string
  20. const (
  21. HTTP Scheme = "http"
  22. HTTPS Scheme = "https"
  23. SOCKET Scheme = "socket"
  24. DEFAULT_HTTP_ADDR string = "0.0.0.0"
  25. )
  26. const (
  27. DEV string = "development"
  28. PROD string = "production"
  29. TEST string = "test"
  30. )
  31. var (
  32. // App settings.
  33. Env = DEV
  34. AppUrl string
  35. AppSubUrl string
  36. InstanceName string
  37. // build
  38. BuildVersion string
  39. BuildCommit string
  40. BuildStamp int64
  41. Enterprise bool
  42. ApplicationName string
  43. // Paths
  44. LogsPath string
  45. HomePath string
  46. DataPath string
  47. PluginsPath string
  48. ProvisioningPath string
  49. CustomInitPath = "conf/custom.ini"
  50. // Log settings.
  51. LogModes []string
  52. LogConfigs []util.DynMap
  53. // Http server options
  54. Protocol Scheme
  55. Domain string
  56. HttpAddr, HttpPort string
  57. SshPort int
  58. CertFile, KeyFile string
  59. SocketPath string
  60. RouterLogging bool
  61. DataProxyLogging bool
  62. StaticRootPath string
  63. EnableGzip bool
  64. EnforceDomain bool
  65. // Security settings.
  66. SecretKey string
  67. LogInRememberDays int
  68. CookieUserName string
  69. CookieRememberName string
  70. DisableGravatar bool
  71. EmailCodeValidMinutes int
  72. DataProxyWhiteList map[string]bool
  73. DisableBruteForceLoginProtection bool
  74. // Snapshots
  75. ExternalSnapshotUrl string
  76. ExternalSnapshotName string
  77. ExternalEnabled bool
  78. SnapShotRemoveExpired bool
  79. // Dashboard history
  80. DashboardVersionsToKeep int
  81. // User settings
  82. AllowUserSignUp bool
  83. AllowUserOrgCreate bool
  84. AutoAssignOrg bool
  85. AutoAssignOrgRole string
  86. VerifyEmailEnabled bool
  87. LoginHint string
  88. DefaultTheme string
  89. DisableLoginForm bool
  90. DisableSignoutMenu bool
  91. ExternalUserMngLinkUrl string
  92. ExternalUserMngLinkName string
  93. ExternalUserMngInfo string
  94. ViewersCanEdit bool
  95. // Http auth
  96. AdminUser string
  97. AdminPassword string
  98. AnonymousEnabled bool
  99. AnonymousOrgName string
  100. AnonymousOrgRole string
  101. // Auth proxy settings
  102. AuthProxyEnabled bool
  103. AuthProxyHeaderName string
  104. AuthProxyHeaderProperty string
  105. AuthProxyAutoSignUp bool
  106. AuthProxyLdapSyncTtl int
  107. AuthProxyWhitelist string
  108. // Basic Auth
  109. BasicAuthEnabled bool
  110. // Plugin settings
  111. PluginAppsSkipVerifyTLS bool
  112. // Session settings.
  113. SessionOptions session.Options
  114. SessionConnMaxLifetime int64
  115. // Global setting objects.
  116. Raw *ini.File
  117. ConfRootPath string
  118. IsWindows bool
  119. // PhantomJs Rendering
  120. ImagesDir string
  121. PhantomDir string
  122. // for logging purposes
  123. configFiles []string
  124. appliedCommandLineProperties []string
  125. appliedEnvOverrides []string
  126. ReportingEnabled bool
  127. CheckForUpdates bool
  128. GoogleAnalyticsId string
  129. GoogleTagManagerId string
  130. // LDAP
  131. LdapEnabled bool
  132. LdapConfigFile string
  133. LdapAllowSignup = true
  134. // QUOTA
  135. Quota QuotaSettings
  136. // Alerting
  137. AlertingEnabled bool
  138. ExecuteAlerts bool
  139. // Explore UI
  140. ExploreEnabled bool
  141. // logger
  142. logger log.Logger
  143. // Grafana.NET URL
  144. GrafanaComUrl string
  145. // S3 temp image store
  146. S3TempImageStoreBucketUrl string
  147. S3TempImageStoreAccessKey string
  148. S3TempImageStoreSecretKey string
  149. ImageUploadProvider string
  150. )
  151. type Cfg struct {
  152. Raw *ini.File
  153. // SMTP email settings
  154. Smtp SmtpSettings
  155. ImagesDir string
  156. DisableBruteForceLoginProtection bool
  157. }
  158. type CommandLineArgs struct {
  159. Config string
  160. HomePath string
  161. Args []string
  162. }
  163. func init() {
  164. IsWindows = runtime.GOOS == "windows"
  165. logger = log.New("settings")
  166. }
  167. func parseAppUrlAndSubUrl(section *ini.Section) (string, string) {
  168. appUrl := section.Key("root_url").MustString("http://localhost:3000/")
  169. if appUrl[len(appUrl)-1] != '/' {
  170. appUrl += "/"
  171. }
  172. // Check if has app suburl.
  173. url, err := url.Parse(appUrl)
  174. if err != nil {
  175. log.Fatal(4, "Invalid root_url(%s): %s", appUrl, err)
  176. }
  177. appSubUrl := strings.TrimSuffix(url.Path, "/")
  178. return appUrl, appSubUrl
  179. }
  180. func ToAbsUrl(relativeUrl string) string {
  181. return AppUrl + relativeUrl
  182. }
  183. func shouldRedactKey(s string) bool {
  184. uppercased := strings.ToUpper(s)
  185. return strings.Contains(uppercased, "PASSWORD") || strings.Contains(uppercased, "SECRET") || strings.Contains(uppercased, "PROVIDER_CONFIG")
  186. }
  187. func shouldRedactURLKey(s string) bool {
  188. uppercased := strings.ToUpper(s)
  189. return strings.Contains(uppercased, "DATABASE_URL")
  190. }
  191. func applyEnvVariableOverrides(file *ini.File) error {
  192. appliedEnvOverrides = make([]string, 0)
  193. for _, section := range file.Sections() {
  194. for _, key := range section.Keys() {
  195. sectionName := strings.ToUpper(strings.Replace(section.Name(), ".", "_", -1))
  196. keyName := strings.ToUpper(strings.Replace(key.Name(), ".", "_", -1))
  197. envKey := fmt.Sprintf("GF_%s_%s", sectionName, keyName)
  198. envValue := os.Getenv(envKey)
  199. if len(envValue) > 0 {
  200. key.SetValue(envValue)
  201. if shouldRedactKey(envKey) {
  202. envValue = "*********"
  203. }
  204. if shouldRedactURLKey(envKey) {
  205. u, err := url.Parse(envValue)
  206. if err != nil {
  207. return fmt.Errorf("could not parse environment variable. key: %s, value: %s. error: %v", envKey, envValue, err)
  208. }
  209. ui := u.User
  210. if ui != nil {
  211. _, exists := ui.Password()
  212. if exists {
  213. u.User = url.UserPassword(ui.Username(), "-redacted-")
  214. envValue = u.String()
  215. }
  216. }
  217. }
  218. appliedEnvOverrides = append(appliedEnvOverrides, fmt.Sprintf("%s=%s", envKey, envValue))
  219. }
  220. }
  221. }
  222. return nil
  223. }
  224. func applyCommandLineDefaultProperties(props map[string]string, file *ini.File) {
  225. appliedCommandLineProperties = make([]string, 0)
  226. for _, section := range file.Sections() {
  227. for _, key := range section.Keys() {
  228. keyString := fmt.Sprintf("default.%s.%s", section.Name(), key.Name())
  229. value, exists := props[keyString]
  230. if exists {
  231. key.SetValue(value)
  232. if shouldRedactKey(keyString) {
  233. value = "*********"
  234. }
  235. appliedCommandLineProperties = append(appliedCommandLineProperties, fmt.Sprintf("%s=%s", keyString, value))
  236. }
  237. }
  238. }
  239. }
  240. func applyCommandLineProperties(props map[string]string, file *ini.File) {
  241. for _, section := range file.Sections() {
  242. sectionName := section.Name() + "."
  243. if section.Name() == ini.DEFAULT_SECTION {
  244. sectionName = ""
  245. }
  246. for _, key := range section.Keys() {
  247. keyString := sectionName + key.Name()
  248. value, exists := props[keyString]
  249. if exists {
  250. appliedCommandLineProperties = append(appliedCommandLineProperties, fmt.Sprintf("%s=%s", keyString, value))
  251. key.SetValue(value)
  252. }
  253. }
  254. }
  255. }
  256. func getCommandLineProperties(args []string) map[string]string {
  257. props := make(map[string]string)
  258. for _, arg := range args {
  259. if !strings.HasPrefix(arg, "cfg:") {
  260. continue
  261. }
  262. trimmed := strings.TrimPrefix(arg, "cfg:")
  263. parts := strings.Split(trimmed, "=")
  264. if len(parts) != 2 {
  265. log.Fatal(3, "Invalid command line argument", arg)
  266. return nil
  267. }
  268. props[parts[0]] = parts[1]
  269. }
  270. return props
  271. }
  272. func makeAbsolute(path string, root string) string {
  273. if filepath.IsAbs(path) {
  274. return path
  275. }
  276. return filepath.Join(root, path)
  277. }
  278. func evalEnvVarExpression(value string) string {
  279. regex := regexp.MustCompile(`\${(\w+)}`)
  280. return regex.ReplaceAllStringFunc(value, func(envVar string) string {
  281. envVar = strings.TrimPrefix(envVar, "${")
  282. envVar = strings.TrimSuffix(envVar, "}")
  283. envValue := os.Getenv(envVar)
  284. // if env variable is hostname and it is empty use os.Hostname as default
  285. if envVar == "HOSTNAME" && envValue == "" {
  286. envValue, _ = os.Hostname()
  287. }
  288. return envValue
  289. })
  290. }
  291. func evalConfigValues(file *ini.File) {
  292. for _, section := range file.Sections() {
  293. for _, key := range section.Keys() {
  294. key.SetValue(evalEnvVarExpression(key.Value()))
  295. }
  296. }
  297. }
  298. func loadSpecifedConfigFile(configFile string, masterFile *ini.File) error {
  299. if configFile == "" {
  300. configFile = filepath.Join(HomePath, CustomInitPath)
  301. // return without error if custom file does not exist
  302. if !pathExists(configFile) {
  303. return nil
  304. }
  305. }
  306. userConfig, err := ini.Load(configFile)
  307. if err != nil {
  308. return fmt.Errorf("Failed to parse %v, %v", configFile, err)
  309. }
  310. userConfig.BlockMode = false
  311. for _, section := range userConfig.Sections() {
  312. for _, key := range section.Keys() {
  313. if key.Value() == "" {
  314. continue
  315. }
  316. defaultSec, err := masterFile.GetSection(section.Name())
  317. if err != nil {
  318. defaultSec, _ = masterFile.NewSection(section.Name())
  319. }
  320. defaultKey, err := defaultSec.GetKey(key.Name())
  321. if err != nil {
  322. defaultKey, _ = defaultSec.NewKey(key.Name(), key.Value())
  323. }
  324. defaultKey.SetValue(key.Value())
  325. }
  326. }
  327. configFiles = append(configFiles, configFile)
  328. return nil
  329. }
  330. func loadConfiguration(args *CommandLineArgs) (*ini.File, error) {
  331. var err error
  332. // load config defaults
  333. defaultConfigFile := path.Join(HomePath, "conf/defaults.ini")
  334. configFiles = append(configFiles, defaultConfigFile)
  335. // check if config file exists
  336. if _, err := os.Stat(defaultConfigFile); os.IsNotExist(err) {
  337. fmt.Println("Grafana-server Init Failed: Could not find config defaults, make sure homepath command line parameter is set or working directory is homepath")
  338. os.Exit(1)
  339. }
  340. // load defaults
  341. parsedFile, err := ini.Load(defaultConfigFile)
  342. if err != nil {
  343. fmt.Println(fmt.Sprintf("Failed to parse defaults.ini, %v", err))
  344. os.Exit(1)
  345. return nil, err
  346. }
  347. parsedFile.BlockMode = false
  348. // command line props
  349. commandLineProps := getCommandLineProperties(args.Args)
  350. // load default overrides
  351. applyCommandLineDefaultProperties(commandLineProps, parsedFile)
  352. // load specified config file
  353. err = loadSpecifedConfigFile(args.Config, parsedFile)
  354. if err != nil {
  355. initLogging(parsedFile)
  356. log.Fatal(3, err.Error())
  357. }
  358. // apply environment overrides
  359. err = applyEnvVariableOverrides(parsedFile)
  360. if err != nil {
  361. return nil, err
  362. }
  363. // apply command line overrides
  364. applyCommandLineProperties(commandLineProps, parsedFile)
  365. // evaluate config values containing environment variables
  366. evalConfigValues(parsedFile)
  367. // update data path and logging config
  368. DataPath = makeAbsolute(parsedFile.Section("paths").Key("data").String(), HomePath)
  369. initLogging(parsedFile)
  370. return parsedFile, err
  371. }
  372. func pathExists(path string) bool {
  373. _, err := os.Stat(path)
  374. if err == nil {
  375. return true
  376. }
  377. if os.IsNotExist(err) {
  378. return false
  379. }
  380. return false
  381. }
  382. func setHomePath(args *CommandLineArgs) {
  383. if args.HomePath != "" {
  384. HomePath = args.HomePath
  385. return
  386. }
  387. HomePath, _ = filepath.Abs(".")
  388. // check if homepath is correct
  389. if pathExists(filepath.Join(HomePath, "conf/defaults.ini")) {
  390. return
  391. }
  392. // try down one path
  393. if pathExists(filepath.Join(HomePath, "../conf/defaults.ini")) {
  394. HomePath = filepath.Join(HomePath, "../")
  395. }
  396. }
  397. var skipStaticRootValidation = false
  398. func validateStaticRootPath() error {
  399. if skipStaticRootValidation {
  400. return nil
  401. }
  402. if _, err := os.Stat(path.Join(StaticRootPath, "build")); err != nil {
  403. logger.Error("Failed to detect generated javascript files in public/build")
  404. }
  405. return nil
  406. }
  407. func NewCfg() *Cfg {
  408. return &Cfg{}
  409. }
  410. func (cfg *Cfg) Load(args *CommandLineArgs) error {
  411. setHomePath(args)
  412. iniFile, err := loadConfiguration(args)
  413. if err != nil {
  414. return err
  415. }
  416. cfg.Raw = iniFile
  417. // Temporary keep global, to make refactor in steps
  418. Raw = cfg.Raw
  419. ApplicationName = "Grafana"
  420. if Enterprise {
  421. ApplicationName += " Enterprise"
  422. }
  423. Env = iniFile.Section("").Key("app_mode").MustString("development")
  424. InstanceName = iniFile.Section("").Key("instance_name").MustString("unknown_instance_name")
  425. PluginsPath = makeAbsolute(iniFile.Section("paths").Key("plugins").String(), HomePath)
  426. ProvisioningPath = makeAbsolute(iniFile.Section("paths").Key("provisioning").String(), HomePath)
  427. server := iniFile.Section("server")
  428. AppUrl, AppSubUrl = parseAppUrlAndSubUrl(server)
  429. Protocol = HTTP
  430. if server.Key("protocol").MustString("http") == "https" {
  431. Protocol = HTTPS
  432. CertFile = server.Key("cert_file").String()
  433. KeyFile = server.Key("cert_key").String()
  434. }
  435. if server.Key("protocol").MustString("http") == "socket" {
  436. Protocol = SOCKET
  437. SocketPath = server.Key("socket").String()
  438. }
  439. Domain = server.Key("domain").MustString("localhost")
  440. HttpAddr = server.Key("http_addr").MustString(DEFAULT_HTTP_ADDR)
  441. HttpPort = server.Key("http_port").MustString("3000")
  442. RouterLogging = server.Key("router_logging").MustBool(false)
  443. EnableGzip = server.Key("enable_gzip").MustBool(false)
  444. EnforceDomain = server.Key("enforce_domain").MustBool(false)
  445. StaticRootPath = makeAbsolute(server.Key("static_root_path").String(), HomePath)
  446. if err := validateStaticRootPath(); err != nil {
  447. return err
  448. }
  449. // read data proxy settings
  450. dataproxy := iniFile.Section("dataproxy")
  451. DataProxyLogging = dataproxy.Key("logging").MustBool(false)
  452. // read security settings
  453. security := iniFile.Section("security")
  454. SecretKey = security.Key("secret_key").String()
  455. LogInRememberDays = security.Key("login_remember_days").MustInt()
  456. CookieUserName = security.Key("cookie_username").String()
  457. CookieRememberName = security.Key("cookie_remember_name").String()
  458. DisableGravatar = security.Key("disable_gravatar").MustBool(true)
  459. cfg.DisableBruteForceLoginProtection = security.Key("disable_brute_force_login_protection").MustBool(false)
  460. DisableBruteForceLoginProtection = cfg.DisableBruteForceLoginProtection
  461. // read snapshots settings
  462. snapshots := iniFile.Section("snapshots")
  463. ExternalSnapshotUrl = snapshots.Key("external_snapshot_url").String()
  464. ExternalSnapshotName = snapshots.Key("external_snapshot_name").String()
  465. ExternalEnabled = snapshots.Key("external_enabled").MustBool(true)
  466. SnapShotRemoveExpired = snapshots.Key("snapshot_remove_expired").MustBool(true)
  467. // read dashboard settings
  468. dashboards := iniFile.Section("dashboards")
  469. DashboardVersionsToKeep = dashboards.Key("versions_to_keep").MustInt(20)
  470. // read data source proxy white list
  471. DataProxyWhiteList = make(map[string]bool)
  472. for _, hostAndIp := range util.SplitString(security.Key("data_source_proxy_whitelist").String()) {
  473. DataProxyWhiteList[hostAndIp] = true
  474. }
  475. // admin
  476. AdminUser = security.Key("admin_user").String()
  477. AdminPassword = security.Key("admin_password").String()
  478. users := iniFile.Section("users")
  479. AllowUserSignUp = users.Key("allow_sign_up").MustBool(true)
  480. AllowUserOrgCreate = users.Key("allow_org_create").MustBool(true)
  481. AutoAssignOrg = users.Key("auto_assign_org").MustBool(true)
  482. AutoAssignOrgRole = users.Key("auto_assign_org_role").In("Editor", []string{"Editor", "Admin", "Viewer"})
  483. VerifyEmailEnabled = users.Key("verify_email_enabled").MustBool(false)
  484. LoginHint = users.Key("login_hint").String()
  485. DefaultTheme = users.Key("default_theme").String()
  486. ExternalUserMngLinkUrl = users.Key("external_manage_link_url").String()
  487. ExternalUserMngLinkName = users.Key("external_manage_link_name").String()
  488. ExternalUserMngInfo = users.Key("external_manage_info").String()
  489. ViewersCanEdit = users.Key("viewers_can_edit").MustBool(false)
  490. // auth
  491. auth := iniFile.Section("auth")
  492. DisableLoginForm = auth.Key("disable_login_form").MustBool(false)
  493. DisableSignoutMenu = auth.Key("disable_signout_menu").MustBool(false)
  494. // anonymous access
  495. AnonymousEnabled = iniFile.Section("auth.anonymous").Key("enabled").MustBool(false)
  496. AnonymousOrgName = iniFile.Section("auth.anonymous").Key("org_name").String()
  497. AnonymousOrgRole = iniFile.Section("auth.anonymous").Key("org_role").String()
  498. // auth proxy
  499. authProxy := iniFile.Section("auth.proxy")
  500. AuthProxyEnabled = authProxy.Key("enabled").MustBool(false)
  501. AuthProxyHeaderName = authProxy.Key("header_name").String()
  502. AuthProxyHeaderProperty = authProxy.Key("header_property").String()
  503. AuthProxyAutoSignUp = authProxy.Key("auto_sign_up").MustBool(true)
  504. AuthProxyLdapSyncTtl = authProxy.Key("ldap_sync_ttl").MustInt()
  505. AuthProxyWhitelist = authProxy.Key("whitelist").String()
  506. // basic auth
  507. authBasic := iniFile.Section("auth.basic")
  508. BasicAuthEnabled = authBasic.Key("enabled").MustBool(true)
  509. // global plugin settings
  510. PluginAppsSkipVerifyTLS = iniFile.Section("plugins").Key("app_tls_skip_verify_insecure").MustBool(false)
  511. // PhantomJS rendering
  512. cfg.ImagesDir = filepath.Join(DataPath, "png")
  513. ImagesDir = cfg.ImagesDir
  514. PhantomDir = filepath.Join(HomePath, "tools/phantomjs")
  515. analytics := iniFile.Section("analytics")
  516. ReportingEnabled = analytics.Key("reporting_enabled").MustBool(true)
  517. CheckForUpdates = analytics.Key("check_for_updates").MustBool(true)
  518. GoogleAnalyticsId = analytics.Key("google_analytics_ua_id").String()
  519. GoogleTagManagerId = analytics.Key("google_tag_manager_id").String()
  520. ldapSec := iniFile.Section("auth.ldap")
  521. LdapEnabled = ldapSec.Key("enabled").MustBool(false)
  522. LdapConfigFile = ldapSec.Key("config_file").String()
  523. LdapAllowSignup = ldapSec.Key("allow_sign_up").MustBool(true)
  524. alerting := iniFile.Section("alerting")
  525. AlertingEnabled = alerting.Key("enabled").MustBool(true)
  526. ExecuteAlerts = alerting.Key("execute_alerts").MustBool(true)
  527. explore := iniFile.Section("explore")
  528. ExploreEnabled = explore.Key("enabled").MustBool(false)
  529. cfg.readSessionConfig()
  530. cfg.readSmtpSettings()
  531. cfg.readQuotaSettings()
  532. if VerifyEmailEnabled && !cfg.Smtp.Enabled {
  533. log.Warn("require_email_validation is enabled but smtp is disabled")
  534. }
  535. // check old key name
  536. GrafanaComUrl = iniFile.Section("grafana_net").Key("url").MustString("")
  537. if GrafanaComUrl == "" {
  538. GrafanaComUrl = iniFile.Section("grafana_com").Key("url").MustString("https://grafana.com")
  539. }
  540. imageUploadingSection := iniFile.Section("external_image_storage")
  541. ImageUploadProvider = imageUploadingSection.Key("provider").MustString("")
  542. return nil
  543. }
  544. func (cfg *Cfg) readSessionConfig() {
  545. sec := cfg.Raw.Section("session")
  546. SessionOptions = session.Options{}
  547. SessionOptions.Provider = sec.Key("provider").In("memory", []string{"memory", "file", "redis", "mysql", "postgres", "memcache"})
  548. SessionOptions.ProviderConfig = strings.Trim(sec.Key("provider_config").String(), "\" ")
  549. SessionOptions.CookieName = sec.Key("cookie_name").MustString("grafana_sess")
  550. SessionOptions.CookiePath = AppSubUrl
  551. SessionOptions.Secure = sec.Key("cookie_secure").MustBool()
  552. SessionOptions.Gclifetime = cfg.Raw.Section("session").Key("gc_interval_time").MustInt64(86400)
  553. SessionOptions.Maxlifetime = cfg.Raw.Section("session").Key("session_life_time").MustInt64(86400)
  554. SessionOptions.IDLength = 16
  555. if SessionOptions.Provider == "file" {
  556. SessionOptions.ProviderConfig = makeAbsolute(SessionOptions.ProviderConfig, DataPath)
  557. os.MkdirAll(path.Dir(SessionOptions.ProviderConfig), os.ModePerm)
  558. }
  559. if SessionOptions.CookiePath == "" {
  560. SessionOptions.CookiePath = "/"
  561. }
  562. SessionConnMaxLifetime = cfg.Raw.Section("session").Key("conn_max_lifetime").MustInt64(14400)
  563. }
  564. func initLogging(file *ini.File) {
  565. // split on comma
  566. LogModes = strings.Split(file.Section("log").Key("mode").MustString("console"), ",")
  567. // also try space
  568. if len(LogModes) == 1 {
  569. LogModes = strings.Split(file.Section("log").Key("mode").MustString("console"), " ")
  570. }
  571. LogsPath = makeAbsolute(file.Section("paths").Key("logs").String(), HomePath)
  572. log.ReadLoggingConfig(LogModes, LogsPath, file)
  573. }
  574. func (cfg *Cfg) LogConfigSources() {
  575. var text bytes.Buffer
  576. for _, file := range configFiles {
  577. logger.Info("Config loaded from", "file", file)
  578. }
  579. if len(appliedCommandLineProperties) > 0 {
  580. for _, prop := range appliedCommandLineProperties {
  581. logger.Info("Config overridden from command line", "arg", prop)
  582. }
  583. }
  584. if len(appliedEnvOverrides) > 0 {
  585. text.WriteString("\tEnvironment variables used:\n")
  586. for _, prop := range appliedEnvOverrides {
  587. logger.Info("Config overridden from Environment variable", "var", prop)
  588. }
  589. }
  590. logger.Info("Path Home", "path", HomePath)
  591. logger.Info("Path Data", "path", DataPath)
  592. logger.Info("Path Logs", "path", LogsPath)
  593. logger.Info("Path Plugins", "path", PluginsPath)
  594. logger.Info("Path Provisioning", "path", ProvisioningPath)
  595. logger.Info("App mode " + Env)
  596. }