mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Progress on deb and rpm packaging, renamed config files, added file logging, #1476
This commit is contained in:
parent
f5cd3d853d
commit
7e0f1a57af
16
Gruntfile.js
16
Gruntfile.js
@ -11,22 +11,6 @@ module.exports = function (grunt) {
|
|||||||
docsDir: 'docs/'
|
docsDir: 'docs/'
|
||||||
};
|
};
|
||||||
|
|
||||||
config.mode = grunt.option('mode') || 'backend';
|
|
||||||
config.modeOptions = {
|
|
||||||
zipSuffix: '',
|
|
||||||
requirejs: {
|
|
||||||
paths: { config: '../config.sample' },
|
|
||||||
excludeConfig: true,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (config.mode === 'backend') {
|
|
||||||
grunt.log.writeln('Setting backend build mode');
|
|
||||||
config.modeOptions.zipSuffix = '-backend';
|
|
||||||
config.modeOptions.requirejs.paths = {};
|
|
||||||
config.modeOptions.requirejs.excludeConfig = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// load plugins
|
// load plugins
|
||||||
require('load-grunt-tasks')(grunt);
|
require('load-grunt-tasks')(grunt);
|
||||||
|
|
||||||
|
13
build.go
13
build.go
@ -30,7 +30,7 @@ var (
|
|||||||
workingDir string
|
workingDir string
|
||||||
|
|
||||||
installRoot = "/opt/grafana"
|
installRoot = "/opt/grafana"
|
||||||
configRoot = "/etc/grafana"
|
configRoot = "/etc/opt/grafana"
|
||||||
grafanaLogDir = "/var/log/grafana"
|
grafanaLogDir = "/var/log/grafana"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -115,9 +115,14 @@ func createRpmAndDeb() {
|
|||||||
postInstallScriptPath, _ := ioutil.TempFile("", "postinstall")
|
postInstallScriptPath, _ := ioutil.TempFile("", "postinstall")
|
||||||
|
|
||||||
versionFolder := filepath.Join(packageRoot, installRoot, "versions", version)
|
versionFolder := filepath.Join(packageRoot, installRoot, "versions", version)
|
||||||
runError("mkdir", "-p", versionFolder)
|
configDir := filepath.Join(packageRoot, configRoot)
|
||||||
runError("mkdir", "-p", filepath.Join(packageRoot, configRoot))
|
|
||||||
|
|
||||||
|
runError("mkdir", "-p", versionFolder)
|
||||||
|
runError("mkdir", "-p", configDir)
|
||||||
|
|
||||||
|
// copy sample ini file to /etc/opt/grafana
|
||||||
|
runError("cp", "conf/sample.ini", filepath.Join(configDir, "grafana.ini"))
|
||||||
|
// copy release files
|
||||||
runError("cp", "-a", filepath.Join(workingDir, "tmp")+"/.", versionFolder)
|
runError("cp", "-a", filepath.Join(workingDir, "tmp")+"/.", versionFolder)
|
||||||
|
|
||||||
fmt.Printf("PackageDir: %v\n", versionFolder)
|
fmt.Printf("PackageDir: %v\n", versionFolder)
|
||||||
@ -268,7 +273,7 @@ func clean() {
|
|||||||
rmr("bin", "Godeps/_workspace/pkg", "Godeps/_workspace/bin")
|
rmr("bin", "Godeps/_workspace/pkg", "Godeps/_workspace/bin")
|
||||||
rmr("dist")
|
rmr("dist")
|
||||||
rmr("tmp")
|
rmr("tmp")
|
||||||
rmr(filepath.Join(os.Getenv("GOPATH"), fmt.Sprintf("pkg/%s_%s/github.com/grafan", goos, goarch)))
|
rmr(filepath.Join(os.Getenv("GOPATH"), fmt.Sprintf("pkg/%s_%s/github.com/grafana", goos, goarch)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func setBuildEnv() {
|
func setBuildEnv() {
|
||||||
|
12
conf/custom.ini
Normal file
12
conf/custom.ini
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
app_mode = development
|
||||||
|
|
||||||
|
[server]
|
||||||
|
router_logging = false
|
||||||
|
static_root_path = src
|
||||||
|
|
||||||
|
[log]
|
||||||
|
level = Trace
|
||||||
|
mode = console, file
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -30,7 +30,7 @@ ssl_mode = disable
|
|||||||
path = data/grafana.db
|
path = data/grafana.db
|
||||||
|
|
||||||
[session]
|
[session]
|
||||||
; Either "memory", "file", default is "memory"
|
; Either "memory", "file", "redis", "mysql", default is "memory"
|
||||||
provider = file
|
provider = file
|
||||||
; Provider config options
|
; Provider config options
|
||||||
; memory: not have any config yet
|
; memory: not have any config yet
|
||||||
@ -100,8 +100,8 @@ auth_url = https://accounts.google.com/o/oauth2/auth
|
|||||||
token_url = https://accounts.google.com/o/oauth2/token
|
token_url = https://accounts.google.com/o/oauth2/token
|
||||||
|
|
||||||
[log]
|
[log]
|
||||||
root_path =
|
root_path = data/log
|
||||||
; Either "console", "file", "conn", "smtp" or "database", default is "console"
|
; Either "console", "file", default is "console"
|
||||||
; Use comma to separate multiple modes, e.g. "console, file"
|
; Use comma to separate multiple modes, e.g. "console, file"
|
||||||
mode = console
|
mode = console
|
||||||
; Buffer length of channel, keep it as it is if you don't know what it is.
|
; Buffer length of channel, keep it as it is if you don't know what it is.
|
43
conf/sample.ini
Normal file
43
conf/sample.ini
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
# Sample grafana config
|
||||||
|
# You only need to specify overrides here
|
||||||
|
# Defaults are in the /opt/grafana/current/conf/defaults.ini file
|
||||||
|
# This file is never ovewritten when upgrading grafana via deb or rpm package
|
||||||
|
|
||||||
|
app_mode = production
|
||||||
|
|
||||||
|
[server]
|
||||||
|
; protocol (http or https)
|
||||||
|
protocol = http
|
||||||
|
; the ip address to bind to, empty will bind to all interfaces
|
||||||
|
http_addr =
|
||||||
|
; the http port to use
|
||||||
|
http_port = 3000
|
||||||
|
; The public facing domain name used to access grafana from a browser
|
||||||
|
domain = localhost
|
||||||
|
; the full public facing url
|
||||||
|
root_url = %(protocol)s://%(domain)s:%(http_port)s/
|
||||||
|
router_logging = false
|
||||||
|
; the path relative to grafana process working directory
|
||||||
|
static_root_path = public
|
||||||
|
enable_gzip = false
|
||||||
|
|
||||||
|
[database]
|
||||||
|
; Either "mysql", "postgres" or "sqlite3", it's your choice
|
||||||
|
type = sqlite3
|
||||||
|
host = 127.0.0.1:3306
|
||||||
|
name = grafana
|
||||||
|
user = root
|
||||||
|
password =
|
||||||
|
; For "postgres" only, either "disable", "require" or "verify-full"
|
||||||
|
ssl_mode = disable
|
||||||
|
; For "sqlite3" only
|
||||||
|
path = /opt/grafana/data/grafana.db
|
||||||
|
|
||||||
|
[log]
|
||||||
|
level = Trace
|
||||||
|
mode = console, file
|
||||||
|
root_path = /var/log/grafana
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,13 +1,21 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/codegangsta/cli"
|
"github.com/codegangsta/cli"
|
||||||
|
"github.com/grafana/grafana/pkg/log"
|
||||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
func initRuntime(c *cli.Context) {
|
func initRuntime(c *cli.Context) {
|
||||||
setting.NewConfigContext(c.GlobalString("config"))
|
setting.NewConfigContext(c.GlobalString("config"))
|
||||||
|
|
||||||
|
log.Info("Starting Grafana")
|
||||||
|
log.Info("Version: %v, Commit: %v, Build date: %v", setting.BuildVersion, setting.BuildCommit, time.Unix(setting.BuildStamp, 0))
|
||||||
|
setting.LogLoadedConfigFiles()
|
||||||
|
|
||||||
sqlstore.NewEngine()
|
sqlstore.NewEngine()
|
||||||
sqlstore.EnsureAdminUser()
|
sqlstore.EnsureAdminUser()
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"path"
|
"path"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/Unknwon/macaron"
|
"github.com/Unknwon/macaron"
|
||||||
"github.com/codegangsta/cli"
|
"github.com/codegangsta/cli"
|
||||||
@ -68,9 +67,6 @@ func mapStatic(m *macaron.Macaron, dir string, prefix string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func runWeb(c *cli.Context) {
|
func runWeb(c *cli.Context) {
|
||||||
log.Info("Starting Grafana")
|
|
||||||
log.Info("Version: %v, Commit: %v, Build date: %v", setting.BuildVersion, setting.BuildCommit, time.Unix(setting.BuildStamp, 0))
|
|
||||||
|
|
||||||
initRuntime(c)
|
initRuntime(c)
|
||||||
|
|
||||||
social.NewOAuthService()
|
social.NewOAuthService()
|
||||||
|
243
pkg/log/file.go
Normal file
243
pkg/log/file.go
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package log
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FileLogWriter implements LoggerInterface.
|
||||||
|
// It writes messages by lines limit, file size limit, or time frequency.
|
||||||
|
type FileLogWriter struct {
|
||||||
|
*log.Logger
|
||||||
|
mw *MuxWriter
|
||||||
|
// The opened file
|
||||||
|
Filename string `json:"filename"`
|
||||||
|
|
||||||
|
Maxlines int `json:"maxlines"`
|
||||||
|
maxlines_curlines int
|
||||||
|
|
||||||
|
// Rotate at size
|
||||||
|
Maxsize int `json:"maxsize"`
|
||||||
|
maxsize_cursize int
|
||||||
|
|
||||||
|
// Rotate daily
|
||||||
|
Daily bool `json:"daily"`
|
||||||
|
Maxdays int64 `json:"maxdays"`
|
||||||
|
daily_opendate int
|
||||||
|
|
||||||
|
Rotate bool `json:"rotate"`
|
||||||
|
|
||||||
|
startLock sync.Mutex // Only one log can write to the file
|
||||||
|
|
||||||
|
Level int `json:"level"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// an *os.File writer with locker.
|
||||||
|
type MuxWriter struct {
|
||||||
|
sync.Mutex
|
||||||
|
fd *os.File
|
||||||
|
}
|
||||||
|
|
||||||
|
// write to os.File.
|
||||||
|
func (l *MuxWriter) Write(b []byte) (int, error) {
|
||||||
|
l.Lock()
|
||||||
|
defer l.Unlock()
|
||||||
|
return l.fd.Write(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// set os.File in writer.
|
||||||
|
func (l *MuxWriter) SetFd(fd *os.File) {
|
||||||
|
if l.fd != nil {
|
||||||
|
l.fd.Close()
|
||||||
|
}
|
||||||
|
l.fd = fd
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a FileLogWriter returning as LoggerInterface.
|
||||||
|
func NewFileWriter() LoggerInterface {
|
||||||
|
w := &FileLogWriter{
|
||||||
|
Filename: "",
|
||||||
|
Maxlines: 1000000,
|
||||||
|
Maxsize: 1 << 28, //256 MB
|
||||||
|
Daily: true,
|
||||||
|
Maxdays: 7,
|
||||||
|
Rotate: true,
|
||||||
|
Level: TRACE,
|
||||||
|
}
|
||||||
|
// use MuxWriter instead direct use os.File for lock write when rotate
|
||||||
|
w.mw = new(MuxWriter)
|
||||||
|
// set MuxWriter as Logger's io.Writer
|
||||||
|
w.Logger = log.New(w.mw, "", log.Ldate|log.Ltime)
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init file logger with json config.
|
||||||
|
// config like:
|
||||||
|
// {
|
||||||
|
// "filename":"log/gogs.log",
|
||||||
|
// "maxlines":10000,
|
||||||
|
// "maxsize":1<<30,
|
||||||
|
// "daily":true,
|
||||||
|
// "maxdays":15,
|
||||||
|
// "rotate":true
|
||||||
|
// }
|
||||||
|
func (w *FileLogWriter) Init(config string) error {
|
||||||
|
if err := json.Unmarshal([]byte(config), w); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(w.Filename) == 0 {
|
||||||
|
return errors.New("config must have filename")
|
||||||
|
}
|
||||||
|
return w.StartLogger()
|
||||||
|
}
|
||||||
|
|
||||||
|
// start file logger. create log file and set to locker-inside file writer.
|
||||||
|
func (w *FileLogWriter) StartLogger() error {
|
||||||
|
fd, err := w.createLogFile()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
w.mw.SetFd(fd)
|
||||||
|
if err = w.initFd(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *FileLogWriter) docheck(size int) {
|
||||||
|
w.startLock.Lock()
|
||||||
|
defer w.startLock.Unlock()
|
||||||
|
if w.Rotate && ((w.Maxlines > 0 && w.maxlines_curlines >= w.Maxlines) ||
|
||||||
|
(w.Maxsize > 0 && w.maxsize_cursize >= w.Maxsize) ||
|
||||||
|
(w.Daily && time.Now().Day() != w.daily_opendate)) {
|
||||||
|
if err := w.DoRotate(); err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.Filename, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
w.maxlines_curlines++
|
||||||
|
w.maxsize_cursize += size
|
||||||
|
}
|
||||||
|
|
||||||
|
// write logger message into file.
|
||||||
|
func (w *FileLogWriter) WriteMsg(msg string, skip, level int) error {
|
||||||
|
if level < w.Level {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
n := 24 + len(msg) // 24 stand for the length "2013/06/23 21:00:22 [T] "
|
||||||
|
w.docheck(n)
|
||||||
|
w.Logger.Println(msg)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *FileLogWriter) createLogFile() (*os.File, error) {
|
||||||
|
// Open the log file
|
||||||
|
return os.OpenFile(w.Filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0660)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *FileLogWriter) initFd() error {
|
||||||
|
fd := w.mw.fd
|
||||||
|
finfo, err := fd.Stat()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("get stat: %s\n", err)
|
||||||
|
}
|
||||||
|
w.maxsize_cursize = int(finfo.Size())
|
||||||
|
w.daily_opendate = time.Now().Day()
|
||||||
|
if finfo.Size() > 0 {
|
||||||
|
content, err := ioutil.ReadFile(w.Filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
w.maxlines_curlines = len(strings.Split(string(content), "\n"))
|
||||||
|
} else {
|
||||||
|
w.maxlines_curlines = 0
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DoRotate means it need to write file in new file.
|
||||||
|
// new file name like xx.log.2013-01-01.2
|
||||||
|
func (w *FileLogWriter) DoRotate() error {
|
||||||
|
_, err := os.Lstat(w.Filename)
|
||||||
|
if err == nil { // file exists
|
||||||
|
// Find the next available number
|
||||||
|
num := 1
|
||||||
|
fname := ""
|
||||||
|
for ; err == nil && num <= 999; num++ {
|
||||||
|
fname = w.Filename + fmt.Sprintf(".%s.%03d", time.Now().Format("2006-01-02"), num)
|
||||||
|
_, err = os.Lstat(fname)
|
||||||
|
}
|
||||||
|
// return error if the last file checked still existed
|
||||||
|
if err == nil {
|
||||||
|
return fmt.Errorf("rotate: cannot find free log number to rename %s\n", w.Filename)
|
||||||
|
}
|
||||||
|
|
||||||
|
// block Logger's io.Writer
|
||||||
|
w.mw.Lock()
|
||||||
|
defer w.mw.Unlock()
|
||||||
|
|
||||||
|
fd := w.mw.fd
|
||||||
|
fd.Close()
|
||||||
|
|
||||||
|
// close fd before rename
|
||||||
|
// Rename the file to its newfound home
|
||||||
|
if err = os.Rename(w.Filename, fname); err != nil {
|
||||||
|
return fmt.Errorf("Rotate: %s\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// re-start logger
|
||||||
|
if err = w.StartLogger(); err != nil {
|
||||||
|
return fmt.Errorf("Rotate StartLogger: %s\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
go w.deleteOldLog()
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *FileLogWriter) deleteOldLog() {
|
||||||
|
dir := filepath.Dir(w.Filename)
|
||||||
|
filepath.Walk(dir, func(path string, info os.FileInfo, err error) (returnErr error) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
returnErr = fmt.Errorf("Unable to delete old log '%s', error: %+v", path, r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
if !info.IsDir() && info.ModTime().Unix() < (time.Now().Unix()-60*60*24*w.Maxdays) {
|
||||||
|
if strings.HasPrefix(filepath.Base(path), filepath.Base(w.Filename)) {
|
||||||
|
os.Remove(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return returnErr
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// destroy file logger, close file writer.
|
||||||
|
func (w *FileLogWriter) Destroy() {
|
||||||
|
w.mw.fd.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
// flush file logger.
|
||||||
|
// there are no buffering messages in file logger in memory.
|
||||||
|
// flush file means sync file from disk.
|
||||||
|
func (w *FileLogWriter) Flush() {
|
||||||
|
w.mw.fd.Sync()
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Register("file", NewFileWriter)
|
||||||
|
}
|
6
pkg/setting/data/log/grafana.log
Normal file
6
pkg/setting/data/log/grafana.log
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
2015/03/03 09:52:42 [I] Setting: ENV override found: GF_SECURITY_ADMIN_USER
|
||||||
|
2015/03/03 09:59:43 [I] Setting: ENV override found: GF_SECURITY_ADMIN_USER
|
||||||
|
2015/03/03 10:03:13 [I] Setting: ENV override found: GF_SECURITY_ADMIN_USER
|
||||||
|
2015/03/03 10:09:13 [I] Setting: ENV override found: GF_SECURITY_ADMIN_USER
|
||||||
|
2015/03/03 10:09:34 [I] Setting: ENV override found: GF_SECURITY_ADMIN_USER
|
||||||
|
2015/03/03 10:15:20 [I] Setting: ENV override found: GF_SECURITY_ADMIN_USER
|
@ -94,6 +94,8 @@ var (
|
|||||||
// PhantomJs Rendering
|
// PhantomJs Rendering
|
||||||
ImagesDir string
|
ImagesDir string
|
||||||
PhantomDir string
|
PhantomDir string
|
||||||
|
|
||||||
|
configFiles []string
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -102,30 +104,32 @@ func init() {
|
|||||||
WorkDir, _ = filepath.Abs(".")
|
WorkDir, _ = filepath.Abs(".")
|
||||||
}
|
}
|
||||||
|
|
||||||
func findConfigFiles() []string {
|
func findConfigFiles(customConfigFile string) {
|
||||||
ConfRootPath = path.Join(WorkDir, "conf")
|
ConfRootPath = path.Join(WorkDir, "conf")
|
||||||
filenames := make([]string, 0)
|
configFiles = make([]string, 0)
|
||||||
|
|
||||||
configFile := path.Join(ConfRootPath, "grafana.ini")
|
configFile := path.Join(ConfRootPath, "defaults.ini")
|
||||||
if com.IsFile(configFile) {
|
if com.IsFile(configFile) {
|
||||||
filenames = append(filenames, configFile)
|
configFiles = append(configFiles, configFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
configFile = path.Join(ConfRootPath, "grafana.dev.ini")
|
configFile = path.Join(ConfRootPath, "dev.ini")
|
||||||
if com.IsFile(configFile) {
|
if com.IsFile(configFile) {
|
||||||
filenames = append(filenames, configFile)
|
configFiles = append(configFiles, configFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
configFile = path.Join(ConfRootPath, "grafana.custom.ini")
|
configFile = path.Join(ConfRootPath, "custom.ini")
|
||||||
if com.IsFile(configFile) {
|
if com.IsFile(configFile) {
|
||||||
filenames = append(filenames, configFile)
|
configFiles = append(configFiles, configFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(filenames) == 0 {
|
if customConfigFile != "" {
|
||||||
|
configFiles = append(configFiles, customConfigFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(configFiles) == 0 {
|
||||||
log.Fatal(3, "Could not find any config file")
|
log.Fatal(3, "Could not find any config file")
|
||||||
}
|
}
|
||||||
|
|
||||||
return filenames
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseAppUrlAndSubUrl(section *ini.Section) (string, string) {
|
func parseAppUrlAndSubUrl(section *ini.Section) (string, string) {
|
||||||
@ -165,11 +169,7 @@ func loadEnvVariableOverrides() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewConfigContext(config string) {
|
func NewConfigContext(config string) {
|
||||||
configFiles := findConfigFiles()
|
findConfigFiles(config)
|
||||||
|
|
||||||
if config != "" {
|
|
||||||
configFiles = append(configFiles, config)
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@ -186,6 +186,7 @@ func NewConfigContext(config string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadEnvVariableOverrides()
|
loadEnvVariableOverrides()
|
||||||
|
initLogging()
|
||||||
|
|
||||||
AppName = Cfg.Section("").Key("app_name").MustString("Grafana")
|
AppName = Cfg.Section("").Key("app_name").MustString("Grafana")
|
||||||
Env = Cfg.Section("").Key("app_mode").MustString("development")
|
Env = Cfg.Section("").Key("app_mode").MustString("development")
|
||||||
@ -233,8 +234,6 @@ func NewConfigContext(config string) {
|
|||||||
ImagesDir = "data/png"
|
ImagesDir = "data/png"
|
||||||
PhantomDir = "vendor/phantomjs"
|
PhantomDir = "vendor/phantomjs"
|
||||||
|
|
||||||
LogRootPath = Cfg.Section("log").Key("root_path").MustString(path.Join(WorkDir, "/data/log"))
|
|
||||||
|
|
||||||
readSessionConfig()
|
readSessionConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,3 +252,76 @@ func readSessionConfig() {
|
|||||||
os.MkdirAll(path.Dir(SessionOptions.ProviderConfig), os.ModePerm)
|
os.MkdirAll(path.Dir(SessionOptions.ProviderConfig), os.ModePerm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var logLevels = map[string]string{
|
||||||
|
"Trace": "0",
|
||||||
|
"Debug": "1",
|
||||||
|
"Info": "2",
|
||||||
|
"Warn": "3",
|
||||||
|
"Error": "4",
|
||||||
|
"Critical": "5",
|
||||||
|
}
|
||||||
|
|
||||||
|
func initLogging() {
|
||||||
|
// Get and check log mode.
|
||||||
|
LogModes = strings.Split(Cfg.Section("log").Key("mode").MustString("console"), ",")
|
||||||
|
LogRootPath = Cfg.Section("log").Key("root_path").MustString(path.Join(WorkDir, "/data/log"))
|
||||||
|
LogConfigs = make([]string, len(LogModes))
|
||||||
|
for i, mode := range LogModes {
|
||||||
|
mode = strings.TrimSpace(mode)
|
||||||
|
sec, err := Cfg.GetSection("log." + mode)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(4, "Unknown log mode: %s", mode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log level.
|
||||||
|
levelName := Cfg.Section("log."+mode).Key("level").In("Trace",
|
||||||
|
[]string{"Trace", "Debug", "Info", "Warn", "Error", "Critical"})
|
||||||
|
level, ok := logLevels[levelName]
|
||||||
|
if !ok {
|
||||||
|
log.Fatal(4, "Unknown log level: %s", levelName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate log configuration.
|
||||||
|
switch mode {
|
||||||
|
case "console":
|
||||||
|
LogConfigs[i] = fmt.Sprintf(`{"level":%s}`, level)
|
||||||
|
case "file":
|
||||||
|
logPath := sec.Key("file_name").MustString(path.Join(LogRootPath, "grafana.log"))
|
||||||
|
os.MkdirAll(path.Dir(logPath), os.ModePerm)
|
||||||
|
LogConfigs[i] = fmt.Sprintf(
|
||||||
|
`{"level":%s,"filename":"%s","rotate":%v,"maxlines":%d,"maxsize":%d,"daily":%v,"maxdays":%d}`, level,
|
||||||
|
logPath,
|
||||||
|
sec.Key("log_rotate").MustBool(true),
|
||||||
|
sec.Key("max_lines").MustInt(1000000),
|
||||||
|
1<<uint(sec.Key("max_size_shift").MustInt(28)),
|
||||||
|
sec.Key("daily_rotate").MustBool(true),
|
||||||
|
sec.Key("max_days").MustInt(7))
|
||||||
|
case "conn":
|
||||||
|
LogConfigs[i] = fmt.Sprintf(`{"level":%s,"reconnectOnMsg":%v,"reconnect":%v,"net":"%s","addr":"%s"}`, level,
|
||||||
|
sec.Key("reconnect_on_msg").MustBool(),
|
||||||
|
sec.Key("reconnect").MustBool(),
|
||||||
|
sec.Key("protocol").In("tcp", []string{"tcp", "unix", "udp"}),
|
||||||
|
sec.Key("addr").MustString(":7020"))
|
||||||
|
case "smtp":
|
||||||
|
LogConfigs[i] = fmt.Sprintf(`{"level":%s,"username":"%s","password":"%s","host":"%s","sendTos":"%s","subject":"%s"}`, level,
|
||||||
|
sec.Key("user").MustString("example@example.com"),
|
||||||
|
sec.Key("passwd").MustString("******"),
|
||||||
|
sec.Key("host").MustString("127.0.0.1:25"),
|
||||||
|
sec.Key("receivers").MustString("[]"),
|
||||||
|
sec.Key("subject").MustString("Diagnostic message from serve"))
|
||||||
|
case "database":
|
||||||
|
LogConfigs[i] = fmt.Sprintf(`{"level":%s,"driver":"%s","conn":"%s"}`, level,
|
||||||
|
sec.Key("driver").String(),
|
||||||
|
sec.Key("conn").String())
|
||||||
|
}
|
||||||
|
|
||||||
|
log.NewLogger(Cfg.Section("log").Key("buffer_len").MustInt64(10000), mode, LogConfigs[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func LogLoadedConfigFiles() {
|
||||||
|
for _, file := range configFiles {
|
||||||
|
log.Info("Config: Loaded from %s", file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
DAEMON_NAME="grafana"
|
DAEMON_NAME="grafana"
|
||||||
DAEMON_USER="grafana"
|
DAEMON_USER="grafana"
|
||||||
DAEMON_PATH="/opt/grafana/current/grafana"
|
DAEMON_PATH="/opt/grafana/current/grafana"
|
||||||
DAEMON_OPTS="web"
|
DAEMON_OPTS="--config=/etc/opt/grafana/grafana.ini web"
|
||||||
DAEMON_PWD="/opt/grafana/current"
|
DAEMON_PWD="/opt/grafana/current"
|
||||||
DAEMON_PID="/var/run/${DAEMON_NAME}.pid"
|
DAEMON_PID="/var/run/${DAEMON_NAME}.pid"
|
||||||
DAEMON_NICE=0
|
DAEMON_NICE=0
|
||||||
|
@ -1,99 +0,0 @@
|
|||||||
require.config({
|
|
||||||
urlArgs: 'bust=' + (new Date().getTime()),
|
|
||||||
baseUrl: 'app',
|
|
||||||
|
|
||||||
paths: {
|
|
||||||
config: ['../config', '../config.sample'],
|
|
||||||
settings: 'components/settings',
|
|
||||||
kbn: 'components/kbn',
|
|
||||||
store: 'components/store',
|
|
||||||
|
|
||||||
css: '../vendor/require/css',
|
|
||||||
text: '../vendor/require/text',
|
|
||||||
moment: '../vendor/moment',
|
|
||||||
filesaver: '../vendor/filesaver',
|
|
||||||
angular: '../vendor/angular/angular',
|
|
||||||
'angular-route': '../vendor/angular/angular-route',
|
|
||||||
'angular-sanitize': '../vendor/angular/angular-sanitize',
|
|
||||||
'angular-dragdrop': '../vendor/angular/angular-dragdrop',
|
|
||||||
'angular-strap': '../vendor/angular/angular-strap',
|
|
||||||
timepicker: '../vendor/angular/timepicker',
|
|
||||||
datepicker: '../vendor/angular/datepicker',
|
|
||||||
bindonce: '../vendor/angular/bindonce',
|
|
||||||
crypto: '../vendor/crypto.min',
|
|
||||||
spectrum: '../vendor/spectrum',
|
|
||||||
|
|
||||||
lodash: 'components/lodash.extended',
|
|
||||||
'lodash-src': '../vendor/lodash',
|
|
||||||
bootstrap: '../vendor/bootstrap/bootstrap',
|
|
||||||
|
|
||||||
jquery: '../vendor/jquery/jquery-2.1.1.min',
|
|
||||||
|
|
||||||
'extend-jquery': 'components/extend-jquery',
|
|
||||||
|
|
||||||
'jquery.flot': '../vendor/jquery/jquery.flot',
|
|
||||||
'jquery.flot.pie': '../vendor/jquery/jquery.flot.pie',
|
|
||||||
'jquery.flot.events': '../vendor/jquery/jquery.flot.events',
|
|
||||||
'jquery.flot.selection': '../vendor/jquery/jquery.flot.selection',
|
|
||||||
'jquery.flot.stack': '../vendor/jquery/jquery.flot.stack',
|
|
||||||
'jquery.flot.stackpercent':'../vendor/jquery/jquery.flot.stackpercent',
|
|
||||||
'jquery.flot.time': '../vendor/jquery/jquery.flot.time',
|
|
||||||
'jquery.flot.crosshair': '../vendor/jquery/jquery.flot.crosshair',
|
|
||||||
'jquery.flot.fillbelow': '../vendor/jquery/jquery.flot.fillbelow',
|
|
||||||
|
|
||||||
modernizr: '../vendor/modernizr-2.6.1',
|
|
||||||
|
|
||||||
'bootstrap-tagsinput': '../vendor/tagsinput/bootstrap-tagsinput',
|
|
||||||
},
|
|
||||||
shim: {
|
|
||||||
|
|
||||||
spectrum: {
|
|
||||||
deps: ['jquery']
|
|
||||||
},
|
|
||||||
|
|
||||||
crypto: {
|
|
||||||
exports: 'Crypto'
|
|
||||||
},
|
|
||||||
|
|
||||||
angular: {
|
|
||||||
deps: ['jquery','config'],
|
|
||||||
exports: 'angular'
|
|
||||||
},
|
|
||||||
|
|
||||||
bootstrap: {
|
|
||||||
deps: ['jquery']
|
|
||||||
},
|
|
||||||
|
|
||||||
modernizr: {
|
|
||||||
exports: 'Modernizr'
|
|
||||||
},
|
|
||||||
|
|
||||||
jquery: {
|
|
||||||
exports: 'jQuery'
|
|
||||||
},
|
|
||||||
|
|
||||||
// simple dependency declaration
|
|
||||||
//
|
|
||||||
'jquery.flot': ['jquery'],
|
|
||||||
'jquery.flot.pie': ['jquery', 'jquery.flot'],
|
|
||||||
'jquery.flot.events': ['jquery', 'jquery.flot'],
|
|
||||||
'jquery.flot.selection':['jquery', 'jquery.flot'],
|
|
||||||
'jquery.flot.stack': ['jquery', 'jquery.flot'],
|
|
||||||
'jquery.flot.stackpercent':['jquery', 'jquery.flot'],
|
|
||||||
'jquery.flot.time': ['jquery', 'jquery.flot'],
|
|
||||||
'jquery.flot.crosshair':['jquery', 'jquery.flot'],
|
|
||||||
'jquery.flot.fillbelow':['jquery', 'jquery.flot'],
|
|
||||||
'angular-dragdrop': ['jquery', 'angular'],
|
|
||||||
'angular-mocks': ['angular'],
|
|
||||||
'angular-sanitize': ['angular'],
|
|
||||||
'angular-route': ['angular'],
|
|
||||||
'angular-strap': ['angular', 'bootstrap','timepicker', 'datepicker'],
|
|
||||||
'bindonce': ['angular'],
|
|
||||||
|
|
||||||
timepicker: ['jquery', 'bootstrap'],
|
|
||||||
datepicker: ['jquery', 'bootstrap'],
|
|
||||||
|
|
||||||
'bootstrap-tagsinput': ['jquery'],
|
|
||||||
},
|
|
||||||
waitSeconds: 60,
|
|
||||||
});
|
|
@ -14,19 +14,16 @@ module.exports = function(grunt) {
|
|||||||
'htmlmin:build',
|
'htmlmin:build',
|
||||||
'ngtemplates',
|
'ngtemplates',
|
||||||
'cssmin:build',
|
'cssmin:build',
|
||||||
'build:grafanaVersion',
|
|
||||||
'ngAnnotate:build',
|
'ngAnnotate:build',
|
||||||
'requirejs:build',
|
'requirejs:build',
|
||||||
'concat:js',
|
'concat:js',
|
||||||
'filerev',
|
'filerev',
|
||||||
'usemin',
|
'usemin',
|
||||||
'clean:temp',
|
'clean:temp',
|
||||||
//'uglify:dest'
|
'uglify:dest'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
grunt.registerTask('build-post-process', function() {
|
grunt.registerTask('build-post-process', function() {
|
||||||
var mode = grunt.config.get('mode');
|
|
||||||
if (mode === 'backend') {
|
|
||||||
grunt.config('copy.dist_to_tmp', {
|
grunt.config('copy.dist_to_tmp', {
|
||||||
expand: true,
|
expand: true,
|
||||||
cwd: '<%= destDir %>',
|
cwd: '<%= destDir %>',
|
||||||
@ -43,27 +40,15 @@ module.exports = function(grunt) {
|
|||||||
});
|
});
|
||||||
grunt.config('copy.backend_files', {
|
grunt.config('copy.backend_files', {
|
||||||
expand: true,
|
expand: true,
|
||||||
src: ['conf/grafana.ini', 'vendor/**/*', 'scripts/*'],
|
src: ['conf/defaults.ini', 'vendor/**/*', 'scripts/*'],
|
||||||
options: { mode: true},
|
options: { mode: true},
|
||||||
dest: '<%= tempDir %>'
|
dest: '<%= tempDir %>'
|
||||||
});
|
});
|
||||||
|
|
||||||
grunt.task.run('copy:dist_to_tmp');
|
grunt.task.run('copy:dist_to_tmp');
|
||||||
grunt.task.run('clean:dest_dir');
|
grunt.task.run('clean:dest_dir');
|
||||||
grunt.task.run('copy:backend_bin');
|
grunt.task.run('copy:backend_bin');
|
||||||
grunt.task.run('copy:backend_files');
|
grunt.task.run('copy:backend_files');
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
grunt.registerTask('build:grafanaVersion', function() {
|
|
||||||
grunt.config('string-replace.config', {
|
|
||||||
files: {
|
|
||||||
'<%= tempDir %>/app/app.js': '<%= tempDir %>/app/app.js'
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
replacements: [{ pattern: /@grafanaVersion@/g, replacement: '<%= pkg.version %>' }]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
grunt.task.run('string-replace:config');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -38,7 +38,7 @@ module.exports = function(config) {
|
|||||||
},
|
},
|
||||||
zip_release: {
|
zip_release: {
|
||||||
options: {
|
options: {
|
||||||
archive: '<%= destDir %>/<%= pkg.name %><%= modeOptions.zipSuffix %>-<%= pkg.version %>.zip'
|
archive: '<%= destDir %>/<%= pkg.name %>-<%= pkg.version %>.zip'
|
||||||
},
|
},
|
||||||
files : [
|
files : [
|
||||||
{
|
{
|
||||||
@ -56,7 +56,7 @@ module.exports = function(config) {
|
|||||||
},
|
},
|
||||||
tgz_release: {
|
tgz_release: {
|
||||||
options: {
|
options: {
|
||||||
archive: '<%= destDir %>/<%= pkg.name %><%= modeOptions.zipSuffix %>-<%= pkg.version %>.tar.gz'
|
archive: '<%= destDir %>/<%= pkg.name %>-<%= pkg.version %>.tar.gz'
|
||||||
},
|
},
|
||||||
files : [
|
files : [
|
||||||
{
|
{
|
||||||
|
@ -6,9 +6,8 @@ module.exports = function(config,grunt) {
|
|||||||
var options = {
|
var options = {
|
||||||
appDir: '<%= tempDir %>',
|
appDir: '<%= tempDir %>',
|
||||||
dir: '<%= destDir %>',
|
dir: '<%= destDir %>',
|
||||||
mainConfigFile: '<%= tempDir %>/app/components/require.<%= mode %>.js',
|
mainConfigFile: '<%= tempDir %>/app/components/require.config.js',
|
||||||
baseUrl: './app',
|
baseUrl: './app',
|
||||||
paths: config.modeOptions.requirejs.paths,
|
|
||||||
|
|
||||||
modules: [], // populated below,
|
modules: [], // populated below,
|
||||||
|
|
||||||
@ -60,8 +59,7 @@ module.exports = function(config,grunt) {
|
|||||||
'directives/all',
|
'directives/all',
|
||||||
'filters/all',
|
'filters/all',
|
||||||
'controllers/all',
|
'controllers/all',
|
||||||
'routes/standalone/all',
|
'routes/all',
|
||||||
'routes/backend/all',
|
|
||||||
'components/partials',
|
'components/partials',
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -76,15 +74,6 @@ module.exports = function(config,grunt) {
|
|||||||
requireModules[0].include.push('text!panels/'+panelName+'/module.html');
|
requireModules[0].include.push('text!panels/'+panelName+'/module.html');
|
||||||
});
|
});
|
||||||
|
|
||||||
if (config.modeOptions.requirejs.excludeConfig) {
|
|
||||||
// exclude the literal config definition from all modules
|
|
||||||
requireModules
|
|
||||||
.forEach(function (module) {
|
|
||||||
module.excludeShallow = module.excludeShallow || [];
|
|
||||||
module.excludeShallow.push('config');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return { options: options };
|
return { options: options };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ module.exports = function(config) {
|
|||||||
return {
|
return {
|
||||||
dest: {
|
dest: {
|
||||||
expand: true,
|
expand: true,
|
||||||
src: ['**/*.js', '!config.sample.js', '!app/dashboards/*.js', '!app/dashboards/**/*.js',],
|
src: ['**/*.js', '!dashboards/*.js'],
|
||||||
dest: '<%= destDir %>',
|
dest: '<%= destDir %>',
|
||||||
cwd: '<%= destDir %>',
|
cwd: '<%= destDir %>',
|
||||||
options: {
|
options: {
|
||||||
|
Loading…
Reference in New Issue
Block a user