diff options
Diffstat (limited to 'modules/log')
-rw-r--r-- | modules/log/conn.go | 104 | ||||
-rw-r--r-- | modules/log/console.go | 73 | ||||
-rw-r--r-- | modules/log/file.go | 243 | ||||
-rw-r--r-- | modules/log/log.go | 312 | ||||
-rw-r--r-- | modules/log/smtp.go | 87 |
5 files changed, 0 insertions, 819 deletions
diff --git a/modules/log/conn.go b/modules/log/conn.go deleted file mode 100644 index c104a16c..00000000 --- a/modules/log/conn.go +++ /dev/null @@ -1,104 +0,0 @@ -// 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" - "io" - "log" - "net" -) - -// ConnWriter implements LoggerInterface. -// it writes messages in keep-live tcp connection. -type ConnWriter struct { - lg *log.Logger - innerWriter io.WriteCloser - ReconnectOnMsg bool `json:"reconnectOnMsg"` - Reconnect bool `json:"reconnect"` - Net string `json:"net"` - Addr string `json:"addr"` - Level int `json:"level"` -} - -// create new ConnWrite returning as LoggerInterface. -func NewConn() LoggerInterface { - conn := new(ConnWriter) - conn.Level = TRACE - return conn -} - -// init connection writer with json config. -// json config only need key "level". -func (cw *ConnWriter) Init(jsonconfig string) error { - return json.Unmarshal([]byte(jsonconfig), cw) -} - -// write message in connection. -// if connection is down, try to re-connect. -func (cw *ConnWriter) WriteMsg(msg string, skip, level int) error { - if cw.Level > level { - return nil - } - if cw.neddedConnectOnMsg() { - if err := cw.connect(); err != nil { - return err - } - } - - if cw.ReconnectOnMsg { - defer cw.innerWriter.Close() - } - cw.lg.Println(msg) - return nil -} - -func (_ *ConnWriter) Flush() { -} - -// destroy connection writer and close tcp listener. -func (cw *ConnWriter) Destroy() { - if cw.innerWriter == nil { - return - } - cw.innerWriter.Close() -} - -func (cw *ConnWriter) connect() error { - if cw.innerWriter != nil { - cw.innerWriter.Close() - cw.innerWriter = nil - } - - conn, err := net.Dial(cw.Net, cw.Addr) - if err != nil { - return err - } - - if tcpConn, ok := conn.(*net.TCPConn); ok { - tcpConn.SetKeepAlive(true) - } - - cw.innerWriter = conn - cw.lg = log.New(conn, "", log.Ldate|log.Ltime) - return nil -} - -func (cw *ConnWriter) neddedConnectOnMsg() bool { - if cw.Reconnect { - cw.Reconnect = false - return true - } - - if cw.innerWriter == nil { - return true - } - - return cw.ReconnectOnMsg -} - -func init() { - Register("conn", NewConn) -} diff --git a/modules/log/console.go b/modules/log/console.go deleted file mode 100644 index f5a8b96f..00000000 --- a/modules/log/console.go +++ /dev/null @@ -1,73 +0,0 @@ -// 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" - "log" - "os" - "runtime" -) - -type Brush func(string) string - -func NewBrush(color string) Brush { - pre := "\033[" - reset := "\033[0m" - return func(text string) string { - return pre + color + "m" + text + reset - } -} - -var colors = []Brush{ - NewBrush("1;36"), // Trace cyan - NewBrush("1;34"), // Debug blue - NewBrush("1;32"), // Info green - NewBrush("1;33"), // Warn yellow - NewBrush("1;31"), // Error red - NewBrush("1;35"), // Critical purple - NewBrush("1;31"), // Fatal red -} - -// ConsoleWriter implements LoggerInterface and writes messages to terminal. -type ConsoleWriter struct { - lg *log.Logger - Level int `json:"level"` -} - -// create ConsoleWriter returning as LoggerInterface. -func NewConsole() LoggerInterface { - return &ConsoleWriter{ - lg: log.New(os.Stdout, "", log.Ldate|log.Ltime), - Level: TRACE, - } -} - -func (cw *ConsoleWriter) Init(config string) error { - return json.Unmarshal([]byte(config), cw) -} - -func (cw *ConsoleWriter) WriteMsg(msg string, skip, level int) error { - if cw.Level > level { - return nil - } - if runtime.GOOS == "windows" { - cw.lg.Println(msg) - } else { - cw.lg.Println(colors[level](msg)) - } - return nil -} - -func (_ *ConsoleWriter) Flush() { - -} - -func (_ *ConsoleWriter) Destroy() { -} - -func init() { - Register("console", NewConsole) -} diff --git a/modules/log/file.go b/modules/log/file.go deleted file mode 100644 index e9402815..00000000 --- a/modules/log/file.go +++ /dev/null @@ -1,243 +0,0 @@ -// 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) -} diff --git a/modules/log/log.go b/modules/log/log.go deleted file mode 100644 index 41be4140..00000000 --- a/modules/log/log.go +++ /dev/null @@ -1,312 +0,0 @@ -// 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 ( - "fmt" - "os" - "path" - "path/filepath" - "runtime" - "strings" - "sync" -) - -var ( - loggers []*Logger - GitLogger *Logger -) - -func NewLogger(bufLen int64, mode, config string) { - logger := newLogger(bufLen) - - isExist := false - for i, l := range loggers { - if l.adapter == mode { - isExist = true - loggers[i] = logger - } - } - if !isExist { - loggers = append(loggers, logger) - } - if err := logger.SetLogger(mode, config); err != nil { - Fatal(2, "Fail to set logger (%s): %v", mode, err) - } -} - -// FIXME: use same log level as other loggers. -func NewGitLogger(logPath string) { - os.MkdirAll(path.Dir(logPath), os.ModePerm) - GitLogger = newLogger(0) - GitLogger.SetLogger("file", fmt.Sprintf(`{"level":0,"filename":"%s","rotate":false}`, logPath)) -} - -func Trace(format string, v ...interface{}) { - for _, logger := range loggers { - logger.Trace(format, v...) - } -} - -func Debug(format string, v ...interface{}) { - for _, logger := range loggers { - logger.Debug(format, v...) - } -} - -func Info(format string, v ...interface{}) { - for _, logger := range loggers { - logger.Info(format, v...) - } -} - -func Warn(format string, v ...interface{}) { - for _, logger := range loggers { - logger.Warn(format, v...) - } -} - -func Error(skip int, format string, v ...interface{}) { - for _, logger := range loggers { - logger.Error(skip, format, v...) - } -} - -func Critical(skip int, format string, v ...interface{}) { - for _, logger := range loggers { - logger.Critical(skip, format, v...) - } -} - -func Fatal(skip int, format string, v ...interface{}) { - Error(skip, format, v...) - for _, l := range loggers { - l.Close() - } - os.Exit(1) -} - -func Close() { - for _, l := range loggers { - l.Close() - } -} - -// .___ __ _____ -// | | _____/ |_ ____________/ ____\____ ____ ____ -// | |/ \ __\/ __ \_ __ \ __\\__ \ _/ ___\/ __ \ -// | | | \ | \ ___/| | \/| | / __ \\ \__\ ___/ -// |___|___| /__| \___ >__| |__| (____ /\___ >___ > -// \/ \/ \/ \/ \/ - -type LogLevel int - -const ( - TRACE = iota - DEBUG - INFO - WARN - ERROR - CRITICAL - FATAL -) - -// LoggerInterface represents behaviors of a logger provider. -type LoggerInterface interface { - Init(config string) error - WriteMsg(msg string, skip, level int) error - Destroy() - Flush() -} - -type loggerType func() LoggerInterface - -var adapters = make(map[string]loggerType) - -// Register registers given logger provider to adapters. -func Register(name string, log loggerType) { - if log == nil { - panic("log: register provider is nil") - } - if _, dup := adapters[name]; dup { - panic("log: register called twice for provider \"" + name + "\"") - } - adapters[name] = log -} - -type logMsg struct { - skip, level int - msg string -} - -// Logger is default logger in beego application. -// it can contain several providers and log message into all providers. -type Logger struct { - adapter string - lock sync.Mutex - level int - msg chan *logMsg - outputs map[string]LoggerInterface - quit chan bool -} - -// newLogger initializes and returns a new logger. -func newLogger(buffer int64) *Logger { - l := &Logger{ - msg: make(chan *logMsg, buffer), - outputs: make(map[string]LoggerInterface), - quit: make(chan bool), - } - go l.StartLogger() - return l -} - -// SetLogger sets new logger instance with given logger adapter and config. -func (l *Logger) SetLogger(adapter string, config string) error { - l.lock.Lock() - defer l.lock.Unlock() - if log, ok := adapters[adapter]; ok { - lg := log() - if err := lg.Init(config); err != nil { - return err - } - l.outputs[adapter] = lg - l.adapter = adapter - } else { - panic("log: unknown adapter \"" + adapter + "\" (forgotten register?)") - } - return nil -} - -// DelLogger removes a logger adapter instance. -func (l *Logger) DelLogger(adapter string) error { - l.lock.Lock() - defer l.lock.Unlock() - if lg, ok := l.outputs[adapter]; ok { - lg.Destroy() - delete(l.outputs, adapter) - } else { - panic("log: unknown adapter \"" + adapter + "\" (forgotten register?)") - } - return nil -} - -func (l *Logger) writerMsg(skip, level int, msg string) error { - if l.level > level { - return nil - } - lm := &logMsg{ - skip: skip, - level: level, - } - - // Only error information needs locate position for debugging. - if lm.level >= ERROR { - pc, file, line, ok := runtime.Caller(skip) - if ok { - // Get caller function name. - fn := runtime.FuncForPC(pc) - var fnName string - if fn == nil { - fnName = "?()" - } else { - fnName = strings.TrimLeft(filepath.Ext(fn.Name()), ".") + "()" - } - - fileName := file - if len(fileName) > 20 { - fileName = "..." + fileName[len(fileName)-20:] - } - lm.msg = fmt.Sprintf("[%s:%d %s] %s", fileName, line, fnName, msg) - } else { - lm.msg = msg - } - } else { - lm.msg = msg - } - l.msg <- lm - return nil -} - -// StartLogger starts logger chan reading. -func (l *Logger) StartLogger() { - for { - select { - case bm := <-l.msg: - for _, l := range l.outputs { - if err := l.WriteMsg(bm.msg, bm.skip, bm.level); err != nil { - fmt.Println("ERROR, unable to WriteMsg:", err) - } - } - case <-l.quit: - return - } - } -} - -// Flush flushs all chan data. -func (l *Logger) Flush() { - for _, l := range l.outputs { - l.Flush() - } -} - -// Close closes logger, flush all chan data and destroy all adapter instances. -func (l *Logger) Close() { - l.quit <- true - for { - if len(l.msg) > 0 { - bm := <-l.msg - for _, l := range l.outputs { - if err := l.WriteMsg(bm.msg, bm.skip, bm.level); err != nil { - fmt.Println("ERROR, unable to WriteMsg:", err) - } - } - } else { - break - } - } - for _, l := range l.outputs { - l.Flush() - l.Destroy() - } -} - -func (l *Logger) Trace(format string, v ...interface{}) { - msg := fmt.Sprintf("[T] "+format, v...) - l.writerMsg(0, TRACE, msg) -} - -func (l *Logger) Debug(format string, v ...interface{}) { - msg := fmt.Sprintf("[D] "+format, v...) - l.writerMsg(0, DEBUG, msg) -} - -func (l *Logger) Info(format string, v ...interface{}) { - msg := fmt.Sprintf("[I] "+format, v...) - l.writerMsg(0, INFO, msg) -} - -func (l *Logger) Warn(format string, v ...interface{}) { - msg := fmt.Sprintf("[W] "+format, v...) - l.writerMsg(0, WARN, msg) -} - -func (l *Logger) Error(skip int, format string, v ...interface{}) { - msg := fmt.Sprintf("[E] "+format, v...) - l.writerMsg(skip, ERROR, msg) -} - -func (l *Logger) Critical(skip int, format string, v ...interface{}) { - msg := fmt.Sprintf("[C] "+format, v...) - l.writerMsg(skip, CRITICAL, msg) -} - -func (l *Logger) Fatal(skip int, format string, v ...interface{}) { - msg := fmt.Sprintf("[F] "+format, v...) - l.writerMsg(skip, FATAL, msg) - l.Close() - os.Exit(1) -} diff --git a/modules/log/smtp.go b/modules/log/smtp.go deleted file mode 100644 index 0a10e56a..00000000 --- a/modules/log/smtp.go +++ /dev/null @@ -1,87 +0,0 @@ -// 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" - "fmt" - "net/smtp" - "strings" - "time" -) - -const ( - subjectPhrase = "Diagnostic message from server" -) - -// smtpWriter implements LoggerInterface and is used to send emails via given SMTP-server. -type SmtpWriter struct { - Username string `json:"Username"` - Password string `json:"password"` - Host string `json:"Host"` - Subject string `json:"subject"` - RecipientAddresses []string `json:"sendTos"` - Level int `json:"level"` -} - -// create smtp writer. -func NewSmtpWriter() LoggerInterface { - return &SmtpWriter{Level: TRACE} -} - -// init smtp writer with json config. -// config like: -// { -// "Username":"example@gmail.com", -// "password:"password", -// "host":"smtp.gmail.com:465", -// "subject":"email title", -// "sendTos":["email1","email2"], -// "level":LevelError -// } -func (sw *SmtpWriter) Init(jsonconfig string) error { - return json.Unmarshal([]byte(jsonconfig), sw) -} - -// write message in smtp writer. -// it will send an email with subject and only this message. -func (s *SmtpWriter) WriteMsg(msg string, skip, level int) error { - if level < s.Level { - return nil - } - - hp := strings.Split(s.Host, ":") - - // Set up authentication information. - auth := smtp.PlainAuth( - "", - s.Username, - s.Password, - hp[0], - ) - // Connect to the server, authenticate, set the sender and recipient, - // and send the email all in one step. - content_type := "Content-Type: text/plain" + "; charset=UTF-8" - mailmsg := []byte("To: " + strings.Join(s.RecipientAddresses, ";") + "\r\nFrom: " + s.Username + "<" + s.Username + - ">\r\nSubject: " + s.Subject + "\r\n" + content_type + "\r\n\r\n" + fmt.Sprintf(".%s", time.Now().Format("2006-01-02 15:04:05")) + msg) - - return smtp.SendMail( - s.Host, - auth, - s.Username, - s.RecipientAddresses, - mailmsg, - ) -} - -func (_ *SmtpWriter) Flush() { -} - -func (_ *SmtpWriter) Destroy() { -} - -func init() { - Register("smtp", NewSmtpWriter) -} |